diff --git a/.agents b/.agents new file mode 120000 index 0000000000..c8161850a4 --- /dev/null +++ b/.agents @@ -0,0 +1 @@ +.claude \ No newline at end of file diff --git a/.claude/skills/orca-profiles/SKILL.md b/.claude/skills/orca-profiles/SKILL.md index 3b2130660f..40ab8c9927 100644 --- a/.claude/skills/orca-profiles/SKILL.md +++ b/.claude/skills/orca-profiles/SKILL.md @@ -1,78 +1,127 @@ --- name: orca-profiles -description: Use when creating, modifying, reviewing or debugging OrcaSlicer FFF system profiles under resources/profiles, including printer/vendor/nozzle/material additions, bundle indexes and versions, preset renames, setting_id and filament_id. Also use for missing presets or vendors, ignored profile settings, ambiguous AMS filament matches, and failures from orca_profile_tool.py, check_profile.sh/.bat, OrcaSlicer_profile_validator or the Check profiles CI job. +description: Use when creating, modifying, reviewing or debugging OrcaSlicer FFF system profiles under resources/profiles, including printer/vendor/nozzle/material additions, bundle indexes and versions, preset renames, setting_id and filament_id, and moving settings that sibling presets repeat onto shared bases after fix-variant or while drafting. Also use for missing presets or vendors, ignored profile settings, ambiguous AMS filament matches, and failures from orca_profile_tool.py, check_profile.sh/.bat, OrcaSlicer_profile_validator or the Check profiles CI job. --- # OrcaSlicer system profiles -A bundle is `resources/profiles/.json` plus `/`. The vendor id is the -filename stem, not the index's display `name`. The index is the loader's only entry point: -unindexed presets never load. `OrcaFilamentLibrary` is the shared filament bundle; -`blacklist.json` is data, not a bundle. +This skill describes how OrcaSlicer system profiles are drafted and shaped: the rules, equations and +patterns a profile follows. Use it to draft new profiles, modify existing ones, fix profile issues and +review profile changes. -## Choose the reference for the task +A bundle is the index `resources/profiles/.json` plus the folder `/`. The vendor id is +the filename stem (`BBL`), not the index's display `name` (`Bambulab`). The index is the loader's only +entry point: an unindexed preset never loads. `OrcaFilamentLibrary` is the shared filament bundle, +loaded first; `blacklist.json` is data, not a bundle. -Read the relevant reference before editing; load others only when the task crosses those areas. -Paths below are relative to this skill. Commands run from the repository root. +## References + +Read the reference for the task before editing; load others only when the task crosses into them. +Paths below are relative to this skill. Commands run from the repository root; on Windows use `py -3` +for `python3`. | Task | Read | | --- | --- | -| Add or tune a filament, brand or material; fix compatibility / alias shadowing | [filament-profiles.md](references/filament-profiles.md) | -| Add a printer or nozzle; change models, variants, assets or extruder vectors | [machine-profiles.md](references/machine-profiles.md) | +| Add or tune a filament, brand or material; fix compatibility, alias shadowing or overlapping coverage | [filament-profiles.md](references/filament-profiles.md) | +| Add a printer or nozzle; change models, variants, assets or per-extruder vectors | [machine-profiles.md](references/machine-profiles.md) | +| Add or tune extruder variants (`extruder_type` Direct Drive / Bowden × nozzle volume type Standard / High Flow / TPU High Flow / E3D High Flow / Extra High Flow variants) on a printer, process or filament | [extruder-variants.md](references/extruder-variants.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) | +| Draft several presets, or clean up after `fix-variant`: which base each shared value belongs on, when a new base pays off, proving nothing loads differently | [shared-bases.md](references/shared-bases.md) | +| Name a preset; check what a name must equal; base names, uniqueness, filenames | [naming.md](references/naming.md) | +| Create a vendor bundle; index, `version`, `inherits`, `include`; migrate preset names; diagnose why a bundle fails to load | [vendor-bundle.md](references/vendor-bundle.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) | +| Review a profile diff | [review-checklist.md](references/review-checklist.md) | -## Golden rules +## Rules -1. **Bump every changed bundle's `version`**, including `OrcaFilamentLibrary.json` when affected. - Increment the last component; carry `.99` into the third component (`02.04.00.99` → - `02.04.01.00`). The updater requires a strictly newer version. CI does not check this. -2. **Register every preset, bases included, parents before children.** `update-index` generates - the four `*_list` arrays; `check` requires its output. Index names must equal file `name` fields. -3. **Generate ids; never invent or copy them.** Keep existing ids during ordinary tuning. New - presets normally omit them until `generate-id`; bases must have no `setting_id`. - BBL's authoritative `setting_id` and a wrongly inherited `filament_id` need the explicit - handling in [ids.md](references/ids.md). -4. **Load failures can discard a whole vendor bundle.** Broken `inherits`, missing indexed files, - duplicate names, invalid model/variant references and unresolved filament ids affect more than - the edited preset. Inheritance stays within a bundle, except filaments may inherit the library. -5. **Preserve shipped selectable names.** Renaming, deleting or changing `instantiation` from - `"true"` to `"false"` needs `renamed_from` on a selectable successor. It is a `;`-separated string; - 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. 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). -8. **Verify setting keys against the code.** Unknown keys are silently discarded. Check - `PrintConfig.cpp` definitions and `PrintConfigDef::handle_legacy`; neighbours can contain dead - keys. `normalize` removes known obsolete keys, but does not detect arbitrary misspellings. -9. **Run the full profile checks before reporting completion.** A vendor-scoped pass is only a - development loop. Review also covers version bumps, assets, non-default processes and hardware - tuning that CI cannot establish. -10. **One all-printer preset per product; color is a runtime property, never a preset.** Never ship - presets that differ only by color — CI accepts them, so this is a review call. See - [color is a runtime property](references/filament-profiles.md#color-is-a-runtime-property). +1. **Bump the `version` of every bundle you change**, `OrcaFilamentLibrary.json` included when affected. + Increment the last component and carry `.99` into the third (`02.04.00.99` → `02.04.01.00`). The + updater installs only a strictly newer version, and CI does not check the bump. +2. **Register every preset, bases included, parents before children.** `update-index` writes the four + `*_list` arrays from the files on disk; `check` fails unless the index equals its output. Each index + entry's `name` must equal the file's `name`. +3. **Generate ids; never invent or copy them.** Keep existing ids during ordinary tuning. New presets + normally omit them until `generate-id`; bases carry no `setting_id`. BBL's own `setting_id`s and a wrongly + inherited `filament_id` need the explicit handling in [ids.md](references/ids.md). +4. **A name is an identity; preserve shipped selectable names.** Every reference (`inherits`, + `compatible_printers`, `default_*`, `printer_model`) is the exact, case-sensitive `name`. Renaming or + deleting a shipped selectable preset, or flipping its `instantiation` from `"true"` to `"false"`, + needs `renamed_from` (a `;`-separated string) on a selectable successor + ([migration rules](references/vendor-bundle.md#renamed_from)); update in-tree references too. +5. **Values are strings or arrays of strings.** `"instantiation": "false"`, never `false`. A + `machine_model`'s `nozzle_diameter` is a `;`-separated string; a `machine`'s is an array. Custom + G-code is one string. Wrong types can abort loading of the bundle or of every vendor + ([failure scopes](references/vendor-bundle.md#failure-scopes)). +6. **Unknown keys are dropped silently.** Confirm every new key exists in + `src/libslic3r/PrintConfig.cpp`; a key a neighbouring file writes is no evidence it exists. `check` rejects, + and `normalize` removes, known obsolete keys, but neither detects an arbitrary misspelling. A key + missing from the definitions may be a legacy name the loader still renames + (`tool_change_gcode` → `change_filament_gcode`) or whose value it rewrites (`DirectDrive` → + `Direct Drive`); check `PrintConfigDef::handle_legacy` before removing one, and write the current name + in new edits. +7. **Write overrides only.** Inherit the bundle's bases and restate just what differs; follow the + bundle's existing layering and style, except that a new filament prefers the library's bases. A + value that every preset of a group shares goes on the group's base + ([shared bases](references/shared-bases.md)). +8. **One load error can discard a whole vendor bundle**: an unresolved `inherits`, a missing indexed + file, two selectable presets with one name, an unknown `printer_model` or `printer_variant`, a + filament with no resolvable `filament_id`, `nil` in a non-nullable key. `inherits` and `include` + resolve only inside the bundle, except that filaments may inherit from OrcaFilamentLibrary. +9. **Filament compatibility names exact printer variants.** Every instantiated filament outside the + library writes a non-empty `compatible_printers` in its own file. Library fallbacks may omit it; + library printer-specific tunes use a non-empty list. One variant may be claimed by only one preset + per filament product (`filament_id`); an overlap is resolved by moving the variant to the most + specific preset, which is preferred over deleting a preset + ([one variant, one profile](references/filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)). +10. **One all-printer preset per product; colour is a runtime property, never a preset.** Never ship + presets that differ only by colour. CI accepts them, so this is a review call + ([colour](references/filament-profiles.md#colour-is-a-runtime-property)). +11. **Write a variant key at full width or not at all.** A key in the four variant sets holds exactly + `N` values in the selectable preset that writes it, `N = S × k` in the + [sizing equation](references/extruder-variants.md#sizing-equation): one per variant, a (normal, + silent) pair per variant for the `machine_max_*` limits; one value is not "the same for every + variant". Profiles must be correct as written: `check` judges each selectable preset by the + equation, never by what the loader pads or cuts, and `check --strict` also holds what a preset + inherits to its own width, as BBL writes it. A base is never judged on its own: its array widths + count, under `--strict`, where they reach a preset, while the id and layout rules judge the + composed preset, inherited values included, without it. Declare the variant layout on a + multi-extruder printer whose extruders need different values + ([widths](references/extruder-variants.md#widths)). +12. **Run the full checks before reporting completion.** A `--vendor` run is only a development loop. + Review also covers version bumps, assets, non-default processes and hardware tuning, which CI cannot + establish. + +## Names + +| Type | Shape | What the loader uses | +| --- | --- | --- | +| `machine_model` | `` (`Bambu Lab X1 Carbon`) | the exact string, named by each variant's `printer_model`; also the `_cover.png` stem | +| `machine` | ` nozzle` | the exact string, named by `compatible_printers`; `printer_variant` holds the nozzle token (`0.4`, [rules](references/machine-profiles.md#printer_model-and-printer_variant)) | +| `process` | `mm @` | the exact string when referenced or selected; `@` is a label, compatibility comes from the preset's list or condition | +| `filament` | ` @` | text before the first `@` is the alias (shadowing, `filament_id`); the rest is a label, with reserved targets `@base` and `@System` | + +The shapes are convention; `check` enforces only uniqueness. Per-type conventions, base names and +filename rules are in [naming.md](references/naming.md). ## Creating or modifying a profile -1. **Inspect the diff and neighbouring presets.** Read their `name`, parent chain and children; - edits to a base or a leaf with descendants propagate. Match the bundle's structure and write +1. **Inspect the diff and the neighbouring presets.** Read their `name`, parent chain and children: + edits to a base, or to a leaf that others inherit, propagate. Match the bundle's structure and write only overrides. New files use tab indentation, LF and a trailing newline; preserve unrelated - formatting in existing files. Match filename case exactly and use cross-platform names. -2. **Author explicit metadata.** Set `type` yourself, especially for `machine` vs `machine_model`. - Use `"from": "system"` and string `instantiation` on config presets. Omit ids on new presets - unless [ids.md](references/ids.md) requires special handling; retain them on existing ones. - Complete compatibility, defaults, assets and any rename migration using the task reference. -3. **Bump the version**, then run the authoring commands in order for each affected bundle: + formatting in existing files. Match filename case exactly and use + [cross-platform names](references/naming.md#filenames-and-paths). +2. **Author explicit metadata.** Set `type` yourself (`machine` vs `machine_model` especially), and use + `"from": "system"` and a string `instantiation` on config presets. Omit ids on new presets unless + [ids.md](references/ids.md) requires special handling; retain them on existing ones. Complete + compatibility, defaults, assets and any rename migration using the task reference. +3. **Put shared values on shared bases** when drafting several presets, and after `fix-variant`, which + widens an array in every preset that writes it and moves nothing. Each value goes on the base of the + level that determines it, a new base only where it pays for itself, and a restructure must leave + every selectable preset loading what it loaded: `snapshot` before the edit, `compare` after it + ([shared-bases.md](references/shared-bases.md)). +4. **Bump the version**, then run the authoring commands in order for each affected bundle, reading + every diff and resolving every error before moving on: ```bash python3 scripts/orca_profile_tool.py normalize --vendor "" @@ -81,46 +130,59 @@ Paths below are relative to this skill. Commands run from the repository root. python3 scripts/orca_profile_tool.py check ``` - Writing commands support `--dry-run`. Inspect their diffs: `normalize` changes content and can - reformat entire files. Stop and resolve command errors before proceeding. - - **Do not use `trim` in this workflow:** it can delete newly authored, unindexed profiles. - Do not use `normalize --force` for routine edits. -4. **Validate:** + Writing commands accept `--dry-run`. `normalize` changes content and can reformat entire files; + rerun `update-index` after any change to `inherits` or `include`, since it orders by them. + **Do not use `trim` in this workflow:** it deletes unindexed files, including one you just added. Do + not use `normalize --force` for routine edits. An error in a bundle you did not touch predates your + change: confirm it on a clean checkout and report it rather than fixing it in the same change. +5. **Validate:** ```bash ./scripts/check_profile.sh --vendor "" # development loop ./scripts/check_profile.sh # full tree before the PR ``` - On Windows use `py -3` instead of `python3`, and `scripts\check_profile.bat -Vendor ""` - / `scripts\check_profile.bat`. Logs land in a per-user cache dir (see - [validation.md](references/validation.md)). - Id checks remain tree-wide under `--vendor`; filament-only bundles skip the default slice check. - See [validation.md](references/validation.md) for flags, coverage and error remedies. -5. **Verify the changed behavior.** Slice newly added non-default processes explicitly, and - [test in the app](references/validation.md#testing-in-the-app) for selection or UI behavior. - Report checks actually run, failures/skips and any hardware tuning still unverified. + On Windows use `scripts\check_profile.bat -Vendor ""` / `scripts\check_profile.bat`. Logs + land in a per-user cache dir ([validation.md](references/validation.md)). Id checks stay tree-wide + under `--vendor`, and filament-only bundles skip the default slice check. Under `--vendor` read only + `profile_tool` and `validate_slice`: the other three checks fail on library presets that name other + vendors' printers ([why](references/validation.md#the-five-checks)). +6. **Verify the changed behaviour.** Slice newly added non-default processes and filaments + [explicitly](references/validation.md#checking-a-copy-of-the-tree), and + [test in the app](references/validation.md#testing-in-the-app) for selection or UI behaviour. Report + the checks actually run, their failures and skips, and any hardware tuning still unverified. -## Symptom → first reference +## Symptom → first look | Symptom | Start here | | --- | --- | -| A vendor disappears | Loader log / `validate_system`; [bundle failure scopes](references/vendor-bundle.md#failure-modes-ranked-by-blast-radius) | -| A setting has no effect | Key spelling/type, `handle_legacy`, or a config key placed on a `machine_model` | -| A preset exists but is not selectable | Index registration, `instantiation`, installation and compatibility | -| A filament is missing, duplicated, or matches the wrong spool | [Compatibility and alias shadowing](references/filament-profiles.md#compatible_printers); [ids](references/ids.md) | -| Presets differ only by color, or an all-printer library preset lacks `@System` | [Color is a runtime property](references/filament-profiles.md#color-is-a-runtime-property) | -| A bed temperature is ignored | [Plate-specific temperature keys](references/filament-profiles.md#bed-temperature-is-twelve-keys-not-one) | -| A change is absent from the running app | Version bump and [installed profile location](references/validation.md#testing-in-the-app) | -| A check fails | [Error → remedy](references/validation.md#error--remedy) | +| A vendor disappears | the app's log or the `validate_system` log; [failure scopes](references/vendor-bundle.md#failure-scopes) | +| A setting has no effect | key spelling or a legacy name (`PrintConfigDef::handle_legacy`), value type, or a config key placed on a `machine_model` | +| A preset exists but is not selectable | index registration, `instantiation`, whether it is installed (chosen in the setup wizard, or listed in the model's `default_materials`), compatibility | +| A filament is missing, duplicated, or matches the wrong spool | [compatibility and alias shadowing](references/filament-profiles.md#compatible_printers), [ids](references/ids.md) | +| Presets differ only by colour, or an all-printer library preset lacks `@System` | [colour is a runtime property](references/filament-profiles.md#colour-is-a-runtime-property) | +| High Flow (or a second extruder) slices with Standard (or extruder 1) values; a variant switch is missing; a variant's tuned values never arrive | [extruder variants](references/extruder-variants.md#variant-strings), [widths](references/extruder-variants.md#widths), [variant names](references/validation.md#variant-names) | +| Values land on the wrong extruder or mode after a variant was added | [inserting a variant](references/extruder-variants.md#adding-a-variant-inserts-its-values-at-its-variant-index), [padding and composition](references/extruder-variants.md#padding-truncation-and-composition) | +| A resolved value matches neither the file nor its `inherits` parent; an array is not the width the file wrote, or a child got only a base's first value | [composition order and `include`](references/vendor-bundle.md#inherits-and-include) | +| A bed temperature is ignored | [the twelve plate keys](references/filament-profiles.md#bed-temperature-is-twelve-keys-not-one) | +| A change is absent from the running app | version bump and [installed profile location](references/validation.md#testing-in-the-app) | +| A check fails | [error → remedy](references/validation.md#error--remedy) | ## Source of truth -When guidance and behavior disagree, inspect the current checkout: -`scripts/orca_profile_tool.py` for tooling and flags; `src/libslic3r/Preset*.cpp` for loading and -compatibility; `src/libslic3r/PrintConfig.cpp` for setting types and legacy handling; -`src/dev-utils/OrcaSlicer_profile_validator.cpp` and `.github/workflows/check_profiles.yml` for -validation coverage. `docs/HLSD/filament_id.md` defines filament identity. The -[profile development guide](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/how_to_create_profiles.md) +When this skill and the checkout disagree, the checkout wins: `scripts/orca_profile_tool.py` for the +tool and its flags; `src/libslic3r/Preset*.cpp` for loading and compatibility; +`src/libslic3r/PrintConfig.cpp` for keys, types, nullable options, the variant key sets and legacy +handling; `src/dev-utils/OrcaSlicer_profile_validator.cpp` and `.github/workflows/check_profiles.yml` +for validation coverage; `docs/HLSD/filament_id.md` for filament identity. The wiki's +[profile guide](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/how_to_create_profiles.md) is a tutorial; confirm loader and CLI details against these sources. + +## Editing this skill + +The skill describes what a profile must be, not what the shipped tree currently is. State rules, +equations, patterns and profile shapes; never inventories of shipped defects, counts, dated +measurements or lists of which vendors do what. Test each sentence: if editing the profiles alone, +with the engine and tool unchanged, could make it false, state the rule behind it or give a generic +example instead. Example files named as models to copy, and commit hashes cited as the reason for a +rule, are fine. diff --git a/.claude/skills/orca-profiles/references/extruder-variants.md b/.claude/skills/orca-profiles/references/extruder-variants.md new file mode 100644 index 0000000000..5059fd5c6b --- /dev/null +++ b/.claude/skills/orca-profiles/references/extruder-variants.md @@ -0,0 +1,547 @@ +# Extruder variants + +Use this when a printer's hotend or extruder can be in more than one hardware configuration that +needs different settings: a Standard and a High Flow nozzle, a TPU High Flow, E3D High Flow or Extra High Flow nozzle, or +a Direct Drive and a Bowden extruder on one machine. Variants let one printer, process and filament preset carry a +separate value per configuration; the user picks the configuration in the sidebar, and slicing uses +the matching values. They are not for nozzle **diameter**: that stays one `machine` preset per +`printer_variant`. + +## Variant strings + +- A **variant string** is `" "`: the extruder's `extruder_type` + value, a space, and its nozzle volume type (the project's `nozzle_volume_type`, seeded by the + printer preset's `default_nozzle_volume_type`), e.g. `"Direct Drive High Flow"`. +- A **variant** is one entry of a preset's variant list, named by its variant string (plus an extruder + id for printer and process lists). A variant-aware key holds **one value per variant** (a + (normal, silent) pair for the `machine_max_*` limits), and each preset declares its variants in + that list. Slicing picks, for each extruder, the variant whose + variant string equals the current `extruder_type` + nozzle volume type. +- Matching is an **exact string compare** of the whole string (plus the extruder id for printer and + process lists) against the preset's own resolved list, in any order. With no match the **first + variant** is used, silently: variant index 0 for printer and process keys (extruder 1's first + variant, whichever extruder asks), the filament's own first variant for filament keys. Printer and + process keys are matched only on a printer with several extruders or whose + `extruder_variant_list` offers several variant strings (`support_different_extruders`); on any + other printer their variant index 0 is read whatever it names. Nothing rejects a profile for a + variant mismatch; mistakes surface only as wrong values in the G-code. +- Variant index and array length follow [Widths](#widths). + +The complete enum is `s_keys_map_ExtruderType` and `s_keys_map_NozzleVolumeType` in +`src/libslic3r/PrintConfig.cpp` (`grep -A5 s_keys_map_NozzleVolumeType` there to confirm): + +| Part | Values | +| --- | --- | +| Extruder type | `Direct Drive`, `Bowden` | +| Nozzle volume type | `Standard`, `High Flow`, `TPU High Flow`, `E3D High Flow`, `Extra High Flow` (`Hybrid` exists but is runtime-only) | + +So the ten legal variant strings are the two extruder types × the five writable nozzle volume types, +and this table is the whole test of legality: a string's presence in a shipped profile is no evidence +for it. `Hybrid` (an extruder with several sub-nozzles) is never a variant: a filament on it reads the +variant of its own nozzle volume type from the project's `filament_volume_map`, printer and process +keys get one variant per nozzle volume type the extruder holds (`extruder_nozzle_stats`), and any +other lookup reads `Standard`. Never write it in a variant string. The same per-filament and +per-type reading applies on any extruder once `extruder_nozzle_stats` lists more nozzle volume +types than there are extruders. + +Every other string (a nozzle volume type name from another slicer, a typo, a variant copied from a +shipped profile) is a **dead variant**: nothing selects it, and since lookup is by string it does not +shift the variants beside it; it still counts toward the variant length when arrays are sized. +`orca_profile_tool.py check` reports it as an error in every bundle, BBL included +([variant names](validation.md#variant-names)). Legacy names are errors too: in the four variant +lists, `default_nozzle_volume_type` and `nozzle_volume_type`, the loader still rewrites `Normal` → +`Standard` and `Big Traffic` → `High Flow`, so a ported `Direct Drive Normal` variant would load, but +`check` rejects the spelling and names the enum name to write. `DirectDrive` is rewritten only in +`extruder_type`, so `DirectDrive Standard` in a variant list is dead. Write the enum names; +`normalize` does not convert them. + +### A nozzle the enum does not name + +The nozzle volume types are fixed by the engine, and a profile cannot add one. A nozzle the table does +not name needs the type added in code first, which is outside profile work; until then any string +for it is a dead variant. Once the engine has the type, its variant string is the enum name after +the extruder type, e.g. `"Direct Drive "`, and `check` accepts it with no tool change, since it +reads the enum from `PrintConfig.cpp`. Existing arrays are unaffected +([slice time](#slice-time-and-existing-users)). + +## When to use variants + +| Hardware | Do | +| --- | --- | +| One extruder, one nozzle type | Nothing. Without a variant list the printer has one variant ([variant length](#widths)) and no printer-key lookup takes place; a filament with several variants still gets the one for the printer's variant string. | +| Bowden-only printer | Nothing either. A list-less printer matches no string, so every printer-key lookup reads variant index 0 whether that variant is called `"Bowden Standard"` or `"Direct Drive Standard"`; naming it is cosmetic while it is the printer's only variant. A multi-extruder Bowden printer that declares the layout writes `"Bowden Standard"` variants: `"Direct Drive Standard"` entries match none of its extruders, so every extruder reads variant index 0 (and `check` reports them under [Printer rule 3](#printer-machine)). A filament with a `"Bowden Standard"` variant does get that variant there. | +| Nozzle types the user swaps (Standard / High Flow / TPU High Flow / E3D High Flow / Extra High Flow) | The printer lists them as variants; tune the keys that really differ per nozzle volume type. | +| Extruders of different types on one machine | One `extruder_type` per extruder, each extruder listing its own variants. | +| Several extruders that need different values in a variant key (retraction, z-hop, `nozzle_volume`, the `machine_max_*` limits) | Declare the layout even with a single nozzle volume type: `extruder_variant_list` with one `" Standard"` per extruder, and the flattened pair. Without it the arrays still hold one value per extruder ([variant length](#widths)), but the loader keeps only extruder 1's value of a list-less printer's arrays, so every extruder prints with it. | + +A preset without variant keys keeps working on a variant printer: its single variant is applied to +every extruder. So adding variants to a printer does not break existing processes or library +filaments; it only makes per-variant tuning possible. + +## Printer (`machine`) + +```json +"extruder_type": ["Direct Drive", "Direct Drive"], +"extruder_variant_list": ["Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive TPU High Flow"], +"printer_extruder_id": ["1", "1", "2", "2", "2"], +"printer_extruder_variant": ["Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow", "Direct Drive TPU High Flow"], +"default_nozzle_volume_type": ["Standard", "Standard"] +``` + +Rules: + +1. `extruder_variant_list` has **one entry per extruder**; each entry is the `,`-joined variants that + extruder supports. It is the per-extruder menu the sidebar offers. It is in no + [variant set](#the-four-key-sets), so the variant-length resize leaves it alone. Extruder 1's + first variant, variant index 0 of the flattened pair, is the fallback of every extruder whose + variant is missing when the arrays are collapsed for slicing + ([slice time](#slice-time-and-existing-users)); it is not necessarily the configuration the user + sees, which is `default_nozzle_volume_type` (rule 4). +2. `printer_extruder_variant` is that list **flattened** extruder-major, one entry per variant, and + `printer_extruder_id` gives each entry its 1-based extruder. These two size and address every + variant. Write all three keys and keep them in agreement. At load with + `single_extruder_multi_material` off, and in the app when the printer tab loads a printer with a + different number of extruders, the pair is rebuilt from `extruder_variant_list` (one + `Direct Drive Standard` per extruder when the list is absent) and the variant arrays are resized to + the rebuilt pair, padded with their first value or cut. The resize skips the `machine_max_*` limits + and `hotend_heating_rate` / `hotend_cooling_rate`: they keep their width, and an extruder beyond it + reads their first value, so extruder 2 and up of a list-less printer take extruder 1's normal limit + as their silent one too. With the three in agreement that changes nothing; a pair written without + the list is replaced. A listed variant the pair lacks is a menu choice that reads variant index 0. + - The pair without `extruder_variant_list` slices, but the sidebar offers no variant switch and + the app cannot add variants to a list-less process: nothing is lost while every extruder + has exactly one variant, and every further variant is unreachable. + - A missing or one-value `printer_extruder_id` is extruder 1 at every index + ([the id trap](#padding-truncation-and-composition)) unless the load-time rebuild above + replaces the pair (`single_extruder_multi_material` off). + - `check` reports against this rule ([variant arrays](validation.md#variant-arrays)). Errors: a + pair that is not the flattening, an id array that does not give each entry its extruder, a list + of more than one variant without the pair, and a pair without the list that puts several variants + on one extruder. A pair without the list and one variant per extruder is a warning where the + load-time rebuild would replace it (`single_extruder_multi_material` off, and a pair other than + one `Direct Drive Standard` per extruder), and passes otherwise. +3. Every variant string in an entry must start with that extruder's `extruder_type`. +4. `default_nozzle_volume_type` has one value per extruder and must name a nozzle volume type that + extruder's variants list; it seeds the sidebar. The live choice is `nozzle_volume_type` in the + project config, never a preset key. +5. Size every array by the set its key belongs to (the three sets are listed in full in + [The four key sets](#the-four-key-sets); the lengths are worked through in the + [sizing equation](#sizing-equation)): exactly the length below in each selectable preset that + writes it, or leave the key out and the preset takes what reaches it, the default or its base's + array. One value is no + shorthand for "the same for every variant"; write the value for every variant: + +| Set | Length | Keys | +| --- | --- | --- | +| `printer_extruder_options` | extruders (`E`) | the 8 per-extruder keys outside the variant scheme (`extruder_type`, `nozzle_diameter`, `default_nozzle_volume_type`, …) | +| `printer_options_with_variant_1` | variant length (`S`) | the full list below; not guessable from names | +| `printer_options_with_variant_2` | 2 × variant length | the 16 `machine_max_*` limits, at [stride 2](#widths): a (normal, silent) pair per variant | + +Put the variant layout on the shared base of all printers that share the hardware, and let the +nozzle-diameter siblings inherit it, restating only the variant arrays whose values change. `check` +does not judge a base on its own; its arrays count where they reach a selectable preset, under +`check --strict`. The loader stores a base at its **own** `printer_extruder_variant`, one variant +when it writes none whatever its extruder count, and cuts a wider array to its first values before +any child inherits it; so a multi-extruder base whose extruders need different values declares the +layout itself ([composition](#padding-truncation-and-composition)). When a variant array can move from +the presets to a base is in [shared-bases.md](shared-bases.md#variant-arrays-on-a-base). + +## Process + +1. `print_extruder_variant` + `print_extruder_id` list the (extruder id, variant string) pairs of the + process's variants. A variant is found by that pair, never by position: what is **required** is + that every pair a compatible printer (by list or condition) can select is present, in any order. A + missing pair reads the process's variant index 0 for that extruder, an extra pair is a variant + nothing selects, and neither is reported. The exception is a single-extruder printer whose + `extruder_variant_list` offers one variant string: no pair is matched there and variant index 0 + is read, so a process shared with such a printer lists that printer's pair first. **Mirroring** the printer's `printer_extruder_variant` + + `printer_extruder_id` entry for entry is the convention; follow it, so the arrays compare by eye, + but a different order with every pair present is a nit, not a defect. A process shared by printers + whose pairs differ falls back to variant index 0 on the pairs it lacks; give each layout its own base. +2. Every key in `print_options_with_variant` ([the full list](#the-four-key-sets), which is not + "every speed") has exactly one value per variant, or is left out. `print_extruder_id` needs its + value per variant too: one value pads to extruder 1 everywhere. `check` holds a + `print_extruder_id` that reaches the preset, written or inherited, to one entry per variant on any + printer, without `--strict`, and warns when it is absent and a variant repeats. +3. Only add process variants if speeds or accelerations really differ per nozzle volume type or + extruder. Otherwise omit the variant keys: a one-variant process needs no list, because match and + no-match both read variant index 0, and that variant is copied to every extruder at slice time. +4. Put the lists on the process base for that printer layout, so leaves stay small. + +## Filament + +```json +"filament_extruder_variant": ["Direct Drive Standard", "Direct Drive High Flow"], +"filament_max_volumetric_speed": ["21", "29"], +"filament_flow_ratio": ["0.98", "0.98"], +"filament_retraction_length": ["nil", "0.4"] +``` + +1. `filament_extruder_variant` lists variants **without extruder ids**: a filament's High Flow variant + is used on whichever extruder is in High Flow. Its entries must be distinct, since the lookup + returns the first equal string and a repeated entry is a variant nothing selects. There is no + filament id key: `filament_extruder_id` exists only as a G-code placeholder, not as a filament + option (its option and its set entry are commented out in `PrintConfig.cpp`), so a filament file that writes it loses the key as unknown. + `filament_extruder_compatibility` is unrelated to variants (it says which extruders the filament + may be loaded into). +2. Every key in `filament_options_with_variant` ([the full list](#the-four-key-sets)) that reaches the + preset, whether written, included or inherited, is resized to its variant count: write it at exactly + that width, or leave it out. Keys outside the set + (`filament_type`, plate temperatures, `fan_max_speed`, `slow_down_min_speed`, …) are never addressed by variant index; the preset contributes their first value however wide a + file writes them. +3. Cover every variant the material is meant to print on across its `compatible_printers`. Leave out + a variant deliberately when the material should not be tuned for it (e.g. a TPU High Flow variant + only on TPU filaments); an extruder reporting that variant string then reads the first variant. +4. Order the variants like the printer's, Standard first, so the first-variant fallback is the + conservative one. +5. Tune what really differs: `filament_max_volumetric_speed` is the usual difference between nozzle + volume types, then flow ratio, temperature and retraction. Use measured values; never copy the + Standard value into the High Flow variant and call it tuned. +6. `nil` is legal per variant in the nullable override keys, occupies one entry like any value, and + keeps the printer's value for that variant only. +7. Declare a multi-variant list with the arrays it sizes: on the filament, in its own file or in a + template it pulls in with [`include`](vendor-bundle.md#inherits-and-include). The filament may be + compatible with printers that list fewer variants, or none: each printer takes the filament's variant + for its own variant string, else the filament's first variant. A one-variant list on a shared base + is harmless, because one variant is the width a list-less preset has anyway; and a list-less base is + stored at that width, so a wider array on it reaches its children as its first value only. + A key such a base writes reaches a multi-variant child as one value, which the loader spreads over + the child's variants; `check --strict` reports it at the child, which restates it at its own width. + +## Widths + +Every variant key is a flat array addressed by **variant index**: index `n` belongs to entry `n` of +the preset's own variant list (`printer_extruder_variant`, `print_extruder_variant` or +`filament_extruder_variant`). The index is found by exact compare of the string +`" "` (plus the 1-based extruder id for printer and process lists), +and the value is read at `index × stride`: + +| Stride | Keys | Layout | +| --- | --- | --- | +| 1 | `printer_options_with_variant_1`, `print_options_with_variant`, `filament_options_with_variant` | `[variant 0, variant 1, …]` | +| 2 | `printer_options_with_variant_2` (the `machine_max_*` limits) | `[variant 0 normal, variant 0 silent, variant 1 normal, variant 1 silent, …]` | + +So a variant array is `variant length × stride` long. The **variant length** is the number of +entries in the preset's variant list, counted on the preset's config **after** `include` and +`inherits` are applied, dead variants included. An inherited array arrives already resized to the +base's own variant length, an included one at the width its file wrote +([composition](#padding-truncation-and-composition)): + +| Preset | Variant length | +| --- | --- | +| `machine` | `len(printer_extruder_variant)`; without it, the variants `extruder_variant_list` offers; without both, **one per extruder** (`len(nozzle_diameter)`), since the list's default is one `Direct Drive Standard` per extruder. `extruders_count` is a printer-tab field, not a preset key. The loader honours that default only halfway for a system preset: it sizes the composed preset by the one-entry default `printer_extruder_variant`, cutting every variant array to its first value, and only then (with `single_extruder_multi_material` off) rebuilds the pair to one variant per extruder ([Printer rule 2](#printer-machine)) and pads the arrays with that value. The rule's width is still one per extruder; to give extruders different values, declare the layout. | +| `process` | `len(print_extruder_variant)`; without one, 1 | +| `filament` | `len(filament_extruder_variant)`; without one, 1 | + +The per-extruder keys in `printer_extruder_options` ([listed with the sets](#the-four-key-sets)) are +outside this scheme and stay one value per extruder. Keys outside [the four sets](#the-four-key-sets) +are never variant-resized or addressed by variant index, however wide a shipped file writes them; a +per-extruder vector holds `len(nozzle_diameter)` values, and a shorter one acts as padded with its +first value ([machine-profiles.md](machine-profiles.md#multi-extruder-idex-and-tool-changers)). + +### Sizing equation + +For a key in one of the four variant sets: + +``` +E = extruders = len(nozzle_diameter) = len(extruder_type) + = len(default_nozzle_volume_type) = len(extruder_variant_list) +V_i = variants listed for extruder i = ","-separated entries of extruder_variant_list[i], + each " " +S = variant length = V_1 + V_2 + … + V_E + = len(printer_extruder_variant) = len(printer_extruder_id) +k = stride = 2 for printer_options_with_variant_2, else 1 + +N = values the key holds, one per variant: + machine (printer_options_with_variant_1, _2) = S × k + process (print_options_with_variant) = len(print_extruder_variant) = len(print_extruder_id) + filament (filament_options_with_variant) = len(filament_extruder_variant) +values[s × k + m] = variant index s, mode m (m = 0 normal, m = 1 silent; only m = 0 at stride 1) +variant index s = (printer_extruder_id[s], printer_extruder_variant[s]) +``` + +`printer_extruder_variant` is not sized by the equation; it defines `S`: it is `extruder_variant_list` +flattened extruder by extruder, and `printer_extruder_id[s]` is the extruder that index `s` came from. +A process that mirrors the printer's pairs, as [Process rule 1](#process) asks, has `N = S`; a +filament lists each variant string it is tuned for once, with no extruder id, so its `N` is its own +and independent of any one printer: it serves every printer in its `compatible_printers`, and a +variant string no extruder of a printer reports is simply never read there (a two-extruder printer +with `S = 7` serves a filament whose `N` is 3, and the filament keeps its 3 on a printer that offers +two variant strings). The +pair is what the loader reads, so the equality with the sum holds when the three keys agree, as +[Printer rule 2](#printer-machine) requires. + +A selectable preset that writes a variant key writes it at its own `N`; any other width, one value +included, is an error. A preset that leaves a key out takes what reaches it, the default or an array +it inherits or includes, which the loader resizes to the preset's `N`; `check --strict` holds that +array to the preset's `N` too. A base is not judged on its own: its arrays count only where they reach +a preset that does not override them. BBL is the model for strict: every printer-specific machine, +process and filament declares its layout and restates every variant key at its own `N`, even where all +the values are the same, keys Orca added to the sets included. +Without the lists, `extruder_variant_list` defaults to one +`Direct Drive Standard` per extruder, so a machine has `V_i = 1` and `S = E`, and a process or filament +has `N = 1`; the loader cuts a list-less machine to its first variant and, with +`single_extruder_multi_material` off, widens it again with that value ([variant length](#widths)). The per-extruder keys outside the sets +(`printer_extruder_options` plus `extruder_offset` and `extruder_colour`) and `extruder_variant_list` +itself hold `E` values. + +### Sizing examples + +**One extruder, two nozzle volume types**: `E = 1`, `V_1 = 2`, so `S = 2`; stride-1 keys hold 2 +values, `machine_max_*` hold 4: + +```json +"nozzle_diameter": ["0.4"], +"extruder_type": ["Direct Drive"], +"extruder_variant_list": ["Direct Drive Standard,Direct Drive High Flow"], +"printer_extruder_id": ["1", "1"], +"printer_extruder_variant": ["Direct Drive Standard", "Direct Drive High Flow"], +"default_nozzle_volume_type": ["Standard"], +"retraction_length": ["0.8", "1.0"], +"machine_max_speed_x": ["500", "200", "600", "250"] +``` + +The matching process lists the same two pairs (`print_extruder_id` `["1", "1"]`, +`print_extruder_variant` as above) and holds 2 values per key, e.g. `outer_wall_speed` +`["200", "260"]`; a filament for it lists `["Direct Drive Standard", "Direct Drive High Flow"]` and +holds 2 values per key, e.g. `filament_max_volumetric_speed` `["16", "24"]`. + +**Four extruders, one nozzle volume type each** (a tool changer): `E = 4`, every `V_i = 1`, so +`S = 4`; stride-1 keys hold 4 values, `machine_max_*` hold 8: + +```json +"nozzle_diameter": ["0.4", "0.4", "0.6", "0.4"], +"extruder_type": ["Direct Drive", "Direct Drive", "Direct Drive", "Direct Drive"], +"extruder_variant_list": ["Direct Drive Standard", "Direct Drive Standard", + "Direct Drive Standard", "Direct Drive Standard"], +"printer_extruder_id": ["1", "2", "3", "4"], +"printer_extruder_variant": ["Direct Drive Standard", "Direct Drive Standard", + "Direct Drive Standard", "Direct Drive Standard"], +"default_nozzle_volume_type": ["Standard", "Standard", "Standard", "Standard"], +"retraction_length": ["0.8", "0.8", "1.2", "0.8"], +"machine_max_speed_x": ["500", "200", "500", "200", "500", "200", "500", "200"] +``` + +The (normal, silent) pair is repeated per extruder: `["500", "200"]` would be width 2 against +`S × k = 8` (the loader pads it to `500, 200, 500, 500, …`) and `["500"]` width 1; both are errors. The +process mirrors the four pairs (`print_extruder_id` `["1", "2", "3", "4"]`) with 4 values per key, or +omits the variant keys altogether when nothing differs per extruder (then one value per key). A +filament for it lists only `["Direct Drive Standard"]`: one entry, so one value per key. Drop the +layout from this printer and the widths stay the same, since the default list gives `S = E = 4`; but +the loader then keeps only the first variant ([variant length](#widths)): `retraction_length` +becomes `0.8` on every extruder and extruder 3 loses its `1.2`. + +### Adding a variant inserts its values at its variant index + +Indexes run extruder-major: extruder 1's variants in `extruder_variant_list` order, then extruder +2's. A new variant's values go in at its index, not at the end. Giving extruder 1 of a two-extruder +printer a High Flow option, when only extruder 2 had one: + +| Key | Before | After | +| --- | --- | --- | +| `extruder_variant_list` | `["Direct Drive Standard", "Direct Drive Standard,Direct Drive High Flow"]` | `["Direct Drive Standard,Direct Drive High Flow", "Direct Drive Standard,Direct Drive High Flow"]` | +| `printer_extruder_id` | `["1", "2", "2"]` | `["1", "1", "2", "2"]` | +| `printer_extruder_variant` | `[Standard, Standard, High Flow]` | `[Standard, High Flow, Standard, High Flow]` (full strings in the file) | +| `retraction_length` (stride 1) | `["0.8", "1.0", "1.2"]` | `["0.8", "?", "1.0", "1.2"]`: one value at index 1 | +| `machine_max_speed_x` (stride 2) | `["500", "200", "600", "250", "700", "300"]` | `["500", "200", "?", "?", "600", "250", "700", "300"]`: a (normal, silent) pair at position 2 | +| `print_extruder_id` / `print_extruder_variant` / `outer_wall_speed` | mirror the printer | the same insertion at index 1 | +| `filament_extruder_variant` `[Standard, High Flow]` | — | unchanged: filament variants carry no extruder id, so the existing High Flow variant now serves both extruders | + +Every `?` is a measured value for that nozzle, on the machine limits as much as on retraction. +Removing or renaming a variant shifts the later values the same way in reverse; a variant string that +no longer matches the enum is simply a variant nothing selects. + +### Padding, truncation and composition + +**Every key in the set widens, whether or not a file restates it.** At load each variant key of the +composed config is resized to the length of the preset's own `*_extruder_variant` (the one-entry +default when it writes none) × stride: a short array is **padded by repeating its first value**, a +long one is truncated to its first values, without a word from the loader or the validator. The rule +does not follow from this padding: a file writes a variant key at **exactly `variant length × stride`** +or not at all. Any other length, one value included (which the loader spreads over every variant, at +stride 2 over normal *and* silent alike), is a mistake the loader hides and +`orca_profile_tool.py check` reports as an error in the selectable preset that writes it, even when +every value is the same; `check --strict` also reports an array that reaches a selectable preset at +another width +([variant arrays](validation.md#variant-arrays)). + +The loader sizes a list-less preset of any type to one variant at this step, a list-less machine +included: a two-extruder machine without a layout that writes `retraction_length` `["0.8", "0.9"]`, the +width the equation asks for, stores `["0.8"]`, which the pair rebuild and the slice-time collapse hand +to both extruders. A 3-value array on a preset of variant length 2 keeps its first two; at length 4 it +becomes `[a, b, c, a]`. + +Composition hands down widths in two ways: + +- **`inherits` hands down the parent's resized arrays.** A base is stored after its own resize, at + the length of its own `*_extruder_variant` (one variant for a base of any type that writes none, + whatever its extruder count), so an array wider than the base's list is cut to its first values + before any child sees it, and a child that adds variants gets those first values padded. Widen an + array only on a preset whose own resolved list already has the entries. `check` judges selectable + presets only, at the width each file wrote: an array a base's own resize cuts is not seen (a review + item), and an inherited array of another width than a child's list is left to the loader's resize + unless `check --strict`, which asks the child to restate it at its own width. +- **`include` hands down the template's diff at its pre-resize width.** The template contributes every + key where its composed config differs from the built-in defaults, taken before its own resize, so the + arrays it writes arrive at the width its file wrote, and the includer's own list sizes them. A key the + template sets to the built-in default is not passed on + ([`include`](vendor-bundle.md#inherits-and-include)). + +The id keys are the trap in this padding: `printer_extruder_id` and `print_extruder_id` are members +with default `[1]`, so a missing or one-value id array beside a longer variant list is padded to +extruder 1 at every index. That is right on a single-extruder printer and wrong on a multi-extruder +one, where every variant is then addressed as extruder 1's. A machine escapes it only where the +load-time pair rebuild of [Printer rule 2](#printer-machine) runs (`single_extruder_multi_material` +off); a process's `print_extruder_id` is never rebuilt at load. `check` +holds an id array that reaches a selectable preset, written or inherited, to one entry per variant on +any printer; `fix-variant` never pads an id array or a variant list, since those address the +variants rather than fill them. + +Consequences: + +- A base that gains a variant silently pads every descendant that restates a variant array at the old + width, and a short `machine_max_*` array copies variant 0's *normal* limit into the silent entries + too; a descendant that restates nothing inherits the widened array and needs no edit. Extend, in one + change: the printer base and each nozzle-diameter sibling that restates a variant array, the process + bases that mirror the printer's variants, and the filaments that should cover the variant. +- A one-value override is reported, and the loader spreads it over **all** variants, overwriting the + ones that should differ. +- A process or filament that omits the new variant is not padded; the variant resolves to its index 0. + +### Slice time and existing users + +**Slice time collapses variants to extruders.** When printer, process and filaments are combined on a +printer with several extruders or several variant strings, each printer and process variant key is +re-gathered to one entry per extruder (× stride) in extruder order, using each extruder's live nozzle +volume type, or to one entry per nozzle volume type for an extruder that holds several (Hybrid, or +`extruder_nozzle_stats` listing more types than there are extruders); on any other printer they are +not re-gathered and variant index 0 is read. Filament keys are re-gathered to one entry per filament, +on a printer with a single variant too once a filament has several variants, and under a dynamic +nozzle map to one entry per variant each filament prints through. Custom G-code and the +`machine_max_*` limits therefore index by extruder or filament, never by variant index; variant order +matters only inside the preset. An extruder with no matching variant reads variant index 0, extruder +1's first variant, whichever extruder it is; under layered nozzle grouping, `get_config_index_base` +reads the collapsed arrays and falls back to the same extruder's first entry instead. + +**Existing user presets and projects follow the variant string, not the position.** A user preset +stores every variant array it changed (nullable keys as per-variant diffs, `nil` where equal to the +parent). On load each parent variant takes the child's value for the variant with the same extruder id +and variant string; variants the parent gained keep the parent's value, and a child whose arrays the +parent cannot map keeps its own. Per-object process overrides are remapped when a printer change +alters the extruder count or the length of `printer_extruder_variant`, by variant string alone (no +extruder id; of several matching values the smallest wins), and a single-value override applies to +every variant. Adding or reordering variants in a shipped preset is therefore safe for existing +users; renaming a variant, or moving it to another extruder id, loses their values for it. + +**A new nozzle volume type changes no array.** Adding one to the code widens nothing until a profile +lists the new variant string; until then every existing array keeps its length and meaning. + +## The four key sets + +Membership is literal (four `std::set` initializers in `src/libslic3r/PrintConfig.cpp`) +and **not guessable from names**: `ironing_speed`, `skirt_speed`, `wipe_speed`, `scarf_joint_speed`, +`small_support_perimeter_speed` and `wipe_tower_max_purge_speed` are process speeds outside the set, +while every process `*_acceleration` and `*_jerk` key is inside, and so are +`small_perimeter_threshold`, `top_solid_infill_flow_ratio` and `slowdown_for_curled_perimeters`; +`filament_flush_temp` is in and `filament_flush_temp_fast` out; `use_firmware_retraction` is out and +`travel_slope` and `retract_lift_enforce` in. The three variant-list keys and the two id +keys are members of their own set (the list sizes itself, a no-op; the id keys are padded like any +other member, [the id trap](#padding-truncation-and-composition)), while `extruder_variant_list` is in +no set: the variant-length resize leaves it alone, and only the pair rebuild of +[Printer rule 2](#printer-machine) pads it. The per-extruder `printer_extruder_options` is listed +last for contrast; it is not a variant set. + +`check` and `fix-variant` read the four sets from `PrintConfig.cpp` on every run, so they follow the +engine. The lists below are from the 2026-09-29 checkout; regenerate them from the repository root +before relying on them (the recipe strips comments, since an initializer can carry a commented-out entry): + +```bash +python3 - <<'EOF' +import re +src = open('src/libslic3r/PrintConfig.cpp', encoding='utf-8', errors='replace').read() +for name in ['printer_options_with_variant_1', 'printer_options_with_variant_2', + 'print_options_with_variant', 'filament_options_with_variant', + 'printer_extruder_options']: + body = re.search(r'std::set\s+' + name + r'\s*=\s*\{(.*?)\};', src, re.S).group(1) + body = re.sub(r'/\*.*?\*/', '', body, flags=re.S) + body = re.sub(r'//[^\n]*', '', body) + print(name, sorted(set(re.findall(r'"([^"]+)"', body)))) +EOF +``` + +**`printer_options_with_variant_1`**, machine, stride 1 (27): `deretraction_speed`, `hotend_cooling_rate`, `hotend_heating_rate`, `long_retractions_when_cut`, `nozzle_flush_dataset`, `nozzle_type`, `nozzle_volume`, `printer_extruder_id`, `printer_extruder_variant`, `retract_after_wipe`, `retract_before_wipe`, `retract_length_toolchange`, `retract_lift_above`, `retract_lift_below`, `retract_lift_enforce`, `retract_restart_extra`, `retract_restart_extra_toolchange`, `retract_when_changing_layer`, `retraction_distances_when_cut`, `retraction_length`, `retraction_minimum_travel`, `retraction_speed`, `travel_slope`, `wipe`, `wipe_distance`, `z_hop`, `z_hop_types` + +**`printer_options_with_variant_2`**, machine, stride 2 (16): `machine_max_acceleration_e`, `machine_max_acceleration_extruding`, `machine_max_acceleration_retracting`, `machine_max_acceleration_travel`, `machine_max_acceleration_x`, `machine_max_acceleration_y`, `machine_max_acceleration_z`, `machine_max_jerk_e`, `machine_max_jerk_x`, `machine_max_jerk_y`, `machine_max_jerk_z`, `machine_max_junction_deviation`, `machine_max_speed_e`, `machine_max_speed_x`, `machine_max_speed_y`, `machine_max_speed_z` + +**`print_options_with_variant`**, process, stride 1 (45): `bridge_acceleration`, `bridge_speed`, `default_acceleration`, `default_jerk`, `default_junction_deviation`, `enable_overhang_speed`, `gap_infill_speed`, `infill_jerk`, `initial_layer_acceleration`, `initial_layer_infill_speed`, `initial_layer_jerk`, `initial_layer_speed`, `initial_layer_travel_acceleration`, `initial_layer_travel_jerk`, `initial_layer_travel_speed`, `inner_wall_acceleration`, `inner_wall_jerk`, `inner_wall_speed`, `internal_bridge_speed`, `internal_solid_infill_acceleration`, `internal_solid_infill_speed`, `outer_wall_acceleration`, `outer_wall_jerk`, `outer_wall_speed`, `overhang_1_4_speed`, `overhang_2_4_speed`, `overhang_3_4_speed`, `overhang_4_4_speed`, `print_extruder_id`, `print_extruder_variant`, `slowdown_for_curled_perimeters`, `small_perimeter_speed`, `small_perimeter_threshold`, `sparse_infill_acceleration`, `sparse_infill_speed`, `support_interface_speed`, `support_speed`, `top_solid_infill_flow_ratio`, `top_surface_acceleration`, `top_surface_jerk`, `top_surface_speed`, `travel_acceleration`, `travel_jerk`, `travel_speed`, `travel_speed_z` + +**`filament_options_with_variant`**, filament, stride 1 (54): `activate_air_filtration`, `activate_air_filtration_during_print`, `activate_air_filtration_on_completion`, `adaptive_pressure_advance`, `adaptive_pressure_advance_bridges`, `adaptive_pressure_advance_model`, `adaptive_pressure_advance_overhangs`, `complete_print_exhaust_fan_speed`, `during_print_exhaust_fan_speed`, `enable_pressure_advance`, `filament_adaptive_volumetric_speed`, `filament_cooling_before_tower`, `filament_deretraction_speed`, `filament_extruder_variant`, `filament_flow_ratio`, `filament_flush_temp`, `filament_flush_volumetric_speed`, `filament_ironing_flow`, `filament_ironing_inset`, `filament_ironing_spacing`, `filament_ironing_speed`, `filament_long_retractions_when_cut`, `filament_max_volumetric_speed`, `filament_pre_cooling_temperature`, `filament_pre_cooling_temperature_nc`, `filament_preheat_temperature_delta`, `filament_ramming_travel_time`, `filament_ramming_travel_time_nc`, `filament_ramming_volumetric_speed`, `filament_ramming_volumetric_speed_nc`, `filament_retract_after_wipe`, `filament_retract_before_wipe`, `filament_retract_length_nc`, `filament_retract_length_toolchange`, `filament_retract_lift_above`, `filament_retract_lift_below`, `filament_retract_lift_enforce`, `filament_retract_restart_extra`, `filament_retract_restart_extra_toolchange`, `filament_retract_when_changing_layer`, `filament_retraction_distances_when_cut`, `filament_retraction_length`, `filament_retraction_minimum_travel`, `filament_retraction_speed`, `filament_wipe`, `filament_wipe_distance`, `filament_z_hop`, `filament_z_hop_types`, `long_retractions_when_ec`, `nozzle_temperature`, `nozzle_temperature_initial_layer`, `pressure_advance`, `retraction_distances_when_ec`, `volumetric_speed_coefficients` + +**`printer_extruder_options`**, machine, one value per extruder, not a variant set (8): +`default_nozzle_volume_type`, `extruder_max_nozzle_count`, `extruder_printable_area`, +`extruder_printable_height`, `extruder_type`, `max_layer_height`, `min_layer_height`, +`nozzle_diameter`. These are never addressed by variant index; `extruder_offset`, `extruder_colour` and +`extruder_variant_list` are per extruder too. A shorter array acts as padded with its first value, and +entries beyond the extruder count are never read +([per-extruder vectors](machine-profiles.md#multi-extruder-idex-and-tool-changers)). + +## Checking and testing + +Checklist for a new variant profile set: + +1. Decide the variants per extruder from the real hardware; pick legal strings only. +2. Printer base: `extruder_type`, `extruder_variant_list`, flattened `printer_extruder_variant` + + `printer_extruder_id`, `default_nozzle_volume_type`; every variant array at variant length, every + `machine_max_*` at 2 × variant length as (normal, silent) pairs, even where the values are the + same, values in variant order. +3. A process base per variant layout, or no variant keys at all. +4. Filaments for the printer: a variant list covering the intended variants, every variant key at that + width, measured values per nozzle volume type. +5. Run the usual authoring commands and full checks. `check` holds each array of steps 2–4 to the + width of the selectable preset that writes it, `check --strict` also to every selectable preset it + reaches, and + the printer's layout keys through every selectable preset + ([variant arrays](validation.md#variant-arrays)); `check_variant_names` holds every variant string, + `extruder_type`, `nozzle_volume_type` and `default_nozzle_volume_type` to the enums + ([variant names](validation.md#variant-names)). The choice of variants, the variant order and + the measured values are not checked. +6. In the app, for each nozzle volume type in the sidebar combo: slice and confirm the G-code uses that + variant's values (e.g. volumetric speed limit, retraction). `validate_slice` only slices the default + nozzle volume type. + +To review rather than author, run the same list against the diff. `check` catches a wrong array length, +a layout key out of step, and a variant string the enums cannot build. The failures no check catches: a +new variant appended instead of inserted at its index, an array widened on a base whose list is +shorter (cut before any child inherits it), a process lacking a pair its printer can select, and a High +Flow variant copied from Standard. + +### UI facts to design around + +- The single-extruder sidebar shows a **nozzle volume type combo** (tooltip `Flow`, in place of the + nozzle-diameter selector) only when `extruder_variant_list` offers more than one distinct variant + string (`support_different_extruders`); four extruders listing `Direct Drive Standard` each show + none. +- The two-extruder sidebar's per-extruder nozzle volume type combos are shown for BBL printers only. + Another vendor's multi-extruder printer falls back to the single-extruder layout: one combo (for the + first extruder) when the variants differ, otherwise the nozzle-diameter selector, so the other + extruders' nozzle volume type stays at `default_nozzle_volume_type`. +- High Flow is hidden from the combo when `printer_variant` is `0.2` or the printer model is + `Bambu Lab X1E`, and E3D High Flow unless `printer_variant` is `0.4` or `0.6`. A variant listed on + another nozzle diameter is never selectable there. +- The filament tab shows a variant switch built from the filament's own `filament_extruder_variant`; + a multi-variant filament whose tab shows none did not resolve its variant list through `include` or + `inherits`. The printer and process tabs show one entry per extruder instead, labelled with that + extruder's live nozzle volume type (two for Hybrid), and only on two-extruder printers whose + `extruder_variant_list` offers more than one variant string; elsewhere they edit the variant of the + nozzle volume type selected in the sidebar (an X1C shows no switch). + +### Worked examples in the tree + +`BBL/machine/fdm_bbl_3dp_001_common.json` (one extruder), `fdm_bbl_3dp_002_common.json` (two +extruders), `Bambu Lab X1 Carbon 0.4 nozzle.json` (Standard + High Flow), `Bambu Lab H2D 0.4 +nozzle.json` (extruders with different variant sets), `Bambu Lab X2D 0.4 nozzle.json` (Direct Drive + +Bowden), with their `@BBL` processes and filaments. The H2D and X2D examples also carry +`E3D High Flow` variants. BBL's multi-variant filament lists come from `fdm_filament_template_*` +presets that the printer-specific filaments pull in with `include`, not from their `inherits` chain. diff --git a/.claude/skills/orca-profiles/references/filament-profiles.md b/.claude/skills/orca-profiles/references/filament-profiles.md index 873e2a6510..0ec5eca24e 100644 --- a/.claude/skills/orca-profiles/references/filament-profiles.md +++ b/.claude/skills/orca-profiles/references/filament-profiles.md @@ -1,8 +1,8 @@ # Filament profiles and OrcaFilamentLibrary -`OrcaFilamentLibrary` is the filament-only bundle the loader reads **first**; its config map -becomes the base bundle, so any vendor may inherit a library preset by name. It is the only cross-bundle -parent — vendor-to-vendor inheritance always fails. +`OrcaFilamentLibrary` is the filament-only bundle the loader reads **first**, so any vendor's filament may +inherit a library preset by name. It is the only cross-bundle parent: vendor-to-vendor inheritance +always fails. ## Where a filament goes @@ -10,63 +10,65 @@ parent — vendor-to-vendor inheritance always fails. | --- | --- | | Generic material for all printers | `OrcaFilamentLibrary/filament/Generic @System.json` | | A brand's product, all printers | `OrcaFilamentLibrary/filament//` | -| A brand's tune for one printer | `OrcaFilamentLibrary/filament///` — recommended; `/filament//` also works | -| A printer vendor's tune of a generic or its own product | `/filament/` | +| A brand's tune for one printer vendor | `OrcaFilamentLibrary/filament///` (recommended); `/filament//` also works | +| A printer vendor's tune of a generic, or its own product | `/filament/` | -Both locations for the last-but-one row are supported: `OrcaFilamentLibrary/filament///.json` +Both locations in the third row are supported: `OrcaFilamentLibrary/filament///.json` (the shape the wiki shows) and `/filament//`. The library path is the one a -filament vendor should contribute to — `OrcaFilamentLibrary/filament//` is the brand's own -folder, while a printer vendor's folder belongs to that printer vendor. Brand tunes do ship under -printer vendors' folders today (Polymaker and SUNLU among others). +filament brand should contribute to: `OrcaFilamentLibrary/filament//` is the brand's own folder, +while a printer vendor's folder belongs to that printer vendor. -Library layout: `filament/base/fdm_filament_*.json` type roots, root-level `Generic @System.json` -generics, and one subfolder per brand, which may nest printer-specific tunes one level deeper. Adding -a brand means adding a folder here; the folder name is a directory label only — `filament_vendor` inside the JSON is the real vendor string. +Library layout: `filament/base/fdm_filament_*.json` material roots, root-level +`Generic @System.json` generics, and one subfolder per brand, which may nest printer-specific +tunes one level deeper. Adding a brand means adding a folder here; the folder name is a directory label +only, and `filament_vendor` inside the JSON is the real vendor string. ## The three-part shape ```jsonc -// Fiberon PA6-CF @base.json — the product root, holds identity + material values +// OrcaFilamentLibrary/filament/Polymaker/Fiberon PA6-CF @base.json — the product root: identity + material values { "type": "filament", "name": "Fiberon PA6-CF @base", "from": "system", "instantiation": "false", "inherits": "fdm_filament_pa", - "filament_id": "OFkOviHk", // generated here; variants inherit it + "filament_id": "OFkOviHk", // minted here by generate-id; every child inherits it "filament_vendor": ["Polymaker"], "filament_type": ["PA6-CF"], /* … */ } -// Fiberon PA6-CF @System.json — the selectable shim, 7 keys +// OrcaFilamentLibrary/filament/Polymaker/Fiberon PA6-CF @System.json — the selectable all-printer shim, 7 keys { "type": "filament", "name": "Fiberon PA6-CF @System", "from": "system", "instantiation": "true", "inherits": "Fiberon PA6-CF @base", "setting_id": "…", "compatible_printers": [] } -// /filament/Polymaker/Fiberon PA6-CF @BBL X1C.json — a printer tune -{ … "inherits": "Fiberon PA6-CF @base", "filament_max_volumetric_speed": ["14"], +// BBL/filament/Polymaker/Fiberon PA6-CF @BBL X1C.json — a printer tune (BBL keeps its own copy of the @base) +{ …, "inherits": "Fiberon PA6-CF @base", "filament_max_volumetric_speed": ["14"], "compatible_printers": ["Bambu Lab X1 Carbon 0.4 nozzle", …] } ``` -- `@base` is the convention for a root. A base carries **no** `setting_id`, no `compatible_printers`, no - `filament_settings_id`. Only the `setting_id` half is enforced, and nothing violates it; the other two - are unchecked and plenty of bases still carry them. Do not copy that from a neighbouring file. -- Every `@System` must be `"instantiation": "true"`. DREMC ships `@System` presets set to `"false"`, - which therefore ship but can never be selected; no check catches it. -- A duplicated brand `@base` across bundles is normal and intentional (`Fiberon PA6-CF @base` exists in - both the library and BBL with the same id, differing only in MVS) — bases never enter the preset - collection, so there is no duplicate-name error. -- You may inherit from an instantiated preset as well as from a base; it is common. +- `@base` is the convention for a root; a root is really `instantiation: "false"`. A base carries + **no** `setting_id`, no `compatible_printers` and no `filament_settings_id`. Only the `setting_id` + half is enforced; the other two are unchecked, so a neighbouring base that carries them is no model. +- Every `@System` shim must be `"instantiation": "true"`; one set to `"false"` would ship but could + never be selected, and no check catches it. The shim exists only for products in the library. +- `filament_cost`, `filament_density`, `filament_type` and `filament_vendor` belong on the root and + should not appear in a printer tune. +- A brand `@base` duplicated across bundles is legal (a vendor bundle may keep its own copy of a + library product root, with the same id): bases never become selectable presets and the + duplicate-name error covers only those, so there is none. +- You may inherit from an instantiated preset as well as from a base. -## Color is a runtime property +## Colour is a runtime property -`filament_id` identifies a product, not a color; filament sync/AMS reads the color from the spool at -runtime. A product ships one all-printer preset and the color is chosen at runtime — never a sibling -preset that differs only by color. A material family (PLA vs PLA Matte vs PLA Silk) is a new product; a -color is not. A printer tune keeps the product alias and does not multiply per color either. +`filament_id` identifies a product, not a colour; filament sync and AMS read the colour from the spool +at runtime. A product ships one all-printer preset and the colour is chosen at runtime, never a sibling +preset that differs only by colour. A material family (PLA vs PLA Matte vs PLA Silk) is a new product; +a colour is not. A printer tune keeps the product alias and does not multiply per colour either. -CI does not catch this — per-color presets pass `check` — so it is a review call. +CI does not catch this (per-colour presets pass `check`), so it is a review call. ## The two most common contributions -**A printer vendor tuning a generic.** Keep the `Generic X` base name so the alias shadows the library -preset on your printers, inherit `Generic X @System`, declare **no** `filament_id` (inheriting the -library's is correct — the product really is the library's generic), and give it a non-empty -`compatible_printers` in its own body: +**A printer vendor tuning a generic.** Keep the `Generic X` alias so it shadows the library preset on +your printers, inherit `Generic X @System`, declare **no** `filament_id` (inheriting the library's is +correct: the product really is the library's generic), and give it a non-empty `compatible_printers` in +its own file: ```jsonc // /filament/Generic PETG @Acme One 0.4 nozzle.json @@ -76,13 +78,14 @@ library's is correct — the product really is the library's generic), and give "compatible_printers": ["Acme One 0.4 nozzle"] } ``` -**A printer vendor's own branded product.** Give it a `@base` root so `generate-id` can mint the id (see -[ids.md](ids.md) — inheriting `Generic X @System` directly makes the id unfixable by the tool), then one -instantiated leaf per printer in the same bundle. No `@System` shim: that is only for a product entering -OrcaFilamentLibrary. +**A printer vendor's own branded product.** Give it a `@base` root on a material base so `generate-id` +can mint the id, then one instantiated leaf per printer in the same bundle. Inheriting +`Generic X @System` directly gives the product the generic's id, which the tool cannot fix +([ids.md](ids.md#what-generate-id-does-and-does-not-fix)). No `@System` shim: that is only for a product +entering OrcaFilamentLibrary. ```jsonc -// /filament/Acme Aura PETG @base.json — instantiation false, no setting_id +// /filament/Acme Aura PETG @base.json — instantiation false, no setting_id { "type": "filament", "name": "Acme Aura PETG @base", "from": "system", "instantiation": "false", "inherits": "fdm_filament_pet", "filament_vendor": ["Acme"], "filament_type": ["PETG"] } // filament_id minted here @@ -94,174 +97,190 @@ OrcaFilamentLibrary. "compatible_printers": ["Acme One 0.4 nozzle"] } ``` -Omit `filament_settings_id` from new presets — it is runtime bookkeeping the app rewrites to the preset +Omit `filament_settings_id` from new presets: it is runtime bookkeeping the app rewrites to the preset name. +To offer either kind by default, add its name to each model's `default_materials`; put it first in the +machine's `default_filament_profile` only if it should be the preselected filament +([machine keys](machine-profiles.md#other-keys)). + ## `compatible_printers` -- **Library fallbacks:** empty `[]` or absent, so they are offered on all printers except where - [alias shadowing](#alias-shadowing) supplies a printer-specific tune. -- **Library printer-specific tunes:** non-empty, listing exact printer **variant** names. These can +- **Library fallbacks** (`@System`): empty `[]` or absent, so they are offered on all printers except + where [alias shadowing](#alias-shadowing) supplies a printer-specific tune. +- **Library printer-specific tunes**: non-empty, listing exact printer **variant** names. These supersede a same-alias fallback just like a tune in a printer vendor's bundle. -- **Instantiated filaments in every other vendor:** non-empty, listing exact printer **variant** names. - Enforced twice but not identically: the C++ `has_errors` reads the *flattened* config, so an inherited list satisfies it, - while the Python check reads the file's **own** key. Write the list in the file itself. This is the - most common filament CI failure. -- Emptying it to "make it apply everywhere" fails that check *and* creates a duplicate-`filament_id` - collision against the library generic on every printer. -- Copying a base's full printer list onto a nozzle-specific variant produces duplicate combobox entries — - a real shipped bug twice over. +- **Instantiated filaments in every other vendor**: non-empty, listing exact printer **variant** names. + Enforced twice, but not identically: `validate_system` reads the resolved config, so an inherited list + satisfies it, while `check` reads the file's **own** key. Write the list in the file itself. This is + the most common filament CI failure. +- Emptying it to "make it apply everywhere" fails that check *and* collides with the library generic's + `filament_id` on every printer. +- Copying a base's full printer list onto a nozzle-specific tune 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 -(`//`). 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. +`filament_id` is the **product** key, not the preset key: every preset of one product shares it +(`//`). 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. `validate_system` reports `Ambiguous AMS filament match: N filament presets share filament_id "X" +and are all compatible with 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 (`@ ` for a whole +Judge specificity from the profile's `compatible_printers` (how many variants it actually covers) and +use the name only as a secondary, often vague hint; decide by the lists, with a judgement call on the +name. Naming conventions differ by vendor: BBL's is the reference (`@ ` for a whole model, `@ nozzle` for one variant, `@` for a vendor-wide generic), but others vary (`@`, a printer serial, or Creality's `@-all`). A name never overrides -the list — see [preset naming](naming.md) for the shapes. +the list; see [preset naming](naming.md#filament) for the shapes. Specificity, most to least: -1. **Variant-specialized** — lists a single printer variant (BBL-style - `... @ nozzle`). -2. **Model-specialized** — lists the variants of one printer model (BBL-style `... @ `). - 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 +1. **Variant-specialized**: lists a single printer variant (BBL-style + `… @ nozzle`). +2. **Model-specialized**: lists the variants of one printer model (BBL-style `… @ `). 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 @`). 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. + 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. + profile, the next level down keeps it; when the model has specialized profiles, the model-level one + wins over the family and generic ones. +- 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 machine's `default_filament_profile` 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. +Several 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. +**Detection caveat:** `orca_profile_tool.py check` is blind to this; only the 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 -on the printers it lists. The matching key is the **alias**: the preset name up to the **first** `@`, -right-trimmed (no `@` → the whole name). So -`QIDI ABS-GF@Q2-Series` aliases to `QIDI ABS-GF`. +A printer-specific filament in either the library or a vendor bundle supersedes the library fallback on +the printers it lists. The matching key is the **alias**: the preset name up to the **first** `@`, +right-trimmed (no `@` → the whole name). So `QIDI ABS-GF@Q2-Series` aliases to `QIDI ABS-GF`. -A library preset with an empty `compatible_printers` collects, into `m_excluded_from`, every printer named -by any same-alias preset that *has* a non-empty list, and is then hidden on those printers. +A library preset with an empty `compatible_printers` is hidden on every printer that a same-alias preset +lists in a non-empty `compatible_printers`, whether that preset is in the library or in a vendor bundle +(a printer matches by its own name or its parent's). Two consequences: -- **Only an unrestricted library fallback can be shadowed.** Two printer-specific presets sharing - an alias do not exclude each other — overlapping lists for the same product trip the - duplicate-`filament_id` check instead. -- This is why adding `Generic PLA @` to a vendor silently removes the library `Generic PLA` - from that printer. Intended — and the reason a vendor tuning a generic must **keep the `Generic X` - base name**. +- **Only an unrestricted library fallback can be shadowed.** Two printer-specific presets sharing an + alias do not hide each other; overlapping lists for the same product trip the ambiguous-match error + above instead. +- This is why adding `Generic PLA @` to a vendor silently removes the library + `Generic PLA @System` from that printer. That is intended, and the reason a vendor tuning a generic + must **keep the `Generic X` alias**. -The literal spelling `Generic @System` is load-bearing beyond shadowing: `find_preset2` rewrites an -unresolved name containing "Generic" into that form and retries against the library, which is how 3MF -and project recovery works. +The literal spelling `Generic @System` is load-bearing beyond shadowing: when a user preset, an +imported preset or a 3MF project names a parent that no longer resolves and contains `Generic`, the +loader rewrites the name into `Generic @System` and retries. Only the library ships those names, +so keep them. ## `filament_id`, `filament_vendor`, `filament_type` -`filament_id` is minted from the triple `(filament_vendor, filament_type, name-before-first-@)`. -`filament_vendor` and `filament_type` are therefore **identity, not decoration** — editing either -re-mints the id. Read `docs/HLSD/filament_id.md` before changing any of them, and see -[ids.md](ids.md) for the tooling. +`filament_id` is minted from the triple `(filament_vendor, filament_type, alias)`. `filament_vendor` and +`filament_type` are therefore **identity, not decoration**: editing either, or the alias, re-mints the +id. Read `docs/HLSD/filament_id.md` before changing any of them, and see [ids.md](ids.md) for the +tooling. -A filament with no resolvable `filament_id` anywhere in its `inherits` chain is a **hard load error** that -discards the vendor bundle. The id inherits across bundles, so a vendor's `Generic ABS @X` inheriting -`Generic ABS @System` gets the library's id for free; a vendor's own product must resolve its own. +A filament with no resolvable `filament_id` anywhere in its `inherits` chain is a **hard load error** +that discards the vendor bundle. The id inherits across bundles, so a vendor's `Generic ABS @X` +inheriting `Generic ABS @System` gets the library's id for free; a vendor's own product must resolve its +own. -- `filament_type` **must be a JSON array** — the one vector key the Python check enforces. A scalar - `"PP"` once hung the filament/printer selection UI. +- `filament_type` **must be a JSON array**: the one vector key `check` rejects as a scalar outright. A + scalar `"PP"` once hung the filament and printer selection UI. - It is an **open** enum: an unlisted value is accepted silently and falls back to 190–300 °C defaults - and adhesion 1.0. Off-list values do ship. Prefer a value from `MaterialType::all()` in + and adhesion 1.0. Prefer a value from `MaterialType::all()` in `src/libslic3r/MaterialType.cpp`, or add a row there. - Generics use `filament_vendor: ["Generic"]`, which `fdm_filament_common` already defaults to. ## `"nil"` -Legal in any key whose `ConfigOptionDef` is `nullable`. In a filament preset that is most of the -`filament_*` family, plus `long_retractions_when_ec` and `retraction_distances_when_ec`. About half are -the extruder overrides (`filament_retraction_length`, `filament_z_hop`, `filament_wipe`, -`filament_retract_*`, `filament_retraction_speed`, `filament_deretraction_speed`, -`filament_retraction_minimum_travel`, `filament_wipe_distance`, `filament_long_retractions_when_cut`, -`filament_retraction_distances_when_cut`, …), where `nil` means *keep the printer/extruder's own value*. -The rest are ordinary nullable options (`filament_flow_ratio`, `filament_flush_temp`, -`filament_adaptive_volumetric_speed`, …) where it means *unset*. +`"nil"` is legal only in an option defined as nullable (`add_nullable`, or `nullable = true`, in +`src/libslic3r/PrintConfig.cpp`). Anywhere else it fails the file, and with it the **whole bundle** +(`Failed loading configuration file`, after `Deserializing nil into a non-nullable object` or +`Invalid value provided for parameter : nil`). To leave a non-nullable key unset, omit it; do not +write `nil`. -Anywhere else it throws `Deserializing nil into a non-nullable object`. To not set a non-nullable key, -omit it — do not write `nil`. +In filament presets a minority of the `filament_*` keys are nullable, plus `long_retractions_when_ec` +and `retraction_distances_when_ec`. About half of them are the extruder overrides (`filament_retraction_length`, +`filament_z_hop`, `filament_wipe`, `filament_retract_*`, `filament_retraction_speed`, +`filament_deretraction_speed`, `filament_retraction_minimum_travel`, `filament_wipe_distance`, +`filament_long_retractions_when_cut`, `filament_retraction_distances_when_cut`, …), where `nil` means +*keep the printer's or extruder's own value*. The rest are ordinary nullable options +(`filament_flow_ratio`, `filament_flush_temp`, `filament_adaptive_volumetric_speed`, …), where it means +*unset*. Check the option's definition before writing `nil` anywhere else. -## What to review per nozzle +## Tuning per nozzle and per variant -Across `@X` / `@X 0.N nozzle` sibling pairs the keys that differ, most often first, are +Between a product's `@X` and `@X 0.N nozzle` tunes the keys that usually differ, most often first, are `filament_max_volumetric_speed`, `filament_retraction_length`, `slow_down_min_speed`, -`filament_flow_ratio`, `slow_down_layer_time`, `nozzle_temperature` and `pressure_advance`. -`filament_cost`, `filament_density`, `filament_type` and `filament_vendor` belong on the `@base` and -should not appear in a printer tune. +`filament_flow_ratio`, `slow_down_layer_time`, `nozzle_temperature` and `pressure_advance` (switched on +by `enable_pressure_advance`). Use measured values for the material, hotend, extruder and nozzle combination. Neither maximum -volumetric speed nor pressure advance has a universal nozzle-only lookup table. When cloning a -0.4 preset for a 0.2 nozzle, explicitly revisit flow limits; do not infer a pressure-advance value -or a required direction of change from diameter alone. +volumetric speed nor pressure advance has a universal nozzle-only lookup table. When cloning a 0.4 +preset for a 0.2 nozzle, explicitly revisit flow limits; do not infer a pressure-advance value, or a +required direction of change, from diameter alone. -## Style - -Overrides, not full copies: a typical instantiated filament preset carries around a dozen non-meta keys, -and a library leaf two or three. Presets that restate fifty-plus keys from their parent do still ship — -Phrozen's single filament preset is that style — but they are the pattern to move away from, not to -copy. Commit `6943b6ddc3` is the stated model (flip true bases to `instantiation: "false"`, strip -`compatible_printers`/`setting_id`/`filament_settings_id`, add `renamed_from` on the survivor). - -Prefer the library's `fdm_filament_*` bases over a vendor-local copy. Phrozen's local -`fdm_filament_common` has drifted from the library's. - -Canonical key order, written by `orca_profile_tool.py normalize` when it rewrites a file: `type`, `name`, -`renamed_from`, `inherits`, `from`, `setting_id`, `filament_id`, `instantiation`, then everything else in -the order you wrote it. Not enforced — a file that leads with `compatible_printers` passes `check`. - -**Every vector-typed (`co*s`) key must be a JSON array.** Only `filament_type` is an outright error, but -`normalize` silently arrayifies five more (`filament_cost`, `filament_density`, -`temperature_vitrification`, `filament_max_volumetric_speed`, `filament_vendor`) and `check` fails when -it would. Every other vector key is on you — including `filament_start_gcode`, `filament_end_gcode`, -`filament_extruder_variant`, `compatible_printers` and the plate temperatures. +On a printer with extruder variants, a filament tunes these per variant too: +`filament_max_volumetric_speed`, `filament_flow_ratio`, `nozzle_temperature`, pressure advance and the +retraction overrides carry one value per variant of `filament_extruder_variant` (Standard, High Flow, …). The +exact key set is [`filament_options_with_variant`](extruder-variants.md#the-four-key-sets); +`slow_down_min_speed` and `fan_max_speed` are not in it. Keep every such array at exactly that width, even where the +setting does not differ per variant, and measure the High Flow variant rather than copying Standard +([extruder-variants.md](extruder-variants.md#filament)). ## Bed temperature is twelve keys, not one -There is no single "bed temperature". Which plate key applies depends on `curr_bed_type`, whose six -selectable values (`btPC`, `btEP`, `btPEI`, `btPTE`, `btPCT`, `btSuperTack`; `btDefault` maps to no key) -`get_bed_temp_key()` turns into `cool_plate_temp`, `eng_plate_temp`, `hot_plate_temp`, -`textured_plate_temp`, `textured_cool_plate_temp` and `supertack_plate_temp` — each with an -`*_initial_layer` twin. +There is no single "bed temperature". The plate type selected for the printer (`Cool Plate`, +`Engineering Plate`, `High Temp Plate`, `Textured PEI Plate`, `Textured Cool Plate`, `Supertack Plate`) +picks one of six keys, each with an `_initial_layer` twin: `cool_plate_temp`, `eng_plate_temp`, +`hot_plate_temp`, `textured_plate_temp`, `textured_cool_plate_temp` and `supertack_plate_temp`. -`textured_cool_plate_temp` is the one most often forgotten. A printer with `support_multi_bed_types` off -hides the selector, and the printer preset's -`default_bed_type` decides which plate is selected for it, but `curr_bed_type` can still hold a stale -value carried over from another printer — so set every plate the printer plausibly has, as the sibling -presets in the bundle do. +`textured_cool_plate_temp` is the one most often forgotten. A non-BBL printer with +`support_multi_bed_types` off hides the plate selector and uses the printer preset's `default_bed_type` +(High Temp Plate, `hot_plate_temp`, when unset or invalid), but a loaded project or a CLI config can +still carry another plate. So set every plate the printer plausibly has, as the sibling presets in the +bundle do. + +## Style + +- Overrides, not full copies: an instantiated filament preset carries around a dozen non-meta keys, + and a library `@System` shim two or three. A preset that restates fifty-plus keys from its parent is + the pattern to move away from, not to copy. Commit `6943b6ddc3` is the stated model for converting such presets: flip true + bases to `instantiation: "false"`, strip their `compatible_printers`, `setting_id` and + `filament_settings_id`, and add `renamed_from` on the surviving selectable preset. A value every + printer tune of a product shares goes on the product's `@base` + ([shared bases](shared-bases.md#levels)). +- Prefer the library's `fdm_filament_*` bases over a vendor-local copy; for a new preset, even in a + bundle whose older presets use one: a local copy drifts from the library's. +- Canonical key order, written by `orca_profile_tool.py normalize` when it rewrites a file: `type`, + `name`, `renamed_from`, `inherits`, `from`, `setting_id`, `filament_id`, `instantiation`, then + everything else in the order you wrote it. Not enforced on its own: a file that leads with + `compatible_printers` passes `check`. +- **Every vector-typed (`co…s`) key must be a JSON array.** Only a scalar `filament_type` is an outright + error; `normalize` silently arrayifies five more (`filament_cost`, `filament_density`, + `temperature_vitrification`, `filament_max_volumetric_speed`, `filament_vendor`), and `check` fails + when it would. Every other vector key is on you, including `filament_start_gcode`, + `filament_end_gcode`, `filament_extruder_variant`, `compatible_printers` and the plate temperatures. diff --git a/.claude/skills/orca-profiles/references/ids.md b/.claude/skills/orca-profiles/references/ids.md index b6a09e9a2f..214a3d719c 100644 --- a/.claude/skills/orca-profiles/references/ids.md +++ b/.claude/skills/orca-profiles/references/ids.md @@ -1,76 +1,78 @@ # `setting_id` and `filament_id` Orca-generated ids are deterministic hashes of identity. **Never invent an id or copy a sibling's -`setting_id`.** Use `scripts/orca_profile_tool.py`; the two special cases are +`setting_id`.** +Use `scripts/orca_profile_tool.py`; the two special cases are [a wrongly inherited filament id](#what-generate-id-does-and-does-not-fix) and [BBL's authoritative setting ids](#bbls-exception-precisely). -`docs/HLSD/filament_id.md` is the authoritative design document for `filament_id` — the id landscape, the -checks CI runs, and the Bambu catalog map. This page is the tooling half. +`docs/HLSD/filament_id.md` is the authoritative design document for `filament_id`: the id landscape, +the checks CI runs, and the Bambu catalog map. This page is the tooling half. | | `setting_id` | `filament_id` | | --- | --- | --- | | Identifies | one selectable preset | one filament **product** | -| Key hashed | `//` | `filament_product///` | -| Shape | 16 base62 chars | `OF` + 6 base62 chars | +| Key hashed | `//` | `filament_product///`, using the resolved (inherited) first values and the name up to the first `@`, right-trimmed | +| Shape | 16 base62 characters | `OF` + 6 base62 characters | | Required on | every `instantiation: "true"` preset | every **instantiated** filament, own or inherited | -| Forbidden on | bases (`instantiation != "true"`) | — (a base is exactly where it belongs) | -| Scope | globally unique across the tree | shared by every variant of the product, in every bundle | +| Forbidden on | bases (`instantiation` not `"true"`) | — (a product's root base is exactly where it belongs) | +| Scope | unique across the whole tree | shared by every preset of the product, in every bundle | -`` is `machine` / `process` / `filament` — the vendor is the **folder** name (`BBL`), not the -display name (`Bambulab`). Renaming a preset changes its `setting_id`; renaming a filament, or editing -its `filament_vendor` or `filament_type`, also changes its `filament_id`. +`` is `machine`, `process` or `filament`, and the vendor is the **folder** name (`BBL`), not the +display name (`Bambulab`). Renaming a preset changes its `setting_id`; renaming a filament's alias, or +editing its `filament_vendor` or `filament_type`, also changes its `filament_id`, and the old id is not +forwarded. ## The tool -Use `scripts/orca_profile_tool.py` with a subcommand: +`scripts/orca_profile_tool.py` takes a subcommand: | Command | Does | | --- | --- | -| `check` | everything CI's `profile_tool` step runs — see [validation.md](validation.md) | +| `check` | everything CI's `profile_tool` step runs; see [validation.md](validation.md#orca_profile_toolpy-check) | | `generate-id` | writes `setting_id` and `filament_id` | | `normalize` | rewrites profile files into their canonical shape | -| `trim` | deletes profile files no `.json` list references | +| `trim` | deletes profile files no `.json` list references | | `update-index` | rebuilds the `*_list` sections from the files on disk | -The order after adding, renaming or deleting files — each step feeds the next, so it is not -interchangeable — is `normalize` → `update-index` → `generate-id` → `check`. -The [authoring workflow](../SKILL.md#creating-or-modifying-a-profile) has the commands. +The order after adding, renaming or deleting files is `normalize` → `update-index` → `generate-id` → +`check`. Each step feeds the next, so it is not interchangeable. The +[authoring workflow](../SKILL.md#creating-or-modifying-a-profile) has the commands. -> **`trim` deletes.** It removes every profile file the index does not list — including the one you just -> added and have not registered yet. Register first, or skip `trim` entirely; it is a cleanup sweep, not +> **`trim` deletes.** It removes every profile file the index does not list, including the one you just +> added and have not registered yet. Register first, or skip `trim` entirely: it is a cleanup sweep, not > part of landing a profile. Preview with `--dry-run`. **Register, then mint.** The `filament_id` pass reads `.json`'s `filament_list`, not the filesystem (the `setting_id` pass walks the filesystem, so a bundle whose index has not landed yet is -still assignable). A new filament file is therefore invisible to `generate-id`'s filament_id pass until -it is registered — its `setting_id` is written regardless. +still assignable). A new filament file is therefore invisible to `generate-id`'s `filament_id` pass +until it is registered; its `setting_id` is written regardless. -- `--dry-run` works on every writing command (`generate-id`, `normalize`, `trim`, `update-index`) - and writes nothing. -- `--filament-id` / `--setting-id` narrow `generate-id`; they exclude each other, and passing neither - writes both. -- `--vendor` is repeatable and narrows **only what is written** — the id is a function of the triple +- `--dry-run` works on every writing command (`generate-id`, `normalize`, `trim`, `update-index`) and + writes nothing. +- `--filament-id` / `--setting-id` narrow `generate-id` to one pass; they exclude each other, and + passing neither writes both. +- `--vendor` is repeatable and narrows **only what is written**: an id is a function of its own key alone, so a narrowed run writes exactly what a full run would. An unknown vendor exits 1 before any write. `--vendor` on `check` narrows the per-vendor checks only; the `setting_id` and `filament_id` passes stay tree-wide. -- `--profiles DIR` points any command at another tree — see +- `--profiles DIR` points any command at another tree; see [Checking a copy of the tree](validation.md#checking-a-copy-of-the-tree). - `--profile-type` narrows `normalize`, `trim` and `update-index` to `machine_model`, `process`, `filament` or `machine`. - Exit codes: 0 clean, 1 errors found (`generate-id` still writes what it could), 2 argparse misuse. - Output is ANSI-coloured; searching for the literal `[ERROR]` still works. -`generate-id` is **idempotent and byte-preserving** — BOM and CRLF kept, one key line touched per pass. -A legitimate `generate-id` diff is one or two changed lines per file: a new instantiated filament gets -both a `filament_id` and a `setting_id`, and a BBL file with a misspelled `settings_id` has that line -dropped and its value restored under the right key. `normalize` is the opposite by design — it rewrites -whole files into canonical shape — which is why `check` demands it already be a no-op. Some bundles have -CRLF committed (OrcaFilamentLibrary, Anycubic and RH3D among them), so a `normalize` pass there rewrites -every line — read the diff before committing it. +`generate-id` is **idempotent and byte-preserving**: BOM and CRLF are kept, and each pass touches only +its one key line. A legitimate `generate-id` diff is one or two changed lines per file: a new instantiated +filament gets both a `filament_id` and a `setting_id`. `normalize` is the opposite by design (it +rewrites whole files into canonical shape), which is why `check` demands it already be a no-op. A file +committed with CRLF line endings changes on every line under `normalize`; read the diff before +committing it. -On a clean tree `check` and `generate-id --dry-run` both exit 0 with zero findings. That is the -baseline to restore before opening a PR. +Exit 1 from `generate-id` does not mean nothing was written: it writes every id it can and reports the +rest, so read the diff before rerunning. On a clean tree `check` and `generate-id --dry-run` both exit 0 +with zero findings; that is the baseline to restore before opening a PR. ## What `generate-id` does and does not fix @@ -78,35 +80,37 @@ Writes: - a `setting_id` into any instantiated preset that lacks one, or whose value does not match the formula; - strips a `setting_id` from a base; -- deletes the misspelled `settings_id` key; +- deletes the misspelled key `settings_id`, moving its value to `setting_id` only on an instantiated BBL + preset that lacks one (everywhere else the old value is discarded and a fresh id minted); - a `filament_id` into the id-less **root(s)** of an instantiated filament that resolves none; - rewrites a **declared** `filament_id` that is not the mint of its own triple. Refuses to write (reports only): a base62 collision between two products, an empty `filament_vendor` or -`filament_type`, a broken `inherits` chain, roots of one filament resolving divergent `(vendor, type)` -pairs. +`filament_type`, a broken `inherits` chain, and roots of one filament resolving different +`(filament_vendor, filament_type)` pairs. -**Does not fix: a preset that *inherits* a wrong `filament_id`.** This is check 2b, and it is the trap -most likely to bite. It happens when a branded filament inherits a generic for its settings: +**Does not fix: a preset that *inherits* a wrong `filament_id`.** This is check 2b (the label `docs/HLSD/filament_id.md` and the tool use), and it is the trap most likely to bite. +It happens when a branded filament inherits a generic for its settings: ```jsonc { "name": "Phrozen Aura PETG @Phrozen Arco 0.4 nozzle", - "inherits": "Generic PETG @System" } // resolves the OFL generic's id — wrong product + "inherits": "Generic PETG @System" } // resolves the library generic's id: wrong product ``` -The preset resolves *an* id, so `generate-id` neither inserts nor rewrites, and `check` fails with +The preset resolves *an* id, so `generate-id` neither inserts nor rewrites one, and `check` fails with `inherits filament_id "X" but its own triple "V/T/N" mints "Y"`. Two fixes, in order of preference: 1. **Give the product a `@base` root** inheriting a material base (`fdm_filament_pet`, - `fdm_filament_pla`, …). No `fdm_filament_*` base carries a `filament_id`, so the filament now resolves - none and `generate-id` mints it for you. This is also the shape the rest of the tree uses. -2. **Declare the tool-computed key on the preset itself.** Use the expected value reported by `check` - or compute it with the function below; this is not a manually chosen id. Make sure the preset - resolves the right `filament_vendor` and `filament_type` first — with - neither set, the triple resolves through the generic parent and the branded product is minted - under vendor `Generic`. If you need the id before the file exists: + `fdm_filament_pla`, …) with its own `filament_vendor` and `filament_type`. No `fdm_filament_*` base + carries a `filament_id`, so the filament now resolves none and `generate-id` mints it on the root. + This is the product-root shape ([the three-part shape](filament-profiles.md#the-three-part-shape)). +2. **Declare the tool-computed id on the preset itself.** Use the expected value `check` reports, or + compute it with the function below; this is not a manually chosen id. First make sure the preset + resolves the right `filament_vendor` and `filament_type`: with neither set, the triple resolves + through the generic parent and the branded product is minted under vendor `Generic`. If you need the + id before the file exists: ```bash python3 -c "import sys; sys.path.insert(0,'scripts'); from orca_profile_tool import generate_filament_id as g; print(g('Polymaker','PLA','PolyLite PLA'))" @@ -114,36 +118,39 @@ Two fixes, in order of preference: ``` The quoting works unchanged in cmd and PowerShell; only swap `python3` for `py -3`. + `generate_preset_setting_id('', '', '')` is the `setting_id` equivalent. - The `setting_id` equivalent is `generate_preset_setting_id('', '', '')`. +A vendor's tune of a generic that keeps the `Generic X` alias is not this case: inheriting the +generic's id is correct there, because the product really is the library generic +([filament-profiles.md](filament-profiles.md#the-two-most-common-contributions)). ## BBL's exception, precisely -`RESERVED_VENDORS = {"BBL"}` covers **`setting_id` assignment only**, keyed on the *folder* name: +The exception covers **`setting_id` assignment only**, keyed on the *folder* name `BBL`: -- The tool never mints or replaces a BBL `setting_id`. A new instantiated BBL preset with no - `setting_id` therefore **cannot be fixed by the tool**, yet the presence rule still applies to it — - carry over Bambu's authoritative id by hand. +- The tool never mints or replaces a `setting_id` in `BBL/`: those are Bambu's own ids. A new + instantiated BBL preset with no `setting_id` therefore **cannot be fixed by the tool**, yet the + presence rule still applies to it: carry over Bambu's authoritative id by hand. - BBL is not exempt from anything else: bases still get their `setting_id` stripped, ids must still be - globally unique, and BBL `filament_id`s are minted like everyone else's — every one of them is an - `OF*`. + unique across the tree, and BBL `filament_id`s are minted like everyone else's, as `OF…` ids. ## Ids other systems compose -No id from another system is the mint of a triple, so `check` rejects it like any other bad id — same -error, same remedy, whoever wrote it. Three such spaces exist near the tree; recognise them so you do -not copy one into a profile: +No id from another system is the mint of a triple, so `check` rejects one used as a `filament_id` like +any other bad id: same error, same remedy, whoever wrote it. Three such spaces exist near the tree; +recognise them so you do not copy one into a profile: -- **Bambu's `GF*` catalog** — external and opaque, correlated to Orca's ids by the generated - `resources/printers/bambu_filament_ids.json`. `GF` is a *prefix*, not a spelling the tree avoids: most - BBL `setting_id`s start with `G`, and `blacklist.json` and - `BBL/filament/filaments_color_codes.json` both reference Bambu catalog ids by design. The rule is - about `filament_id` and nothing else. -- **Qidi's `QD_*`** — composed at runtime by the box (`QD___`), not a preset id. -- **`P` + 7 hex, and `"null"`** — what `CreatePresetsDialog.cpp` gives a *user*-created filament. +- **Bambu's `GF…` catalog**: external and opaque, correlated to Orca's ids by the generated + `resources/printers/bambu_filament_ids.json`. `blacklist.json` and + `BBL/filament/filaments_color_codes.json` reference Bambu catalog ids by design. The rule is about + `filament_id` and nothing else: every BBL `setting_id` starts with `G`, and that is Bambu's own + preset id, not a leaked catalog id. +- **Qidi's `QD_…`**: composed at runtime by the printer's filament box + (`QD___`), not a preset id. +- **`P` + 7 hex digits, and `"null"`**: what the app gives a *user*-created filament. ## Tests -`python3 -m unittest discover -s scripts/tests -t scripts` (`py -3 -m …` on Windows). Note the -`-t scripts` argument; without it the imports fail. CI runs them as the first, non-`continue-on-error` -step of the profile job — see [validation.md](validation.md#ci). +`python3 -m unittest discover -s scripts/tests -t scripts` (`py -3 -m …` on Windows) runs the tool's +unit tests. Note the `-t scripts` argument; without it the imports fail. CI runs them as the first, +non-`continue-on-error` step of the profile job; see [validation.md](validation.md#ci). diff --git a/.claude/skills/orca-profiles/references/machine-profiles.md b/.claude/skills/orca-profiles/references/machine-profiles.md index 01071af6b1..de338f14ee 100644 --- a/.claude/skills/orca-profiles/references/machine-profiles.md +++ b/.claude/skills/orca-profiles/references/machine-profiles.md @@ -1,23 +1,23 @@ # Printer models and variants -Both live in `resources/profiles//machine/*.json`; models go in `machine_model_list`, variants -and shared bases in `machine_list`. Every one of them is registered. Some vendors (Elegoo, Eryone, -InfiMech, FlyingBear) nest a further subfolder under `machine/`, so recurse rather than globbing -`machine/*.json`. +Both live in `resources/profiles//machine/`; models go in `machine_model_list`, variants and +shared bases in `machine_list`. Every one of them is registered. A bundle may nest further subfolders +under `machine/`, so recurse rather than globbing `machine/*.json`. -## A `machine_model` is not a config preset +## `machine_model`: a record, not a config preset -It is parsed by a hand-written key switch, and only these keys are stored (`version` and `url` are -matched and discarded): +The loader reads a fixed set of keys from a `machine_model` and stores only these (`version` and `url` +are recognised and discarded): `name`, `model_id`, `nozzle_diameter`, `machine_tech`, `family`, `bed_model`, `bed_texture`, `hotend_model`, `default_materials`, `not_support_bed_type`, `image_bed_type`, `bottom_texture_end_name`, `bottom_texture_rect`, `bottom_texture_rect_longer`, `middle_texture_rect`, `use_double_extruder_default_texture`. -**Everything else is silently dropped.** Only `name` and `nozzle_diameter` are required. Dead keys ship -on real models today — `url`, `default_bed_type`, even a `desciption` typo — so a neighbour carrying a -key is no evidence it does anything. Printer config options belong on the `machine` preset, never here. +**Everything else is silently dropped**, a printer config key such as `default_bed_type` or a +misspelling included, so a neighbour carrying a key is no evidence it does anything. Printer config options belong on the `machine` preset, never here. The loader drops a model +silently if its index entry has no name or its `nozzle_diameter` yields no sizes; `check` also requires +the file's own `name`. ```json { @@ -36,28 +36,28 @@ key is no evidence it does anything. Printer config options belong on the `machi | Field | Notes | | --- | --- | -| identity | **the `name` of the `machine_model_list` entry**, which is what a variant's `printer_model` must equal. `check_name_consistency` forces it to equal the file's `name`, so they coincide. | -| `model_id` | a *separate* cloud/device printer type. Optional, and not required to be unique. Not the model's identity. Changing it changes device matching. | -| `machine_tech` | only `starts_with("SL")` means SLA; everything else is FFF. Write `FFF`; a few models write `FGF`, which is a label with no effect. | -| `nozzle_diameter` | `;`-separated string, one token per available size. Order is free (Qidi writes `0.4;0.2;0.6;0.8` to put the default first). This list is the authoritative set of legal `printer_variant` values. | -| `default_materials` | `;`-separated filament **preset names**. Used to preselect in the wizard *and* by `PresetBundle::load_installed_filaments` to auto-install a printer's filaments on first run, so a dangling entry costs a real user a filament. Not `,`; case-sensitive (`@System`). `check` fails on a dangling name here or in `default_filament_profile`. | +| identity | **the `name` of the `machine_model_list` entry**, which is what a variant's `printer_model` must equal. `check` forces it to equal the file's `name`, so they coincide. | +| `model_id` | a *separate* cloud/device printer type. Optional, and not required to be unique. Not the model's identity; changing it changes device matching. | +| `machine_tech` | only a value starting with `SL` means SLA; everything else is FFF. Write `FFF`; `FGF` behaves as FFF. | +| `nozzle_diameter` | `;`-separated string, one token per available size. Order is free (`0.4;0.2;0.6;0.8` puts the default first). This list is the authoritative set of legal `printer_variant` values. | +| `default_materials` | `;`-separated filament **preset names**, not `,`; case-sensitive (`@System`); order is ignored. Used to preselect filaments in the setup wizard *and* to install a printer's filaments on first run, so a dangling entry costs a real user a filament. Every name must exist (`check` fails on a name matching no filament file, here or in `default_filament_profile`), and every variant of the model needs at least one entry compatible with it (`validate_system`). | | `family` | a wizard grouping label only; give every model one. | ### Assets -`bed_model`, `bed_texture` and `hotend_model` are paths relative to the **vendor folder** (by id). -Majority convention: `_buildplate_model.stl` and `_buildplate_texture.svg`. An empty string -is the legal "none", and is the norm for `hotend_model`. +`bed_model`, `bed_texture` and `hotend_model` are paths relative to the **vendor folder** (named by the +vendor id). Convention: `_buildplate_model.stl` and `_buildplate_texture.svg`. An +empty string is the legal "none", and is the norm for `hotend_model`. -**Nothing checks that the file exists.** A missing `hotend_model` falls back to -`resources/profiles/hotend.stl`; a missing `bed_model`/`bed_texture` just renders nothing. Broken -references already ship. Verify by hand. +**Nothing checks that the files exist.** A missing `hotend_model` falls back to +`resources/profiles/hotend.stl`; a missing `bed_model` makes the bed render as a generic custom bed, and a missing +`bed_texture` renders no texture. +Verify by hand, in exact case. -Every model also has a `_cover.png` in the vendor folder — treat it as required, not optional. -240×240 is the cap `scripts/optimize_cover_images.py` enforces and the size most covers already use. -A missing cover degrades to a placeholder in both the wizard and the sidebar. +Every model also has a `_cover.png` in the vendor folder; treat it as required, not optional. +240×240 is the cap `scripts/optimize_cover_images.py` enforces. A missing cover degrades to a placeholder in both the wizard and the sidebar. -## The `machine` variant +## `machine`: the variant ```json { @@ -79,116 +79,154 @@ A missing cover degrades to a placeholder in both the wizard and the sidebar. Minimum viable key set: `type`, `name`, `from`, `instantiation`, `setting_id`, `inherits`, `printer_model`, `printer_variant`, `nozzle_diameter`, `printable_area`, `printable_height`, -`default_print_profile`. The four keys without which the preset will not load at all are `name`, -`instantiation`, `printer_model` and `printer_variant`; `default_filament_profile` is an array -(`["Generic PLA @System"]`) and the model's `default_materials` a `;`-separated string. Unlike a -`machine_model`, a `machine` **is** config-loaded, so a key belonging to another preset type is a -reported error (a misspelled key is still silent). +`default_print_profile`. `default_filament_profile` is optional; when written it +is an array (`["Generic PLA @System"]`), while the model's `default_materials` is a `;`-separated +string. Unlike a `machine_model`, a `machine` **is** a config preset, so a key belonging to another +preset type is a reported error and is removed; a misspelled key is still dropped silently. -### `printer_variant` — three hard rules +### `printer_model` and `printer_variant` -1. Non-empty, and an exact member of the model's `;`-separated `nozzle_diameter` list. -2. `printer_model` non-empty and naming a model of this vendor. -3. In validation mode, for instantiated presets only: split `printer_variant` on `+`, each token must - start with a number (a trailing non-numeric suffix such as `HF` is ignored), and the resulting **set** - must equal `set(nozzle_diameter)`. +1. `printer_model` is non-empty and names a model of this bundle exactly. +2. `printer_variant` is non-empty and an exact token of that model's `;`-separated `nozzle_diameter` + list. +3. For instantiated presets, when validating: split `printer_variant` on `+`; each token must start + with a number (a trailing non-numeric suffix such as `HF` is ignored), and the resulting **set** must + equal the set of `nozzle_diameter` values. -Rules 1 and 2 are loader-enforced — failing either drops the preset *and* the whole bundle. Rule 3 only -raises a validation error: the preset still loads, but the validator exits non-zero. +Rules 1 and 2 are loader-enforced: failing either discards the whole bundle. Rule 3 only raises a +validation error: the preset still loads, but the validator exits non-zero. -`nozzle_diameter` lists one entry **per physical nozzle**; `printer_variant` lists the **distinct** -diameters joined with `+`. Snapmaker U1 is the worked case: `["0.4","0.4","0.6","0.6"]` against -`"0.4+0.6"` — it passes because the comparison is on sets. +`nozzle_diameter` lists one entry **per extruder**; `printer_variant` lists the **distinct** diameters +joined with `+`: `["0.4","0.4","0.6","0.6"]` against `"0.4+0.6"` passes because the comparison is on +sets. -The conventional values are `0.2`, `0.25`, `0.4`, `0.5`, `0.6`, `0.8` and `1.0`. Suffixed forms -(`0.4HF`, `0.6HF`, `0.8HF`, `0.4HS`) are Flashforge-only and the `+` form is rare. A variant is **not** -required to be unique within a model — Volumic ships `EXO42 IDRE`, `… COPY MODE` and `… MIRROR MODE` all -at `0.4` under the one model `EXO42 IDRE`. +Write `printer_variant` as a bare diameter matching the model's list, with no unit. The conventional +values are `0.2`, `0.25`, `0.4`, `0.5`, `0.6`, `0.8` and `1.0`; a suffixed form (`0.4HF`, `0.4HS`) or +the `+` form is legal under rule 3. A `printer_variant` is **not** required to be unique within a +model: an IDEX model's normal, `COPY MODE` and `MIRROR MODE` presets can all be `0.4`. The converse is **unchecked**: a nozzle size in the model's list with no matching variant is offered in -the wizard and resolves to nothing. `Wanhao France`'s `D12 500 PRO M2 DIRECT` ships that bug today. +the wizard and resolves to nothing. A variant whose `printer_model` names a sibling model by mistake +leaves its own model's size in exactly that state. -### Other fields worth knowing +### Other keys -- `default_print_profile` is a **scalar**, matched by exact preset name. Not a `;` list. The named +- `default_print_profile` is a **scalar**, matched by exact preset name; not a `;` list. The named process must be compatible with this printer through its resolved list or condition. `validate_slice` attempts to select it and rejects generic Default fallbacks, but compatibility - updates can choose another compatible preset. Check the exact default reference yourself. -- `default_filament_profile` is an **array**, one name per element. -- `printable_area` is an array of `"XxY"` strings — four points for a rectangle, one per segment for a - delta or circular bed. -- `gcode_flavor` is usually set once in the base; `klipper`, `marlin`, `marlin2` and `reprapfirmware` - cover nearly every shipped printer. -- `printer_settings_id` is junk — most files carrying it disagree with their own name. Do not copy it - when cloning a bundle. -- `min_layer_height` / `max_layer_height` are **machine** keys (per extruder), never process keys. + updates can choose another compatible preset, and `check` does not resolve the name. Check the exact + default reference yourself. +- `default_filament_profile` is an **array**, one name per element. Entry 0 is the filament preselected + when the printer is chosen; entry *i* is the preferred replacement when filament *i* is incompatible, + and any listed name outranks an unlisted one. The validator checks every entry. The list of a + printer's filaments is the model's `default_materials`: a new filament goes into `default_materials`; + put it first in `default_filament_profile` only if it should become the preselected one. +- `printable_area` is an array of `"XxY"` strings: four points for a rectangle; a delta or other circular bed + is a polygon with one point per segment. +- A non-BBL printer shows the plate selector only with `support_multi_bed_types` `"1"`; otherwise it + uses its `default_bed_type` (a plate name such as `"Textured PEI Plate"`; High Temp Plate when unset). + Filaments still set every plate + ([twelve keys](filament-profiles.md#bed-temperature-is-twelve-keys-not-one)). +- `gcode_flavor` is usually set once in the base; the common values are `klipper`, `marlin`, `marlin2` + and `reprapfirmware`. +- `printer_settings_id` does nothing in a preset file: the app replaces it with the selected preset's + name before slicing. Omit it, and do not copy it when cloning a bundle. +- `min_layer_height` / `max_layer_height` are **machine** keys (one per extruder), never process keys. ## Bases -Nearly every machine-bearing vendor registers a base literally named `fdm_machine_common`, and Klipper -vendors add `fdm_klipper_common` on top of it. Two levels is the usual depth. +The conventional machine root is a base named `fdm_machine_common`, with `fdm_klipper_common` on top +of it for Klipper printers. Which values a hardware +family or model base holds, and when adding one pays off, is in [shared-bases.md](shared-bases.md). **There is no leading-underscore convention for bases.** ## Adding a printer to an existing bundle -1. Choose the names first — model, variant(s), process(es); everything else references them. +1. Choose the names first: model, variant(s), process(es); everything else references them + ([naming.md](naming.md)). 2. Add the model (`machine_model_list`) and one `machine` variant per nozzle; the minimum key sets are above. Bed assets and `_cover.png` go directly in `/`. 3. Add at least one process per variant naming it in `compatible_printers` ([process-profiles.md](process-profiles.md#adding-a-quality-tier-or-a-nozzles-processes)). -4. Register everything (or run `update-index`), bump the version, run the id tool, validate. +4. Add the variants to the filaments they should offer, and set the model's `default_materials` so every + variant has a compatible entry. +5. Register everything (`update-index`), bump the version, run the id tool, validate: the + [authoring workflow](../SKILL.md#creating-or-modifying-a-profile). ## Adding a nozzle variant 1. Extend the model's `nozzle_diameter` (`"0.4"` → `"0.4;0.6"`). -2. Add the variant preset. Either inherit the shared base (the usual choice) or the 0.4 sibling (Elegoo, - BBL, Prusa and Qidi do this — smaller diff, but the sibling's edits now reach this file too). -3. Override what actually changes with nozzle: `nozzle_diameter`, `printer_variant`, - `default_print_profile`, `default_filament_profile`, `min_layer_height`/`max_layer_height`, and +2. Add the variant preset. Either inherit the shared base (the usual choice), or the 0.4 sibling + (a smaller diff, but the sibling's edits now reach this file too). Follow the bundle. +3. Override what actually changes with the nozzle: `nozzle_diameter`, `printer_variant`, + `default_print_profile`, `default_filament_profile`, `min_layer_height` / `max_layer_height`, and retraction if the vendor tunes it. -4. Add at least one process for the new nozzle — see [process-profiles.md](process-profiles.md). +4. Add at least one process for the new nozzle (see [process-profiles.md](process-profiles.md)), and + extend the filaments' `compatible_printers` so at least one `default_materials` entry covers the new + variant. 5. Register both, bump the version, run the id tool, validate. -## Multi-extruder, IDEX and tool-changers +## Multi-extruder, IDEX and tool changers -Per-extruder vectors are **silently resized** to the nozzle count, with no error. Padding repeats the -**first** value, not the last — `["0.4","0.6"]` on a 4-nozzle machine becomes `0.4, 0.6, 0.4, 0.4`. -Longer vectors are truncated. +Per-extruder vectors hold one value per extruder (`len(nozzle_diameter)`), and a wrong length raises no +error: a short vector acts as padded with its **first** value, not the last (`extruder_offset` +`["0x0","50x0"]` on a 4-extruder machine reads as `0x0, 50x0, 0x0, 0x0`), and entries beyond the +extruder count are never read. -Note the two sizing families: the plain per-extruder keys (`extruder_offset`, `extruder_colour`, -`extruder_printable_height`, `min_layer_height`, `max_layer_height`, `nozzle_diameter`) are sized to the -extruder count, while `printer_options_with_variant_1` (`retraction_length`, `z_hop`, `wipe`, -`nozzle_type`, the rest of the retraction family) is sized to `printer_extruder_variant` instead. +Note the two sizing families. The plain per-extruder keys (`printer_extruder_options`: `extruder_type`, +`nozzle_diameter`, `default_nozzle_volume_type`, `extruder_printable_height`, `min_layer_height`, +`max_layer_height`, …, given in full with the [key sets](extruder-variants.md#the-four-key-sets), plus +`extruder_offset` and `extruder_colour`) hold one value per extruder. The variant sets +(`retraction_length`, `z_hop`, `wipe`, `nozzle_type`, the `machine_max_*` limits at stride 2; +[the full lists](extruder-variants.md#the-four-key-sets)) are sized to the variant length: +`len(printer_extruder_variant)`, or one variant per extruder when the resolved preset writes no layout, +since `extruder_variant_list` defaults to one `Direct Drive Standard` per extruder +([widths](extruder-variants.md#widths)). `extruders_count` is a printer-tab field, not a preset key; the +loader drops it. - Give **one entry per extruder** for ordinary per-extruder vectors such as `extruder_offset`, - `extruder_colour`, `min_layer_height` and `max_layer_height`; size the variant-dependent family - to `printer_extruder_variant` instead. - A single `["0x0"]` `extruder_offset` on a dual or multi-tool machine — which already ships — pads every - toolhead to the same offset, so the offset never applies. -- Overriding `nozzle_diameter` to a different count without re-stating every per-extruder vector is the - other half of the trap — `Snapmaker U1 (0.4+0.6 nozzle)` inherits 5-entry vectors against 4 nozzles. + `extruder_colour`, `min_layer_height` and `max_layer_height`. Size the variant sets to the variant + length × stride, one value per variant (per extruder when there is no layout; a (normal, silent) + pair for the `machine_max_*` limits), even where the values are the same; the loader keeps only the first value of a list-less printer's variant arrays, so declare + the layout when the extruders differ. A single `["0x0"]` `extruder_offset` on a dual or + multi-extruder machine pads every extruder to the same offset, so the offset never applies. +- Overriding `nozzle_diameter` to a different count without restating every per-extruder vector is the + other half of the trap: a 4-extruder preset on a 5-extruder base inherits 5-entry vectors against 4 + extruders. + The reverse is silent too: a base is stored resized to its own `printer_extruder_variant` (one variant + when it writes none, whatever its extruder count), so a wider variant array on it reaches the children + as its first value padded ([composition](extruder-variants.md#padding-truncation-and-composition)). + `check` does not judge the base on its own; where its extruders need different values, declare the + layout on the base. -Copy targets: `Custom/machine/fdm_toolchanger_common.json` + `Custom/machine/MyToolChanger 0.4 -nozzle.json` (a clean minimal variant on a base that gives every vector five entries), and -`Ratrig/machine/RatRig V-Core 4 IDEX 300 0.4 nozzle.json` for IDEX. The BBL extruder-variant machinery -(`extruder_variant_list`, `printer_extruder_id`, `default_nozzle_volume_type`) is used by a handful of -vendors — do not copy it into a new bundle (`nozzle_volume_type` itself is not a machine-preset key). +Structure to copy: `Custom/machine/fdm_toolchanger_common.json` + `Custom/machine/MyToolChanger 0.4 +nozzle.json` (a minimal variant on a base that gives the per-extruder vectors five entries), and +`Ratrig/machine/RatRig V-Core 4 IDEX 300 0.4 nozzle.json` for IDEX. Take the structure from them and +the widths from the [sizing equation](extruder-variants.md#sizing-equation). Both are list-less, so +every variant array holds one value per extruder and the loader keeps only the first: fine while every +extruder shares the same retraction and limits. Add the extruder-variant layout +(`extruder_variant_list`, `printer_extruder_variant` / `printer_extruder_id`, +`default_nozzle_volume_type`) when the hardware has swappable nozzle volume types or mixed extruder +types, or as soon as one extruder needs its own value in a variant key; how to author it, and the +matching process and filament variants, is in [extruder-variants.md](extruder-variants.md). +(`nozzle_volume_type` itself is not a machine-preset key.) ## Custom G-code The keys are `machine_start_gcode`, `machine_end_gcode`, `change_filament_gcode`, -`machine_pause_gcode`, `before_layer_change_gcode` and `layer_change_gcode`. Both a single string with -embedded `\n` and a JSON array of lines are legal and both are in use — do not convert one into the -other. Conditionals are `{if …}` / `{elsif …}` / `{else}` / `{endif}`; `{elsif}` is rare but real (Qidi's -`layer_change_gcode` uses it). +`machine_pause_gcode`, `before_layer_change_gcode` and `layer_change_gcode`. Each is one string with +embedded `\n`. Never split G-code into a JSON array of lines: the loader joins array elements with `,` +into a single line (a one-element array is equivalent to the string): a two-element +`machine_start_gcode` becomes one line, `PRINT_START …,SET_PRESSURE_ADVANCE ADVANCE=0.046`. +Conditionals are `{if …}` / `{elsif …}` / `{else}` / `{endif}`. -Placeholder errors only surface when the config is actually expanded, which means `validate_slice`: +Placeholder errors only surface when the G-code is actually expanded, which means `validate_slice`: ```bash ./scripts/check_profile.sh --vendor "" validate_slice # Windows: scripts\check_profile.bat -Vendor "" validate_slice ``` -What the sweep covers is in [validation.md](validation.md#validate_slice); no `CP TOOLCHANGE START` in -the output means `change_filament_gcode` never expanded. +What the sweep covers is in [validation.md](validation.md#validate_slice); a printer whose output has no +`CP TOOLCHANGE START` fails it, because its `change_filament_gcode` never expanded. diff --git a/.claude/skills/orca-profiles/references/naming.md b/.claude/skills/orca-profiles/references/naming.md index cad82ebb6b..e2fd5a4d88 100644 --- a/.claude/skills/orca-profiles/references/naming.md +++ b/.claude/skills/orca-profiles/references/naming.md @@ -1,90 +1,94 @@ # 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` | `` | the exact string, named by a variant's `printer_model` | -| `machine` | ` nozzle` | the exact string, named by `compatible_printers`; `printer_variant` must equal a nozzle diameter | -| `process` | `mm @` | the exact string when referenced or selected; the `@` half is a label | -| `filament` | ` @` | text before the first `@` is the **alias**, used for shadowing; the rest is a label | +A preset's `name` is its identity, not decoration. The index registers it; `inherits`, +`compatible_printers`, `printer_model` and the `default_*` keys reference it by the exact, +case-sensitive string; `renamed_from` migrates it; `setting_id` and `filament_id` hash it +([ids.md](ids.md)). Treat a name change as an identity change that needs +[migration](vendor-bundle.md#renamed_from), not a relabel. Which part of each name the loader acts on +is the table in [SKILL.md](../SKILL.md#names); this page holds the conventions. ## `machine_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 `_cover.png` and bed-asset stem. +``, vendor-prefixed: `Bambu Lab X1 Carbon`, `Creality K1`, `Prusa CORE One`. Each variant's +`printer_model` names it verbatim (a mismatch discards the bundle), and its index entry equals the +file's `name`. It is also the stem of `_cover.png` and, by convention, of the bed assets +(`_buildplate_model.stl`). ## `machine` (variant) -` 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__common`. +` nozzle` is near-universal (`Bambu Lab X1 Carbon 0.4 nozzle`). Casing varies +(`nozzle` / `Nozzle`): match the bundle, not this page. A variant that is not nozzle-specific (a +special toolhead, a multi-material build, IDEX copy and mirror modes such as +` COPY MODE (0.4 nozzle)`) may drop or reshape the suffix; it is still an exact reference. `printer_variant` +holds the nozzle token: `0.4`, a suffixed `0.4HF`, or `0.4+0.6` for mixed nozzles +([rules](machine-profiles.md#printer_model-and-printer_variant)). ## `process` -`mm @` — [process-profiles.md](process-profiles.md#naming) has the -quality ladder and the `fdm_process_*` base names. The quality label stays before `@` and the printer -target after it: a printer model in the quality slot leaves the tier undescribed. The `@` 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. +`mm @`. The quality word stays before `@` and the printer target after +it: a printer model in the quality position leaves the tier undescribed. The `@` is a label, +and need not equal any variant name; compatibility comes from `compatible_printers` or the +condition. The quality ladder and per-nozzle labels are in +[process-profiles.md](process-profiles.md#naming). ## `filament` -` @`. 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: +` @`. The product half, up to the first `@` and right-trimmed, is the **alias**: +shadowing matches on it and `filament_id` hashes it. The target half is a label, except for the +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, and the convention for an all-printer product - (` @System`, empty `compatible_printers`); not enforced, so a deviation is worth a review - comment. The literal `Generic @System` is load-bearing for 3MF/project recovery, beyond the - alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)). -- `@`, `@ `, `@ nozzle` — printer tunes, BBL's shape. - Other vendors differ (a bare model, a printer serial, Creality's `@-all`). Specificity is judged - from `compatible_printers`, not the name +- `@base`: a non-instantiated product root. Convention only; a base is really + `instantiation: "false"` without `setting_id` + ([the three-part shape](filament-profiles.md#the-three-part-shape)). +- `@System`: the OrcaFilamentLibrary selectable shim, and the convention for an all-printer product + (` @System`, empty `compatible_printers`). Not enforced, so a deviation is worth a review + comment. The literal `Generic @System` is also load-bearing for project recovery + ([alias shadowing](filament-profiles.md#alias-shadowing)). +- Printer tunes. BBL's shape is the reference: `@` (vendor-wide), `@ ` (one + model), `@ nozzle` (one variant). Other vendors differ: a bare model + (`QIDI ABS-GF@Q2-Series`), a printer serial, Creality's `@-all`. Judge specificity from + `compatible_printers`, never from the name ([one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)). -- Color is not part of the product name: ` ` presets are not authored; the color is - chosen at runtime - ([color is a runtime property](filament-profiles.md#color-is-a-runtime-property)). +- No colour in the product name: ` ` presets are not authored; colour is chosen at + runtime ([colour](filament-profiles.md#colour-is-a-runtime-property)). -## Checking names - -Check every newly added profile's `name` against its type and role: model, selectable preset or base. -Apply the same checks to an intentional name change. The human-readable naming shapes are not enforced -by `check`: inspect the added or renamed profiles in the diff, using neighbouring names as context and -following the bundle's established style where the type-specific conventions allow variation. - -For bases (`instantiation: "false"`), use the type-specific conventions: +## Bases | Type | Base names | | --- | --- | -| `machine` | `fdm_machine_common`, `fdm__common`, or an established machine-family base name | -| `process` | `fdm_process_*`, including shared roots and per-layer-height / per-nozzle bases such as `fdm_process_single_0.20` | -| `filament` | `fdm_filament_*` material roots or ` @base` product roots | +| `machine` | `fdm_machine_common`, `fdm__common`, `fdm_klipper_common`, or an established machine-family base | +| `process` | `fdm_process_*`: shared roots and per-layer-height or per-nozzle bases such as `fdm_process_single_0.20` or `fdm_process___nozzle_` | +| `filament` | `fdm_filament_*` material roots, ` @base` product roots | -Shared base names across bundles are intentional, including product roots such as `Fiberon PA6-CF @base`. -Investigate a newly authored base that retains an unrelated selectable preset's name from a copy. +There is no leading-underscore convention. Base names repeat across bundles by design: +every bundle may have its own `fdm_process_common`, and a product root such as `Fiberon PA6-CF @base` +can exist in both the library and a vendor. Investigate a newly authored base that kept an unrelated +selectable preset's name from a copy. -**Name uniqueness is checked by CI.** `check_preset_name_uniqueness` checks type + name within each -bundle. `check_machine_model_name_uniqueness` checks model names across the entire tree, even with -`--vendor`: `Preset::get_printer_type` matches `printer_model` against all vendors' models and returns -the first match, so a duplicate makes lookup depend on vendor order. Both run as part of -`python3 scripts/orca_profile_tool.py check`. +## Uniqueness -## Not the same as the filename +- Type + name is unique within a bundle, indexed or not; `check` enforces it. +- `machine_model` names are unique across the whole tree; `check` enforces it even with `--vendor`. + Printer-type lookup matches `printer_model` against every vendor's models and takes the first, so a + duplicate makes it depend on vendor order. +- At load, two selectable presets with one name discard the bundle, and a duplicate across vendors + is a validator error. Two bases with one name, or a base and a selectable preset, load silently and + the first in the index wins; an unindexed twin is therefore one `sub_path` edit away from becoming + the parent every child resolves to. -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)). +## Filenames and paths + +The loader keys off `name`, and a filename that disagrees usually still loads, but keep the filename +equal to the `name` and to the index `sub_path`. Match the exact case of every `sub_path` and asset +filename: Linux filesystems distinguish case even when a macOS or Windows checkout does not, and +preset-name references are case-sensitive on every platform. Avoid Windows-invalid characters +(`< > : " | ? *`), reserved device names such as `CON` and `NUL` (with any extension), and trailing +spaces or dots in a path component; a space right before `.json` is not a trailing space. + +## Checking names + +Check the `name` of every newly added profile, and every intentional rename, against its type and role +(model, selectable preset or base). `check` does not enforce the shapes on this page: inspect the +added or renamed presets in the diff, use neighbouring names as context, and follow the bundle's +established style where the conventions allow variation. Preserve shipped names during ordinary +tuning; renaming a shipped selectable preset needs `renamed_from`. diff --git a/.claude/skills/orca-profiles/references/process-profiles.md b/.claude/skills/orca-profiles/references/process-profiles.md index 98f31bac1a..785c9ee358 100644 --- a/.claude/skills/orca-profiles/references/process-profiles.md +++ b/.claude/skills/orca-profiles/references/process-profiles.md @@ -1,14 +1,15 @@ # Process profiles -Processes live in `resources/profiles//process/` — selectable leaves and shared bases alike, and +Processes live in `resources/profiles//process/`, selectable leaves and shared bases alike, and every one of them is registered in `process_list`. There are no global processes shared across vendors. ## Naming -`"mm @"` — near-universal, so match it. +`"mm @"` is near-universal, so match it: the quality word before `@`, +the printer label after it ([naming.md](naming.md#process)). -Follow the bundle's existing quality vocabulary. BBL's common ladder relates the quality word to -the layer-height / nozzle ratio; it is a naming convention, not a loader constraint: +Follow the bundle's existing quality vocabulary. BBL's common ladder relates the quality word to the +layer height / nozzle ratio; it is a naming convention, not a loader constraint: | Quality | Ratio | 0.2 nozzle | 0.4 | 0.6 | 0.8 | | --- | --- | --- | --- | --- | --- | @@ -20,49 +21,50 @@ the layer-height / nozzle ratio; it is a naming convention, not a loader constra | Extra Draft | 0.7× | 0.14 | 0.28 | 0.42 | 0.56 | This is the `fdm_process_single__nozzle_` ladder; 0.4 is commonly the unsuffixed nozzle default. -Match neighbouring names rather than renaming shipped tiers to fit the table. +Newer BBL printers add High Quality, Balanced Quality and Strength tiers. Match neighbouring names rather +than renaming shipped tiers to fit the table. On a model with several nozzles, processes for the other +nozzles usually carry the nozzle in the label (`0.30mm Standard @BBL X1C 0.6 nozzle`); follow the bundle. -The `@target` is a human label, not a reference: most do not equal any real printer variant name. +The `@target` is a human label, not a reference: it need not equal any printer variant name. Compatibility comes from the resolved list or condition, not this label. ## Shape -A selectable leaf's only truly universal keys are `type`, `setting_id`, `name` and `instantiation`; -`inherits` and `from` are near-universal — plus compatibility. No slicing key is universal; even -`layer_height` is more often inherited than restated. A base has `type`, `name`, `instantiation`, almost -always `from`, and **no** `setting_id`. +A selectable leaf has `type`, `setting_id`, `name` and `instantiation`, normally `inherits` and +`from`, plus compatibility; its slicing keys, `layer_height` included, normally come from its bases. A +base has `type`, `name`, `instantiation`, `from`, and **no** `setting_id`. -**Target shape: a 7-key leaf.** `OrcaArena` is the cleanest model — +**Target shape: a 7-key leaf.** `OrcaArena` is the cleanest model: `fdm_process_common` → `fdm_process_arena_common` → `fdm_process_arena__nozzle_` → leaf, where the -leaf carries only `type`, `name`, `inherits`, `from`, `setting_id`, `instantiation`, +leaf carries only `type`, `name`, `inherits`, `from`, `setting_id`, `instantiation` and `compatible_printers`, and the per-nozzle base holds the layer height and all eight line widths. +[shared-bases.md](shared-bases.md#levels) says which level each process setting belongs to. -BBL, WonderMaker and Z-Bolt are uniform in *layering* — every leaf inherits a base, names its printers -directly and holds no layer height of its own — but not in key count. Imitate BBL's layering, not its -content: its leaves carry doubled `print_extruder_variant` arrays that no single-variant vendor needs. +BBL's *layering* is a model too (every leaf inherits a base, names its printers directly and holds no +layer height of its own), but not its content: its leaves carry multi-variant `print_extruder_variant` +arrays that no single-variant vendor needs ([extruder-variants.md](extruder-variants.md#process)). -Nearly every vendor ships its own `fdm_process_common` as the inherits-less root. Those files are not -identical; copying another vendor's version into a new bundle is normal. +A bundle has its own `fdm_process_common` as the inherits-less root, since a process inherits only +inside its bundle; starting a new bundle's from another vendor's copy is fine. -Beware leaf-inherits-leaf: Prusa chains several levels deep through sibling leaves, and Elegoo and -Flashforge do it too, so editing one selectable process silently changes others. Check a leaf's children -before editing it. +Beware leaf-inherits-leaf: a bundle may chain selectable processes several levels deep, so editing one +silently changes others. Check a leaf's children before editing it. ## Compatibility -Most leaves set `compatible_printers` directly; some inherit it from a base, and Prusa's fall through to +A leaf sets `compatible_printers` directly, inherits it from a base, or falls through to `compatible_printers_condition`. After resolving `inherits`, **every selectable process has one or the -other** — that is the invariant to review against. Unlike filaments, inheriting `compatible_printers` is +other**: that is the invariant to review against. Unlike filaments, inheriting `compatible_printers` is legitimate for a process, and no check enforces its presence. -- A non-empty `compatible_printers` makes `compatible_printers_condition` **dead code**. Use one or - the other. -- A condition that fails to parse means *compatible with everything* — a warning, not an error. A typo +- A non-empty `compatible_printers` makes `compatible_printers_condition` **dead**. Use one or the + other. +- A condition that fails to parse means *compatible with everything*: a warning, not an error. A typo widens compatibility instead of narrowing it. -- Matching is `boost::regex` **`regex_match`** — a full-string match, which is why every shipped - condition wraps its keyword in `.*`. Because it is boost rather than `std`, `.` also spans the newlines - inside `printer_notes`. -- A `printer_notes` keyword that prefixes another model's keyword matches both. Prusa guards it: +- A regex in a condition must match the **whole** string, so wrap the keyword in `.*`; `.` also spans + the newlines inside `printer_notes`. +- A `printer_notes` keyword that prefixes another model's keyword matches both. Guard it with a + character class after the keyword, and combine terms with `and`: ``` printer_notes=~/.*PRINTER_MODEL_COREONE[^_a-zA-Z0-9].*/ and nozzle_diameter[0]==0.4 and printer_notes=~/.*HF_NOZZLE.*/ @@ -70,76 +72,84 @@ legitimate for a process, and no check enforces its presence. The `[^_a-zA-Z0-9]` exists because `PRINTER_MODEL_COREONE_L` also contains `PRINTER_MODEL_COREONE`. -`compatible_printers` is almost always one element. A leaf listing a whole model family is where a newly -added printer is usually forgotten. +A leaf listing a whole model family is where a newly added printer is usually forgotten. -## What to review per nozzle +## Values to review per nozzle | Key group | Review | | --- | --- | | `line_width` and per-region widths | resolved widths suit the nozzle and layer height | -| `layer_height`, `initial_layer_print_height` | within the printer's limits | +| `layer_height`, `initial_layer_print_height` | within the printer's `min_layer_height` / `max_layer_height` | | print speeds | consistent with flow limits and hardware tuning | -| shell layers, wall loops, accelerations, support Z distances | preserve the intended thickness, motion and support behavior | +| shell layers, wall loops, accelerations, support Z distances | preserve the intended thickness, motion and support behaviour | -**A common starting pattern is nozzle + 0.02 mm**: 0.22 / 0.42 / 0.62 / 0.82 / 1.02. In that pattern, at 0.4, -`inner_wall_line_width`, `sparse_infill_line_width`, `skin_infill_line_width` and +**A common starting pattern is line width = nozzle + 0.02 mm**: 0.22 / 0.42 / 0.62 / 0.82 / 1.02. In +that pattern, at 0.4, `inner_wall_line_width`, `sparse_infill_line_width`, `skin_infill_line_width` and `skeleton_infill_line_width` widen to 0.45 and `initial_layer_line_width` to 0.5; at 0.2, `initial_layer_line_width` widens to 0.25. Also derived, and easily missed: -`ironing_inset = line_width / 2` (0.11 / 0.21 / 0.31 / 0.41). -These are examples, not required values; preserve intentional vendor tuning and percentage/automatic -widths, and validate their resolved values. +`ironing_inset = line_width / 2` (0.11 / 0.21 / 0.31 / 0.41). These are examples, not required values; +preserve intentional vendor tuning and percentage or automatic widths, and validate their resolved +values. -`min_layer_height` and `max_layer_height` are machine keys — no process file sets them. +`min_layer_height` and `max_layer_height` are machine keys; no process file sets them. -## Slice-time content checks +### Slicing limits -`Print::validate()` enforces four rules at slice time: +Slicing rejects a process that breaks one of these (the message in italics): -1. `initial_layer_print_height` ≤ min `nozzle_diameter` -2. `layer_height` ≤ min `nozzle_diameter` — *"Layer height cannot exceed nozzle diameter."* -3. `line_width` and the seven per-region widths (inner/outer wall, sparse infill, internal solid infill, - top surface, skin, skeleton) > `layer_height` — *"Line width too small"*. `support_line_width` only - when the object has support or a raft; `initial_layer_line_width` is never checked. -4. every width ≤ 5 × max `nozzle_diameter` — *"Line width too large"* +1. `initial_layer_print_height` ≤ the smallest `nozzle_diameter` (with a raft, the nozzle of the raft's + first-layer extruder). +2. `layer_height` ≤ the smallest `nozzle_diameter`: *"Layer height cannot exceed nozzle diameter."* +3. `line_width` and the seven per-region widths (inner and outer wall, sparse infill, internal solid + infill, top surface, skin, skeleton) > `layer_height`: *"Line width too small"*. + `support_line_width` is checked only when the object has support or a raft; + `initial_layer_line_width` is never checked. A width that resolves to 0 (automatic) is skipped. +4. Every width ≤ 5 × the largest `nozzle_diameter`: *"Line width too large"*. -Two further rules cover `bridge_line_width` (≤ nozzle diameter; > `layer_height` unless `thick_bridges` -and `thick_internal_bridges` are both on). The sweep starts from printer defaults rather than -enumerating every process. **A new non-default process gets no dedicated slice coverage in CI.** +Two further rules cover `bridge_line_width`: it must not exceed the nozzle diameter, and must exceed +`layer_height` unless `thick_bridges` and `thick_internal_bridges` are both on. The slice sweep starts +from printer defaults rather than enumerating every process: **a new non-default process gets no +dedicated slice coverage in CI.** ## What CI checks on a process Structure, not content: `process_list` name consistency **and** index coverage the other way, two files claiming one process name, the `extruder_clearance_radius` / `extruder_clearance_max_radius` conflict -pair, duplicate JSON keys, a file `normalize` would rewrite, and the five `setting_id` rules (the fifth -rejects the misspelled key `settings_id`). `compatible_printers` presence is checked for **filaments -only**. +pair, duplicate JSON keys, a file `normalize` would rewrite, the five `setting_id` rules (present on +selectable presets, absent from bases, equal to the formula outside `BBL/`, unique across the tree, and +no misspelled key `settings_id`), and the variant arrays: every array of `print_options_with_variant` +exactly `variant length × stride` wide in each selectable process that writes it, and a written +`print_extruder_id` one entry per variant +([variant arrays](validation.md#variant-arrays)). `compatible_printers` presence is checked for +**filaments only**. -Note the C++ loader derives a missing `setting_id` on the fly, so the validator will not fail a process -without one — only `orca_profile_tool.py check` catches it. Running the validator alone gives a false -all-clear. +The loader derives a missing `setting_id` on the fly, so the validator accepts a process without one; +only `orca_profile_tool.py check` catches it. +Running the validator alone gives a false all-clear. ## Silent failures specific to processes -- **Unknown or misspelled keys are discarded with no error and no warning.** They ship all over the - process tree, both plain typos (`inital_layer_height`, `tree_support_bramch_diameter_angle`, - `sparse_infill_patter`) and keys copied from other slicers that Orca never defined. -- Keys on the tool's `OBSOLETE_KEYS` list (`adaptive_layer_height`, `overhang_totally_speed`, …) are - rejected by `check`'s normalization pass across preset types; `normalize` removes them. - The additional per-key obsolete warnings read `filament/` only. -- A dangling `compatible_printers` inside an `instantiation: "false"` base is invisible to - `check_preset_references`: a base never becomes a `Preset` at all (its config goes into `config_maps` - and the loader returns early), so it is in no collection for the check to walk. -- Orphan bases that nothing inherits are scattered through the tree — usually the leftover of a - half-finished nozzle addition. +- **Unknown or misspelled keys are discarded with no error and no warning**, both plain typos + (`inital_layer_height`, `tree_support_bramch_diameter_angle`, `sparse_infill_patter`) and keys + copied from other slicers that Orca never defined. +- Keys on the tool's obsolete list (`adaptive_layer_height`, `overhang_totally_speed`, …) are rejected + by `check`'s normalization pass across preset types; `normalize` removes them. The additional per-key + obsolete warnings read `filament/` only. +- A dangling `compatible_printers` inside an `instantiation: "false"` base is reported only through a + selectable child that inherits it unchanged; it goes unreported when every child overrides the list, + or when the base has no instantiated children. +- Nothing flags an orphan base that nothing inherits, usually the leftover of a half-finished nozzle + addition. ## Adding a quality tier or a nozzle's processes -1. Choose the layer height and quality label using the vendor's existing ladder. -2. If the vendor has per-nozzle bases, add one (`fdm_process___nozzle_`) with the layer +1. Choose the layer height and quality label using the bundle's existing ladder. +2. If the bundle has per-nozzle bases, add one (`fdm_process___nozzle_`) with the layer height, nozzle-appropriate line widths, `initial_layer_print_height` and `ironing_inset`. 3. Add the leaf: 7 keys, `compatible_printers` naming the exact printer variant(s). -4. Register both in `process_list`, parent first. Bump the version, run the id tool, validate. -5. Slice this process explicitly with its intended printer; the sweep gives non-default tiers no - dedicated coverage. If it is a printer's `default_print_profile`, verify the exact name and - resolved compatibility too — the sweep may fall back or select another compatible process. +4. Register both in `process_list`, parent first, bump the version, run the id tool and validate: the + [authoring workflow](../SKILL.md#creating-or-modifying-a-profile). +5. Slice this process explicitly with its intended printer + ([on a copy of the tree](validation.md#checking-a-copy-of-the-tree)); the sweep gives non-default + tiers no dedicated coverage. If it is a printer's `default_print_profile`, verify the exact name and + resolved compatibility too: the sweep may fall back or select another compatible process. diff --git a/.claude/skills/orca-profiles/references/review-checklist.md b/.claude/skills/orca-profiles/references/review-checklist.md index 1d49cf2524..9037e364b4 100644 --- a/.claude/skills/orca-profiles/references/review-checklist.md +++ b/.claude/skills/orca-profiles/references/review-checklist.md @@ -1,37 +1,43 @@ # Reviewing a profile change -Start with delivery, identity and backward compatibility, then check the affected preset types. -The table highlights gaps that need human review. What CI *does* run: -[validation.md](validation.md). +Run `./scripts/check_profile.sh` on the applied diff first ([validation.md](validation.md) says what CI +runs), then work through the items below: delivery, identity and backward compatibility first, then the +affected preset types. The table lists the gaps CI cannot see, so only a reviewer catches them. | Not checked by CI | Consequence | | --- | --- | -| The `version` bump | The change never reaches an upgrading user | -| A misspelled setting key | Setting silently has no effect | +| The `version` bump | The change never reaches an upgrading user; an absent `version` hides the vendor from the setup wizard | +| A misspelled setting key | The setting silently has no effect | | A filename Windows cannot check out, or one that differs from its `sub_path` only in case | Works on the author's machine, breaks the bundle on another platform | -| `bed_model` / `bed_texture` / `hotend_model` pointing at a missing asset | Bed renders as Custom, hotend falls back to the generic model | +| `bed_model` / `bed_texture` / `hotend_model` / cover pointing at a missing asset | A missing bed model renders a generic custom bed and a missing texture renders none, the hotend falls back to the generic model, the cover shows a placeholder | | A nozzle size in a model's list with no matching variant | The size is offered and resolves to nothing | | A non-default process | `validate_slice` gives non-default quality tiers no dedicated coverage | | Whether the intended default survived compatibility selection | The sweep can select a different compatible preset | -| A dangling `compatible_printers` inside an `instantiation: "false"` base | A base never becomes a `Preset`, so the reference check never sees it (a bad `inherits` in a base *is* caught) | +| A dangling `compatible_printers` inside a base whose children all override it (or that has no instantiated children) | The reference check walks resolved selectable presets, so it reports a base's list only through a child that inherits it unchanged (a bad `inherits` in a base *is* caught) | +| A base nothing inherits | Dead weight, usually the leftover of an unfinished nozzle addition | | A `renamed_from` whose old name is still a live preset | The redirect is inert while a live preset carries that name | -| A preset differentiated only by color, or an all-printer library preset without `@System` | Per-color presets split one product across ids and the selector fills with near-duplicates; CI stays green | -| Per-extruder vector length on a multi-nozzle printer | Silently padded (with the **first** value) or truncated | -| A name that ignores its type's convention — a model in a `process` quality slot, or an unrelated target label left in a copied preset | The selector misrepresents the preset's quality or intended printer | +| A preset differentiated only by colour, or an all-printer library preset without `@System` | Per-colour presets split one product across several ids and the selector fills with near-duplicates; CI stays green | +| Plate temperatures for plates the printer has | The user's plate reads an unset or inherited temperature | +| Per-extruder vector length on a multi-extruder printer | Silently padded (with the **first** value) or truncated | +| A new variant appended instead of inserted at its variant index, a variant array widened on a base with a shorter list, or a variant a filament/process lacks | Values shift onto the wrong extruder, are cut before any child inherits them, or resolve to the first variant: High Flow silently gets Standard values | +| A name that ignores its type's convention: a printer model in a `process` quality position, or an unrelated target label or base name left in a copied preset | The selector misrepresents the preset's quality or intended printer | +| Values: temperatures, speeds, widths, pressure advance | A wrong value prints wrong while CI stays green | ## 1. Was the vendor `version` bumped? For **every** bundle whose folder the diff touches, `resources/profiles/.json` must have its -`version` incremented — last component, carrying `.99` into the third component. A library change -means bumping `OrcaFilamentLibrary.json`. +`version` incremented: last component, carrying `.99` into the third component. A library change means +bumping `OrcaFilamentLibrary.json`. -*Why:* nothing in CI checks it, and `PresetUpdater` reinstalls only when `vendor_ver < resource_ver` — -without a bump the change reaches neither an upgrading user nor the author's own running app. +*Why:* nothing in CI checks it, and the app reinstalls a bundled profile set only when its version is +newer than the installed one: without a bump the change reaches neither an upgrading user nor the +author's own running app. Without any `version` the vendor vanishes from the setup wizard, and neither +`check` nor the validator reports it. ## 2. Was the index rebuilt, and does the diff contain only this change? -`check` now fails on an unregistered file, on an index `update-index` would reorder, and on a file -`normalize` would rewrite — so a PR that skipped them arrives red, and you do not have to spot the +`check` fails on an unregistered file, on an index `update-index` would reorder, and on a file +`normalize` would rewrite, so a PR that skipped them arrives red and you do not have to spot the omission yourself. Three things are still yours: - **The index diff belongs to this change.** `update-index` rewrites whole `*_list` sections. If the @@ -41,11 +47,15 @@ omission yourself. Three things are still yours: registration; `validate_custom` detects the break only for names covered by released fixtures. - **`normalize` edits content, not just layout.** It drops `version` and `is_custom_defined` from preset files, removes obsolete keys, deletes six print-speed keys from filament profiles, and resolves - `extruder_clearance_radius` against `extruder_clearance_max_radius` by keeping the larger. - Check that the keys it removed were meant to go. + `extruder_clearance_radius` against `extruder_clearance_max_radius` by keeping the larger + ([what normalize changes](validation.md#normalize-and-update-index-are-part-of-the-check)). Check that + the keys it removed were meant to go. -Obsolete keys fail `check`'s normalization pass and should be removed with `normalize`. -`check` also reports per-key obsolete warnings for filament profiles in the selected vendors. +Index order is dependency order, not alphabetical: parents and include templates before the presets +that use them, then, in name order, the entries that neither depend on nor are depended on by another +entry of their own list (such as a leaf filament whose only parent is in the library), and any entry on +a dependency cycle. Judge a hand-placed entry only by +`update-index --dry-run`: if it reports nothing to rebuild, the position is not a finding. *Why:* the index is the loader's only entry point. Out-of-order entries fail with `can not find inherits` and take the whole vendor bundle down; an unindexed file gets reviewed, merged and never loads. @@ -55,8 +65,8 @@ and take the whole vendor bundle down; an unindexed file gets reviewed, merged a No hand-typed or copied `setting_id` / `filament_id`. Instantiated presets have a `setting_id`; bases do not. `check` enforces all of that; what it cannot tell you is whether the identity *should* have moved. -A rewritten or removed `filament_id` means a product's identity moved — a rename, or an edited -`filament_vendor` / `filament_type` — and the old id is not forwarded anywhere. Confirm that was +A rewritten or removed `filament_id` means a product's identity moved (a renamed alias, or an edited +`filament_vendor` / `filament_type`), and the old id is not forwarded anywhere. Confirm that was intended, and that a new id is not a rename in disguise. *Why:* a duplicate `filament_id` on one printer makes AMS spool matching a coin toss; a copied @@ -64,136 +74,204 @@ intended, and that a new id is not a rename in disguise. ## 4. Does anything disappear for existing users? -A rename, a deletion, or a flip of `"instantiation": "true"` → `"false"` on a shipped preset removes the -name from the preset collection. It needs `renamed_from` on a successor — and only one preset may claim a -given old name. The claimed old name must **not** still be a live preset; the redirect is inert if it is. +A rename, a deletion, or a flip of `"instantiation": "true"` → `"false"` on a shipped selectable preset +removes the name from the preset collection. It needs `renamed_from` on a selectable successor +([renamed_from](vendor-bundle.md#renamed_from)), and only one preset may claim a given old name. The +claimed old name must **not** still be a live preset; the redirect is inert if it is. *Why:* user presets inheriting it die with `can not find parent for config !`; 3MF-embedded presets are dropped with no error at all. Commit `33923464ae` reverted exactly this for Cubicon; -`6943b6ddc3` redid it correctly. CI's `validate_custom` catches the shipped-name case — but not an inert -`renamed_from`. +`6943b6ddc3` redid it correctly with `renamed_from`. CI's `validate_custom` catches the shipped-name +case, but not an inert `renamed_from`. ## 5. Is `compatible_printers` right? -Exact printer **variant** names, non-empty on every instantiated filament outside OrcaFilamentLibrary -and written in the preset's own file — golden rule 6, with the flattened-vs-own-key trap in -[filament-profiles.md](filament-profiles.md#compatible_printers). Watch for a nozzle-specific variant that -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. +Exact printer **variant** names, non-empty on every instantiated filament outside OrcaFilamentLibrary, +and written in the preset's own file ([SKILL.md rule 9](../SKILL.md#rules); the resolved-vs-own-key trap +is in [filament-profiles.md](filament-profiles.md#compatible_printers)). A `machine_model` name instead +of a variant name is the usual mistake: `check` passes it, the validator reports +`references unknown compatible_printers`. Watch for a nozzle-specific tune that 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 +variant to the most specific preset and remove it from the more general ones, which is 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). The Python `check` passes on an overlap; only the full `check_profile.sh` (`validate_system`) -reports `Ambiguous AMS filament match`. +*Why:* real shipped bugs twice (`b7b3418baf` filaments "showing up everywhere", `ff83aa41ef` duplicate +Flashforge 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 +## 6. One product, one all-printer preset; colour is not a preset -- New nozzle size → the model's `nozzle_diameter` list extended, a variant with a matching - `printer_variant`, and at least one process listing that variant. -- `default_print_profile` is one exact name (not a `;` list), and that process's resolved - compatibility list or condition includes this printer. +No presets that differ only by colour: `filament_id` identifies a product, and the colour comes from the +spool at runtime. An all-printer library product is a ` @System` shim with an empty +`compatible_printers` ([colour](filament-profiles.md#colour-is-a-runtime-property)). + +*Why:* per-colour presets pass every check, so this is a review call. + +## 7. Model ↔ variant ↔ process consistency + +- A new nozzle size → the model's `nozzle_diameter` list extended, a variant with a matching + `printer_variant`, and at least one process listing that variant. Every size in the model's list has a + variant (unchecked). +- `default_print_profile` is one exact name (not a `;` list), and that process's resolved compatibility + list or condition includes this printer. - `default_filament_profile` is an array of names that exist. +- Each variant of the model has at least one compatible entry in the model's `default_materials`. -*Why:* an unlisted `printer_variant` is a hard bundle-load failure. Default process selection is -weaker: the sweep attempts the named default, then updates compatibility and rejects generic Default -fallbacks. Another compatible process can conceal a bad reference, so inspect it even after a pass. +*Why:* an unlisted `printer_variant` is a hard bundle-load failure. Default process selection is weaker: +the sweep attempts the named default, then updates compatibility and rejects generic Default fallbacks, +so another compatible process can conceal a bad reference. Inspect it even after a pass. -## 7. Types and spellings +## 8. Types and spellings Every value a string or an array of strings; `filament_type` an array; `instantiation` the string -`"true"`/`"false"` — golden rule 7. Check index metadata and model `nozzle_diameter` especially; -wrong types there can abort loading for **every** vendor. +`"true"` / `"false"`; custom G-code one string, never an array of lines ([SKILL.md rule 5](../SKILL.md#rules)). +Check index metadata and model `nozzle_diameter` especially: wrong types there can abort loading for +**every** vendor. The part only a reviewer can do: check new setting keys against `src/libslic3r/PrintConfig.cpp`. A -misspelled key is silently discarded (rule 8), the single most common way a profile edit does nothing -while CI stays green. +misspelled key is silently discarded ([rule 6](../SKILL.md#rules)), the single most common way a profile +edit does nothing while CI stays green. -## 8. Blast radius of a base edit +## 9. Blast radius of a base edit -A change to `fdm_*_common.json` reaches every child at once. Ask which presets it touches — several -reverts in this repo are exactly this (`41d1b0d3c8`, `dc491166a8`). Also check whether the edited leaf has -children of its own: Prusa, Flashforge and Elegoo all chain leaf-inherits-leaf several levels deep. +A change to `fdm_*_common.json` or any other base reaches every child at once. Ask which presets it +touches: several reverts in this repo are exactly this (`41d1b0d3c8`, `dc491166a8`). Also check whether +the edited leaf has children of its own: a bundle may chain leaf-inherits-leaf several levels deep. A +newly added base that nothing inherits is dead weight, and a dangling +`compatible_printers` inside a base is reported only through a child that inherits it unchanged. A diff +that only moves values between presets and bases must leave every selectable preset loading what it +loaded: ask for the `compare` result ([shared bases](shared-bases.md#nothing-loads-differently)), and +check each new base against the [balance rules](shared-bases.md#balance). -## 9. Do the numbers make sense for the nozzle? +## 10. Do the numbers make sense for the nozzle and material? -Check resolved widths and layer heights against the nozzle, and flow limits / pressure advance -against the actual hardware and material. The patterns in [process-profiles.md](process-profiles.md) -are examples, not mandatory values; [filament-profiles.md](filament-profiles.md) explains what to -revisit for a nozzle change. A cloned preset's unchanged MVS needs particular scrutiny. +Check resolved widths and layer heights against the nozzle, temperatures against the material (PLA +values under an ASA name print wrong), and flow limits / pressure advance against the actual hardware +and material. The patterns in [process-profiles.md](process-profiles.md#values-to-review-per-nozzle) +are examples, not mandatory values; [filament-profiles.md](filament-profiles.md#tuning-per-nozzle-and-per-variant) +explains what to revisit for a nozzle change. A cloned preset's unchanged volumetric speed needs +particular scrutiny. Settings tuned for real hardware cannot be verified by reading the diff. Say so rather than approving numbers nobody measured. -## 10. Asset references (not checked anywhere) +## 11. Plate temperatures + +A filament sets the plate temperature for every plate the printer plausibly has, as its siblings do; +`textured_cool_plate_temp` is the one most often forgotten +([twelve keys](filament-profiles.md#bed-temperature-is-twelve-keys-not-one)). + +## 12. Asset references (not checked anywhere) `bed_model`, `bed_texture`, `hotend_model` and `_cover.png` exist under -`resources/profiles//`. Broken references already ship; nothing checks them. +`resources/profiles//`, in exact case. Nothing checks them. -## 11. `default_materials` (checked by CI) +## 13. `default_materials` and `default_filament_profile` (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. 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: +`check` fails on a `default_materials` / `default_filament_profile` name that matches no filament file, +and `validate_system` on a variant with no compatible system filament in `default_materials`, 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 "" # py -3 on Windows ``` -## 12. Per-extruder vector lengths (not checked) +## 14. Per-extruder vectors (not checked) and variant arrays (widths and layout checked) -One entry per extruder for the plain per-extruder vectors; the `printer_options_with_variant_1` keys are -sized to `printer_extruder_variant` instead. A wrong length is silently padded — repeating the **first** -value, not the last — or truncated. The two sizing families and the worked cases are in +One entry per extruder for the plain per-extruder vectors; the variant sets are sized to the variant +length, `len(printer_extruder_variant)` or one per extruder when the resolved preset has no layout (a +per-extruder difference in those keys still needs the layout, since the loader keeps only the +first value of a list-less printer's arrays). A wrong length is silently padded, repeating the **first** +value, not the last, or truncated. The two sizing families and the worked cases are in [machine-profiles.md](machine-profiles.md#multi-extruder-idex-and-tool-changers). -## 13. Non-default processes get no slice coverage +`check` reports a variant array of any type that is not exactly the `variant length × stride` width +of the selectable preset that writes it, one value included, as an error whatever the values; +`check --strict` also reports one that reaches a selectable preset at another width. A base is not +judged on its own. On a machine it +also reports layout keys that disagree: `printer_extruder_variant` / `printer_extruder_id` not the +flattening of `extruder_variant_list`, a variant without its extruder's `extruder_type` prefix, a +`default_nozzle_volume_type` the extruder does not list, a list of several variants without the pair, a +pair without the list that puts several variants on one extruder. On a machine or a process, an id +array, written or inherited, whose length differs from its variant list is an error; the id and +layout rules judge the composed preset without `--strict`. Two layout findings are warnings: a +pair without the list that `single_extruder_multi_material` off would replace at load, and a process +without `print_extruder_id` whose variants repeat. The full rules are in +[variant arrays](validation.md#variant-arrays). `check_variant_names` separately holds every variant +string, `extruder_type`, `nozzle_volume_type` and `default_nozzle_volume_type` to the engine's enums +in every bundle, BBL included, failing on a dead variant, a legacy spelling and a variant list that +names one variant twice ([variant names](validation.md#variant-names)). + +On a multi-variant printer, still check by hand: + +- that a new variant's values sit at its variant index (machine limits as a (normal, silent) pair at + `2 × index`) in every file of the chain that restates the key, `include` templates included; +- that each process lists every (extruder id, variant) pair its printers can select; +- that no array was widened on a base with a shorter variant list: the loader cuts it before the + children inherit it ([composition](extruder-variants.md#padding-truncation-and-composition)), and + `check`, even `--strict`, composes without that cut, so it passes; +- that only keys in [the four sets](extruder-variants.md#the-four-key-sets) carry per-variant values; +- that the High Flow variants carry measured values rather than copies + ([checking and testing](extruder-variants.md#checking-and-testing)). + +## 15. Non-default processes get no slice coverage `validate_slice` starts from printer defaults; it does not enumerate every process. Slice a new or -changed non-default tier explicitly with its intended printer. - -## 14. Housekeeping worth a nit, not a block - -`"from"` other than `"system"` (the preset-bundle loader ignores it, though the CLI's config-file loader -rejects anything but `system`/`user`/`User`), `printer_settings_id` copied from another -vendor, and a filename that disagrees with the preset's `name` (common; the loader keys off `name`). - -## 15. Cross-platform filenames and paths (not checked) - -Check for Windows-invalid characters, reserved device names, trailing path-component spaces/dots, -and case mismatches in `sub_path` or asset paths. See [cross-platform paths](validation.md#cross-platform-paths). +changed non-default tier explicitly with its intended printer +([on a copy of the tree](validation.md#checking-a-copy-of-the-tree)). ## 16. Do the preset names follow the conventions? -Check **every newly added profile and intentional name change**, including models and bases, -against [the naming conventions](naming.md#checking-names). Preserve shipped names during -ordinary tuning; renaming a shipped selectable preset requires the migration in item 4. +Check **every newly added profile and intentional name change**, including models and bases, against +[the naming conventions](naming.md#checking-names): no printer model in a process quality position, no +target label or base name left over from a copied preset, the bundle's established style. Preserve +shipped names during ordinary tuning; renaming a shipped selectable preset requires the migration in +item 4. -*Why:* CI checks name uniqueness, but does not enforce the naming conventions. Catch naming -mistakes before the names ship and existing projects depend on them. +*Why:* CI checks name uniqueness, but does not enforce the naming conventions. Catch naming mistakes +before the names ship and existing projects depend on them. + +## 17. Cross-platform filenames and paths (not checked) + +Check for Windows-invalid characters, reserved device names, trailing path-component spaces or dots, +and case mismatches between `sub_path` or asset references and the files on disk. See +[filenames and paths](naming.md#filenames-and-paths). + +## 18. Housekeeping worth a nit, not a block + +`"from"` other than `"system"` (the bundle loader ignores it, though loading the file as a CLI config +rejects anything but `system` / `user` / `User`), `printer_settings_id` copied from another vendor, +redundant overrides that restate the parent's value, siblings that each repeat a value their base could +hold ([shared bases](shared-bases.md)), and a filename that disagrees with the preset's +`name` (the loader keys off `name`). --- ## Reporting the review -A finding is: **one defect**, its file, what breaks at runtime or in CI, and the fix. Split independent -defects into separate findings even when they live in one file — five id problems in one bullet get one -fix and four survivors. +A finding is **one defect**: its file (or quoted lines), what breaks at runtime or in CI, and the fix. +Split independent defects into separate findings even when they live in one file: five id problems in +one bullet get one fix and four survivors. Say which findings `check` or the validator reports and which +only a reader catches: a missing version bump, a misspelled key and wrong temperatures pass CI, so a +contributor who only reruns the tools fixes what CI flags and resubmits the rest. Severity discriminates only if it is earned: | Severity | Means | | --- | --- | | blocker | the bundle fails to load, or a preset is unreachable at runtime | -| major | CI fails, or existing users lose a preset | -| minor | wrong-but-working: dead keys, `from`, naming, redundant overrides | +| major | CI fails, existing users lose a preset, or a value prints wrong while CI stays green (PLA temperatures under an ASA name; a misspelled key whose intended value differs from the inherited one) | +| minor | wrong but working: redundant or dead keys that change nothing, `from`, naming | -Compute every number and id (`orca_profile_tool.py`, a scripted count) or omit it — one invented count -makes a reader stop trusting the right ones. Report a command's result only if you ran it. +Compute every number and id (`orca_profile_tool.py`, a scripted count) or omit it: one invented count +makes a reader stop trusting the right ones. Report a command's result only if you ran it. End with a +verdict: can it merge as it stands? diff --git a/.claude/skills/orca-profiles/references/shared-bases.md b/.claude/skills/orca-profiles/references/shared-bases.md new file mode 100644 index 0000000000..500cd34006 --- /dev/null +++ b/.claude/skills/orca-profiles/references/shared-bases.md @@ -0,0 +1,254 @@ +# Shared bases + +Use this when drafting several presets at once, after `fix-variant`, or when sibling presets repeat the +same values. Each value is written once, on the base of the group it is true for, and a selectable +preset holds its identity and what makes it different. The work has two halves: choosing the groups, +which is judgment, and moving the values, which must leave every preset loading exactly what it loaded +before. + +## When + +- **Drafting** a printer family, a quality ladder or a product line: place each setting at its + [level](#levels) before writing any preset, then write the presets as overrides + ([Rule 7](../SKILL.md#rules)). +- **After `fix-variant`.** It resizes each array in the selectable preset that writes it and never + moves or deletes a value ([variant arrays](validation.md#variant-arrays)). A family whose presets all + wrote one value now repeats the widened array in every preset, and a preset that restated what it + inherits now restates it wider. +- **Converting full copies**: a machine that inherits nothing, or a filament that restates fifty-plus + keys, is the style to move away from ([filament style](filament-profiles.md#style)). + +Out of scope: + +- **BBL.** Its profiles are synced from BambuStudio: a restructure is overwritten by the next sync and + makes every later sync diff unreadable. Fix BBL values in the file that holds them. +- **OrcaFilamentLibrary bases for one vendor's values.** A library base reaches every bundle's + filaments. Put a vendor's shared values on a base in its own bundle (a product `@base`, or a vendor + base that inherits the library's), and change a library base only for a value true of every filament + below it in every bundle. +- **Families the change does not touch.** Restructure the presets you are already changing; a + bundle-wide pass is a change of its own. Commit a restructure without any value change, so `compare` + alone verifies it. + +## Nothing loads differently + +A restructure changes where values are written, never what a selectable preset loads. Presets keep +their `name` and `setting_id`, and user presets and projects refer to a system preset by name and store +their own changes against what it loads, so an unchanged load changes nothing for users. Prove it with +the bundled helper, from the repository root (every subcommand takes `--profiles ` to work on a +copy of the tree): + +```bash +python3 .claude/skills/orca-profiles/scripts/shared_settings.py snapshot # before any edit +python3 .claude/skills/orca-profiles/scripts/shared_settings.py compare # after: "0 difference(s)", exit 0 +``` + +`snapshot` records every selectable preset of every bundle as the loader stores it: the parent's stored +config, each `include` at the width its file wrote, the preset's own keys, then every variant array +resized to the preset's own variant list ([composition](vendor-bundle.md#inherits-and-include)). It +models the step `check` does not see: a base is stored after its own resize, so an array wider than a +base's list reaches its children cut. It also leaves out what the loader reads from each file and never +hands down (`name`, `type`, `from`, `instantiation`, `inherits`, `include`, `setting_id`, +`renamed_from`, `description`, `version`, `url`, `is_custom_defined`), so those keys never move to a +base. Nor does it record `print_settings_id`, `printer_settings_id` or `filament_settings_id`: the app +replaces them with the selected presets' names before slicing, so a file's value never counts. Delete +them from the presets you restructure rather than moving them to a base. + +It does not know the built-in defaults, so `compare` lists a key written on one side only (no file of +the preset's chain writes it on the other) apart from the differences, and exits 1 for either. A +difference is a value the edit changed: undo it, or make it a separate, deliberate change. A one-sided +key is no change only when its written value is the option's default in `PrintConfig.cpp`: confirm +each, as when a preset that loaded the default by leaving a key out must now write it +([Balance 5](#balance)). A value equal to the default needs writing nowhere when no base above writes +another: delete it from the presets rather than moving it, and confirm the one-sided keys. + +## Levels + +A base stands for a level of the vendor's catalogue, and a setting lives at the level that determines +it. The test for a shared value: if it had to change for one preset of the group, should it change for +all of them? If yes, it is the group's and goes on the group's base. A value that is only equal today +(two unrelated printers with the same acceleration) stays in each preset: a base built on coincidence +is later edited for one preset and silently changes the others. For a default with exceptions +([Balance 5](#balance)), ask the question of the presets that inherit the default. + +The tables give each setting's usual level; the test decides for a given bundle: where each toolhead +(Bowden or Direct Drive) has its own default filament, `default_filament_profile` follows the +toolhead, not the nozzle. Levels run +coarse to fine, and a chain need not visit every level: each preset or base inherits the next coarser +level that has a base. + +| Machine level | Base | Settings it determines | +| --- | --- | --- | +| Vendor | `fdm_machine_common`, `fdm__common` | the vendor's defaults for every printer | +| Firmware | `fdm_klipper_common`, `fdm_marlin_common` | `gcode_flavor`, G-code that calls the firmware's macros (layer change, pause, filament change), `host_type`, `print_host`, the thumbnail format | +| Hardware family: models that share a frame, motion system, toolhead or extruder layout | `fdm___common` (`fdm_qidi_x3_common`, `fdm_machine_eryone_ER20_common`) | the `machine_max_*` limits, `extruder_clearance_*`, the toolhead's retraction where every nozzle shares it, `z_hop` and wipe, fitted hardware such as `auxiliary_fan`, the extruder count and per-extruder vectors, the variant layout ([Printer rule 2](extruder-variants.md#printer-machine)) | +| Model: one `machine_model`, which for an IDEX printer includes its mode | the default-nozzle preset where the bundle hangs its other nozzle presets off it; otherwise `fdm___common` | `printable_area`, `printable_height`, `bed_exclude_area`, the model's start G-code, a COPY or MIRROR mode's settings | +| Nozzle: the selectable preset | none | `printer_model` and `printer_variant`, which name the preset's model and nozzle and stay in every preset as the tree writes them; `nozzle_diameter`, `min_layer_height`, `max_layer_height`, `default_print_profile`, `default_filament_profile`, retraction the vendor tunes per nozzle | + +A family may split once more, into toolhead or revision groups that exist only within it: +`fdm___common` → `fdm___mk1_common`. A split that crosses another axis is not a +level: when every controller comes with every toolhead, a toolhead base under each controller base +repeats the same values in each ([Balance 6](#balance)). + +| Process level | Base | Settings it determines | +| --- | --- | --- | +| Vendor | `fdm_process_common`, `fdm_process__common` | strategy: seam, wall order, infill and support patterns | +| Printer family or variant layout | `fdm_process___common` (`fdm_process_arena_common`, BBL's `fdm_process_dual_common`) | speeds, accelerations and jerk of that motion system; the variant layout ([Process rule 4](extruder-variants.md#process)) | +| Layer height × nozzle | `fdm_process___nozzle_` (BBL's `fdm_process_single_0.20`) | `layer_height`, line widths, shell layers, speeds scaled to the layer | +| Quality × printer: the selectable preset | none | `compatible_printers`, and what is unique to that combination | + +| Filament level | Base | Settings it determines | +| --- | --- | --- | +| Material | `fdm_filament_` in OrcaFilamentLibrary, shared by every bundle | material defaults | +| Product | ` @base` | `filament_id` (minted here, [ids](ids.md)), `filament_vendor`, `filament_type`, density, cost, the product's temperatures and cooling | +| Printer or nozzle tune: the selectable preset | none | `compatible_printers` (always in its own file, [Rule 9](../SKILL.md#rules)), volumetric speed, flow ratio, pressure advance and retraction measured on that printer | + +**Equal where they must differ is a copy.** A key that follows a finer level, such as the layer-height +limits and line widths that follow the nozzle diameter or `printable_area` that follows the bed, never +moves above that level. When presets that differ in it carry the same value, the value was copied: leave +it in the presets and report it (the [worked example](#worked-example-an-idex-family) has one). + +## Balance + +1. **One group, one base; use the existing one first.** A base is the home of the presets below it, + whatever its name. In a bundle whose presets are all one family, the vendor base is the family base, + so the family's values go there. In a bundle that hangs the other nozzles off the default-nozzle preset, that preset is the model's home. + Never create a base whose presets are exactly its parent's. Where two existing bases already serve + the same presets (a copied `fdm_machine_common` above the vendor's own base), the finer one is the + home, and merging the pair is a change of its own. Moving a key into an existing home adds no file. + A base value that no preset below it loads is dead: replace it with the group's value when there is + one; otherwise leave it and report it, since a future preset would inherit it. +2. **A new base must stand for a level and pay for itself.** Its file costs five metadata keys and an + index entry, so create it only when it takes `k` keys off `n` selectable presets with + `(n − 1) × k > 6`, where a custom G-code value counts as one key per G-code line: what it removes + must outnumber what it adds. A model with two nozzles that share three short keys keeps them in both. +3. **No ad-hoc bases:** never a base for presets that merely agree (the ones with 0.8 mm retraction), + and never a base with one preset below it. +4. **Keep every selectable preset within four ancestors**, selectable parents included. When a level would push a preset past that, fold it into the level above or leave + its keys in the presets. +5. **A default with exceptions.** A value that only some presets below a shared base load moves to that + base, whichever axis it follows, when two conditions hold. More presets load it than any other value + (on a tie the key stays in the presets), and `w − a > 1`, where `w` presets drop their copy and `a` + presets that take the key from the base and load another value, the built-in default included, must + now write theirs. Presets that write another value keep it and are unaffected. The base then holds + the group's default, and the exceptions stay visible in their own files. +6. **One chain; the other axes stay in the presets.** `inherits` follows one axis. When presets vary + along several (bed size × controller × toolhead), first fill the existing homes by + rules 1 and 5. Then give new bases to the axis whose bases pay most: sum rule 2's count over its + bases, less the keys a re-parented preset must now write because it no longer inherits them from its + old parent; on a tie, follow the layering the bundle already has. Leave the other axes' keys in the + presets, and never repeat one axis's bases under each group of another. Outside BBL, whose synced + presets need theirs, add no `include` template for a second axis: the loader reads `include` only + since #15869 (2026-09-25), and an app that predates it ignores the key, so the template's settings + never reach the preset. + +Name a new base after its level ([base names](naming.md#bases)). The name must be unique in its bundle +and must not equal a selectable preset's: two such presets load silently and the first in the index wins +([uniqueness](naming.md#uniqueness)). + +## Restated values + +`candidates` lists every key a file writes that it would load unchanged without writing it. Delete it +when the value is what the presets below the base that supplies it share: more of them load it, +written or inherited, than any other value. A family that restates machine limits, clearances and +G-code every other printer of the bundle loads from `fdm_klipper_common` drops its copies. When most +presets below that base load another value, the match is a coincidence: keep the key, and move it to +the level of the presets that share it. Keys of the nozzle level stay in the preset in +either case. + +After a restructure the report still lists keys that are right where they are: the nozzle-level keys +each preset keeps, and arrays a list-less multi-extruder base writes at its presets' width for +`check --strict`. + +## Variant arrays on a base + +- The loader stores a base with its variant arrays resized to the base's own variant list, one variant + when it writes none, so an array on a narrower base reaches its presets as its first value, padded. + Move a variant array to a base only when the base declares the presets' variant list (and, for a + machine or process, their ids), moving the layout keys with it as + [Printer rule 2](extruder-variants.md#printer-machine) and [Process rule 4](extruder-variants.md#process) + ask; or when the presets load its first value anyway: every value is equal, or the presets are + list-less machines, which the loader cuts to one variant. `compare` catches a cut. +- Write the array on the base at the width of the presets it serves, their `N` + ([sizing equation](extruder-variants.md#sizing-equation)), so `check --strict` judges the right width + where it reaches them. When the presets below a base need different widths (single- and + dual-extruder models on one base), leave the array in the presets, or on bases that each serve one + width. +- On a list-less multi-extruder family base, declare the extruder count: `nozzle_diameter` and the other + per-extruder vectors at one entry per extruder. The base then has its presets' width, and + `fix-variant --strict` writes an array that reaches the presets at another width into the base once, + instead of into every preset. +- Deleting a restated variant array leaves the preset on the inherited array. Plain `check` accepts + that; `check --strict` reports it when the inherited width differs, which is why a bundle held to + `--strict` restates the array at each preset's width. + +## Procedure + +1. **Snapshot** the tree before any edit, `fix-variant` included. After `fix-variant`, run `compare`: a + difference is a value its padding changed (it repeats the last value, the loader the first). Set that + value deliberately, then snapshot again as the baseline for the restructure. +2. **List the candidates:** + + ```bash + python3 .claude/skills/orca-profiles/scripts/shared_settings.py candidates --vendor "" --type machine + python3 .claude/skills/orca-profiles/scripts/shared_settings.py candidates --vendor "" --type machine --group-by printer_model + ``` + + It prints the [restated values](#restated-values), then, per base, the keys every selectable preset + below it loads with one value and how many of those presets write it themselves, and under + `default with exceptions` the values that pass [Balance 5](#balance), with `w` and `a`. With + `--group-by ` it groups the selectable presets by that key's value instead and names each + group's nearest common base, where a new base would go: `printer_model` for models, `gcode_flavor` + for firmware, `extruder_type` or `default_filament_profile` for toolheads, `filament_id` for + filament products, `layer_height` for processes. The report is evidence, not a plan: it cannot tell + a shared value from a coincidence or a copy. +3. **Decide each key** by [Levels](#levels), [Balance](#balance) and + [Restated values](#restated-values): delete the restatements of shared values, move group values up + to the group's home, and create only the bases that pay. +4. **Edit.** Each new base gets `"type"`, `"name"`, `"from": "system"`, `"instantiation": "false"`, no + `setting_id`, and `inherits` set to the presets' old parent. Point the presets' `inherits` at it and + delete the moved keys from them. Bump the version, then run `normalize`, `update-index` (it orders + parents first) and `generate-id --dry-run`, which must write nothing: bases take no id and presets + keep theirs. +5. **In a bundle held to `--strict`, run `fix-variant --strict` now**, so it writes into the new bases. +6. **Verify.** `compare` prints `0 difference(s)`, and every one-sided key it lists is a default. + `check` reports no error it did not report before, and neither does `check --strict` where the bundle + passes it. Then run the [authoring checks](../SKILL.md#creating-or-modifying-a-profile). +7. **Report** each base added (name, level, presets below it, keys it holds), the keys left in presets + and why, the copies found, and the `compare` result. + +## Worked example: an IDEX family + +A Klipper bundle's IDEX family has 36 selectable machines (bed size 300, 400 or 500 × normal, COPY or +MIRROR mode × 0.4, 0.5, 0.6 or 0.8 nozzle) that all inherit `fdm_klipper_common` directly and write 49 +keys each. `fix-variant` has widened their retraction arrays to two values and their machine limits +to four. + +- **Restated.** All 36 restate 10 values that every other printer of the bundle loads from + `fdm_klipper_common`: three machine limits, the three clearances, wipe, `retract_before_wipe`, and the + layer-change and pause G-code. Delete them. +- **Family.** All 36 load one value for 24 more keys: the other machine limits, `extruder_offset`, + retraction, `z_hop`, `single_extruder_multi_material`, `manual_filament_change`, the remaining G-code + except the start G-code, and thumbnails. A new family base, `fdm___idex_common`, + holds them, plus `nozzle_diameter` `["0.4", "0.4"]` for the extruder count: at least + `(36 − 1) × 24 = 840`. +- **Model.** Each `printer_model` (a bed size in one mode) has four nozzle presets that share + `printable_area`, `printable_height` and a three-line `machine_start_gcode`: `(4 − 1) × 5 = 15`, so + one base per model, nine in all. The family does not hang its other nozzles off a default-nozzle + preset, so the model level here is a base. +- **A coincidence.** The twelve 500 presets' `printable_height` 500 equals `fdm_klipper_common`'s, but + every preset of the bundle writes its own height and 300 is the most common. The 500 is the base's + leftover, not a shared value, so it stays on the model bases. +- **A copy.** In COPY and MIRROR mode, every nozzle of a model carries the 0.4 nozzle's + `min_layer_height`, `max_layer_height` and `retract_lift_below`: 0.06, 0.3 and 0.2 on the 0.8 nozzle, + where normal mode has 0.12, 0.5 and 0.3. `candidates --group-by printer_model` lists the first and + last as shared by the model, and `max_layer_height` as restated from `fdm_klipper_common`, whose value + is also 0.3. They follow the nozzle, so they stay in the presets and are reported for tuning. +- **Nozzle.** Each preset keeps `printer_model`, `printer_variant`, `nozzle_diameter`, + `min_layer_height`, `max_layer_height` and `retract_lift_below` beside its metadata. +- **Result.** 36 full presets become 36 short ones on 10 new bases. `compare` reports 0 differences, + `check --vendor ""` passes as before, and `generate-id --dry-run` writes nothing. + `check --strict` reports more errors than before, because the deleted variant arrays now reach the + presets at `fdm_klipper_common`'s one value. `fix-variant --strict` writes those arrays into the + family base alone, after which `check --strict` passes for the family and `compare` still reports 0 + differences. diff --git a/.claude/skills/orca-profiles/references/validation.md b/.claude/skills/orca-profiles/references/validation.md index c23b555f49..b5c647f839 100644 --- a/.claude/skills/orca-profiles/references/validation.md +++ b/.claude/skills/orca-profiles/references/validation.md @@ -1,8 +1,8 @@ # Validating profiles ```bash -./scripts/check_profile.sh # everything CI runs -./scripts/check_profile.sh --vendor "" # fast loop +./scripts/check_profile.sh # everything CI runs +./scripts/check_profile.sh --vendor "" # development loop ./scripts/check_profile.sh profile_tool validate_slice # named checks only ``` @@ -12,153 +12,316 @@ scripts\check_profile.bat -Vendor "" scripts\check_profile.bat profile_tool validate_slice ``` -`check_profile.bat` is a shim around `check_profile.ps1` — same checks, same order, same logs; -the flags take PowerShell spellings (`-Vendor`, `-ProfilesDir`, `-Validator`, `-Download`, `-Refresh`, -`-WorkDir`, `-LogLevel`) and positional check names are unchanged. `-p`, `-v` and `-l` are aliases, so -`-v Elegoo -l 2` reads the same on both platforms. It passes `-ExecutionPolicy Bypass` because a +`check_profile.bat` is a shim around `check_profile.ps1`: same checks, same order, same logs. Its flags +take PowerShell spellings (`-Vendor`, `-ProfilesDir`, `-Validator`, `-Download`, `-Refresh`, +`-WorkDir`, `-LogLevel`), and positional check names are unchanged. `-p`, `-v` and `-l` are aliases, +so `-v Elegoo -l 2` reads the same on both platforms. It passes `-ExecutionPolicy Bypass` because a default Windows client refuses to run a checked-out `.ps1` at all. The `.ps1` finds Python itself, probing `py -3`, then `python`, then `python3`; run the tool by hand with `py -3` for the same reason. -Every check in the run happens even after an earlier one fails; the script exits non-zero if any did, and writes -`logs/.log` plus, on failure, `pr_comment.md` under a per-user cache dir — the same report CI posts on the PR. -That dir is `~/Library/Caches/orca-profile-check` on macOS, `${XDG_CACHE_HOME:-~/.cache}/orca-profile-check` on Linux -and `%LOCALAPPDATA%\orca-profile-check` on Windows; it is named apart from OrcaSlicer's own per-user dirs and sits -outside the checkout, so every worktree shares one copy. `--work-dir` / `-WorkDir` overrides it. A stale `.lock` -there after a crash must be removed by hand. +Every check runs even after an earlier one fails; the script exits non-zero if any failed, and writes +`logs/.log` plus, on failure, `pr_comment.md` (the same report CI posts on the PR) under a +per-user cache dir: + +| Platform | Cache dir | +| --- | --- | +| macOS | `~/Library/Caches/orca-profile-check` | +| Linux | `${XDG_CACHE_HOME:-~/.cache}/orca-profile-check` | +| Windows | `%LOCALAPPDATA%\orca-profile-check` | + +It is named apart from OrcaSlicer's own per-user dirs and sits outside the checkout, so every worktree +shares one copy and each run overwrites its `logs/`. `--work-dir` / `-WorkDir` overrides it. + +When other worktrees or agents may run checks too, pass `--work-dir ` from the start +and capture the console output yourself: the shared `logs/` can belong to another run by the time you +read them. With `--work-dir`, also pass `--validator` pointing at the cached nightly, so the new dir +does not download it again: + +| Platform | Cached validator | +| --- | --- | +| Linux | `/validator/OrcaSlicer_profile_validator` | +| macOS | `/validator/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator` | +| Windows | `\validator\OrcaSlicer_profile_validator.exe` | + +Copying the cached `profile-fixtures/` into the new dir reuses the fixture archives; the fixture +`manifest.json` is still downloaded on every run, so `validate_custom` needs the network either way. +`another run is using ` means a live run holds `/.lock`: leave it and use your own +`--work-dir`. Only a `.lock` with no `check_profile` process alive is a crash leftover; delete it by +hand. ## The five checks | Check | Command it runs | Catches | | --- | --- | --- | -| `profile_tool` | `python3 scripts/orca_profile_tool.py check` | index coverage **both ways**, preset-name collisions, files `normalize`/`update-index` would still rewrite, duplicate JSON keys, filament `compatible_printers`, `filament_type` array, conflict keys, id length, **all `setting_id` and `filament_id` rules** | -| `validate_system` | `validator -p resources/profiles -l 2` | load errors, missing filament `compatible_printers`, dangling `inherits`/`compatible_*`, duplicate `filament_id` per printer | -| `validate_slice` | `validator -p … -s -l 2` | custom G-code expansion, unresolvable printer defaults | -| `validate_filament_subtypes` | `validator -p … -l 2 -f` | nothing extra — see below | -| `validate_custom` | `validator -p -l 2` | a shipped preset name that a past release offered no longer resolving | +| `profile_tool` | `python3 scripts/orca_profile_tool.py check` | index coverage **both ways**, preset-name collisions, files `normalize` / `update-index` would still rewrite, duplicate JSON keys, filament `compatible_printers`, `filament_type` array, conflict keys, variant strings and array widths and layout keys, dangling `default_materials`, id length, **all `setting_id` and `filament_id` rules** ([below](#orca_profile_toolpy-check)) | +| `validate_system` | `validator -p resources/profiles -l 2` | load errors, missing filament `compatible_printers`, dangling `inherits` / `compatible_*`, duplicate `filament_id` per printer (`Ambiguous AMS filament match`), printer defaults that name no compatible system filament | +| `validate_slice` | `validator -p … -s -l 2` | custom G-code expansion and unresolvable printer defaults, by slicing | +| `validate_filament_subtypes` | `validator -p … -l 2 -f` | nothing extra; see below | +| `validate_custom` | `validator -p -l 2` | a shipped preset name that a past release offered no longer resolving | -**`-f` is a no-op.** It is declared `po::bool_switch()->default_value(true)`, so the duplicate-`filament_id` -check runs whether or not you pass it — `validate_system` already fails on duplicates. The binary's own -`--help` ("Off unless this flag is present") does not reflect that default. +**`-f` is a no-op.** It defaults to on, so the duplicate-`filament_id` check runs whether or not you +pass it, and `validate_system` already fails on duplicates. The binary's own `--help` ("Off unless this +flag is present") does not reflect that default. -### `validate_custom` — the backward-compatibility gate +**A `--vendor` run reads differently from CI.** The validator's `-v` loads that vendor plus +OrcaFilamentLibrary and nothing else, so every library tune whose `compatible_printers` names another +vendor's printers fails `validate_system`, `validate_filament_subtypes` and each `validate_custom` +fixture with thousands of `references unknown compatible_printers "Bambu Lab …"` lines. Under +`--vendor`, `profile_tool` and `validate_slice` are the meaningful results; for the other three, filter +the log for your vendor's files and treat only those lines as findings. The unscoped run is the CI +result; run it before the PR. -Downloads one fixture archive per past release (v1.9.0 onwards) of *generated mock* user presets — -a `__orca_test` copy of every system preset that -release shipped, cut with the validator's own `-g 1` mode — unpacks each over a copy of the current tree -and loads it. Each entry holds only `inherits` plus a canned diff, so the one failure it adds over -`validate_system` is a shipped preset name disappearing. (The whole current tree sits under each fixture, -so every `validate_system` error fails it too.) This is what makes a rename or an -`instantiation` flip a CI failure rather than just a user complaint, and the reason `renamed_from` is -mandatory. +### `validate_custom`: the backward-compatibility gate + +It downloads one fixture archive per past release (v1.9.0 onwards) of *generated mock* user presets: a +`__orca_test` copy of every system preset that release shipped, cut with the +validator's own `-g 1` mode. It unpacks each over a copy of the current tree and loads it. Each entry +holds only `inherits` plus a canned diff, so the one failure it adds over `validate_system` is a shipped +preset name disappearing. This is what makes a rename, a deletion or an `instantiation` flip a CI +failure rather than just a user complaint, and the reason `renamed_from` is mandatory. + +The whole current tree sits under each fixture, so every `validate_system` error fails +`validate_custom` too: fix `validate_system` first. Under `--vendor` it copies only the top-level index +files, `/` and `OrcaFilamentLibrary/`, and picks fixtures by the index's display `name` +(`Bambulab` for `BBL`), not the file stem; fixture presets without that prefix are covered only by an +unscoped run, and it warns `validate_custom checked nothing` when none match. ### `validate_slice` -Slices a two-colour cube on every instantiable printer in the tree, sequentially, forcing the prime tower. -It selects `default_print_profile` and the first `default_filament_profile`, then updates compatibility; -that update can select a different compatible preset. Confirm the intended defaults yourself rather -than treating a passing sweep as proof that those exact presets were sliced. -A printer fails if it cannot be selected, falls back to a Default preset, throws, produces no g-code, or -emits no `CP TOOLCHANGE START`. It cannot be scoped to a filament-only vendor -(`No instantiable printer presets found for vendor OrcaFilamentLibrary`); `check_profile.sh` records it -as SKIP for a vendor with no `machine/` folder. +It slices a two-colour cube on every instantiable printer in the tree, sequentially, forcing the prime +tower. It selects `default_print_profile` and the first `default_filament_profile`, then updates +compatibility; that update can select a different compatible preset. Confirm the intended defaults +yourself rather than treating a passing sweep as proof that those exact presets were sliced. + +A printer fails if it cannot be selected, falls back to a Default preset, throws, produces no G-code, +or emits no `CP TOOLCHANGE START` (`change_filament_gcode` never expanded). Non-default processes and +filaments get no dedicated coverage; [slice them on a copy](#checking-a-copy-of-the-tree). In the +default set, a bundle without a `machine/` folder is recorded as SKIP; naming `validate_slice` +explicitly for it fails (`No instantiable printer presets found for vendor OrcaFilamentLibrary`). The +validator logs `[error]` lines that do not fail a check (such as `could not found extruder_type`); only +each check's PASS or FAIL counts. ## `orca_profile_tool.py check` -`check` is one subcommand of the tool that also owns -`generate-id`, `normalize`, `trim` and `update-index`; see [ids.md](ids.md) for the writing half. +`check` is one subcommand of the tool that also owns `fix-variant`, `generate-id`, `normalize`, +`trim` and `update-index`; [ids.md](ids.md#the-tool) has the writing half. -| Per vendor | Catches | -| --- | --- | -| `check_preset_name_uniqueness` | two files in one bundle claiming one type + name — indexed or not | -| `check_index_coverage` | a file on disk that no `*_list` references (**an error, not a warning**) | -| `check_name_consistency` | an index entry whose `name` disagrees with the file, or whose `sub_path` is missing | -| `check_normalized` | a file `normalize` would rewrite, and an index `update-index` would rebuild | -| `check_filament_compatible_printers` | an instantiated non-library filament with no `compatible_printers` of its own | -| `check_conflict_keys` | `extruder_clearance_radius` alongside `extruder_clearance_max_radius` | -| `check_vector_type_keys` | a vector option written as a scalar (`"filament_type": "PLA"`) | -| `check_filament_id_length` | a declared `filament_id` longer than 8 characters | -| `check_machine_default_materials` | every `default_materials` / `default_filament_profile` name resolves | -| `check_obsolete_keys` | per-key warnings for ignored options; **filament files only** | +| Catches | Scope | Function in the tool | +| --- | --- | --- | +| two files in one bundle claiming one type + name, indexed or not | per vendor | `check_preset_name_uniqueness` | +| a file on disk that no `*_list` references (**an error, not a warning**) | per vendor | `check_index_coverage` | +| an index entry whose `name` disagrees with the file, or whose `sub_path` is missing | per vendor | `check_name_consistency` | +| a file `normalize` would rewrite, an index `update-index` would rebuild | per vendor | `check_normalized` | +| duplicate JSON keys in a file | every file read | the JSON loader | +| an instantiated non-library filament with no non-empty `compatible_printers` of its own | per vendor | `check_filament_compatible_printers` | +| `extruder_clearance_radius` alongside `extruder_clearance_max_radius` | per vendor | `check_conflict_keys` | +| a scalar `filament_type` (`"filament_type": "PLA"`); the five other filament vectors `normalize` arrayifies surface as `normalize would convert to an array` | per vendor | `check_vector_type_keys`, `check_normalized` | +| a variant string the two enums cannot build (a dead variant, a legacy spelling included), a variant list naming one variant twice, an `extruder_type`, `nozzle_volume_type` or `default_nozzle_volume_type` that is not an enum name ([variant names](#variant-names)) | per vendor | `check_variant_names` | +| a variant array not exactly `variant length × stride` wide in a selectable preset that writes it (with `--strict`, also in one it reaches); machine variant layout keys that disagree; a process id array that does not pair each variant ([variant arrays](#variant-arrays)) | per vendor | `check_variant_arrays` | +| a declared `filament_id` longer than 8 characters | per vendor | `check_filament_id_length` | +| a `default_materials` name, or a `default_filament_profile` name, matching no filament file ([below](#default-material-references)) | per vendor | `check_machine_default_materials` | +| per-key warnings for ignored options, **filament files only** | per vendor | `check_obsolete_keys` | +| `setting_id` uniqueness, every `filament_id` rule, and `machine_model` names duplicated across bundles | **tree-wide, ignoring `--vendor` entirely** | `check_setting_id_uniqueness`, `check_filament_ids`, `check_machine_model_name_uniqueness` | -Tree-wide, **ignoring `--vendor` entirely**: `check_setting_id_uniqueness` and `check_filament_ids`. So a -vendor-scoped run can and does fail on another vendor's files — and it saves seconds, not minutes. +Because the id and model-name checks stay tree-wide, a vendor-scoped run can and does fail on another +vendor's files, and it saves seconds, not minutes. Unscoped, the per-vendor pass covers every bundle. The only exclusion is the stray `user/` directory -(see below); `OrcaFilamentLibrary` is held to the same rules as any vendor, its sole exemption being -that a library filament may leave `compatible_printers` empty — exactly what -`check_filament_compatible_printers` allows. `check_normalized` covers every bundle with an index. +(below); OrcaFilamentLibrary is held to the same rules as any vendor, its sole exemption being that a +library filament may leave `compatible_printers` empty. `check_normalized` covers every bundle with an +index. Notes that matter: -- Exit codes: **0** clean, **1** errors found, **2** argparse misuse. Warnings never change the exit code. -- A nonexistent `--vendor` is a hard error — `[ERROR] unknown vendor "" in `, exit 1. -- `--vendor ""` means all vendors; `check_profile.sh` relies on that. `--vendor` is repeatable. -- A **stray directory** under `resources/profiles/` still gets counted as a vendor by the per-vendor pass - and warned about (`No profiles found for vendor: at …/.json`, and the "Checked vendors" count - goes up by one). The one exception is `user/`, the validator's data dir, which an unscoped `check` - skips by name; `--vendor user` still checks and warns about it. Warnings never change the exit code. - `normalize`, `trim` and `update-index` ignore strays too — they define a bundle as *a directory with a +- Exit codes: **0** clean, **1** errors found, **2** argparse misuse. Warnings never change the exit + code. +- A nonexistent `--vendor` is a hard error: `[ERROR] unknown vendor "" in `, exit 1. +- `--vendor ""` means all vendors; `check_profile.sh` relies on that. `--vendor` is repeatable + (`check --vendor A --vendor OrcaFilamentLibrary`); `check_profile.sh` takes one. +- A **stray directory** under `resources/profiles/` still gets counted as a vendor by the per-vendor + pass and warned about (`No profiles found for vendor: at …/.json`, and the "Checked + vendors" count goes up by one): usually an emptied folder, or a `user/` left by a direct validator + run. An unscoped `check` skips `user/` by name; `--vendor user` still checks and warns about it. + `normalize`, `trim` and `update-index` ignore strays too: they define a bundle as *a directory with a matching index file*. - Each remedy is printed once for the whole run, not once per file, as a `[WARNING]` under the errors - ("2 unreferenced file(s) above: delete them, or run … update-index"). Read those lines: they name the + (`2 unreferenced file(s) above: delete them, or run … update-index`). Read those lines: they name the command that fixes the batch. -- The trailing summary always suggests `normalize`. That is right for the shape errors and misleading for - everything else — an id error needs `generate-id`, a dangling `default_materials` needs a human. +- When there are errors or warnings, the trailing summary suggests `normalize`. That is right for the + shape errors and misleading for everything else: an id error needs `generate-id`, a dangling + `default_materials` needs a human. +- Other options: `--dry-run` on every writing command, `--profiles DIR` to point any command at another + tree, `--profile-type` to narrow `normalize`, `trim` and `update-index` to one type + ([ids.md](ids.md#the-tool)). - `resources/profiles/check_unused_setting_id.py` is a legacy BBL-only diagnostic, not part of profile CI. Use `orca_profile_tool.py check` for current id validation. -### Obsolete-key diagnostics +### Obsolete keys -`check` always reports per-key warnings for obsolete options in filament profiles. -The normalization check also rejects obsolete keys across preset types; `normalize` removes them. +`check` always reports per-key warnings for obsolete options in filament profiles. Its normalization +check also rejects obsolete keys across all preset types (`normalize would remove `); `normalize` +removes them. ### Default-material references -The materials check finds `default_materials` / `default_filament_profile` entries naming a preset -that does not exist. The three authoring errors it surfaces are `,` instead of `;`, wrong case -(`@system`), and a whole `;`-joined string stuffed into one array element. +The materials check finds `default_materials` / `default_filament_profile` entries naming a preset that +does not exist. It reads each `machine/` file's own key (a model's `default_materials`, a variant's +`default_filament_profile`; a file that writes both is checked on `default_materials` only) and accepts +any `name` found in the vendor's or OrcaFilamentLibrary's `filament/` files, bases and unindexed files +included. The three authoring errors it surfaces are `,` instead of `;`, wrong case (`@system`), and a +whole `;`-joined string stuffed into one array element. Only the validator (`validate_system`) requires +an instantiated system filament that is compatible with each variant. + +### Variant arrays + +`check_variant_arrays` composes every selectable preset the loader's way (the parent, then each +`include` in order, then the file's own keys; a filament's `inherits` may fall through to +OrcaFilamentLibrary) and holds each key of [the four variant sets](extruder-variants.md#the-four-key-sets) +that the preset writes itself to exactly its `variant length × stride` +([widths](extruder-variants.md#widths)). The variant length is the length of the composed preset's +own `*_extruder_variant` list; without one, a machine's is the number of variants its +`extruder_variant_list` offers, else its extruder count (the list's default is one +`Direct Drive Standard` per extruder), and a process's or filament's is 1. Any other width is an +error, one value included and even when every value is the same. A key the preset does not write +takes what reaches it, the default or an array it inherits or includes, which the loader resizes; it +is not checked. A base is not judged on its own: what it writes counts only where it reaches a preset +that does not override it. + +`check --strict` also holds every selectable preset to its own width for each key that reaches it, +so a preset whose variants differ from those of the file its array comes from restates the array +(the error names that file). That is BBL's practice and the target for new printer-specific presets; +CI runs `check` without `--strict`. + +An id array that reaches a selectable preset, `printer_extruder_id` or `print_extruder_id`, written or +inherited, must have one entry per entry of its variant list on any printer. This rule and the +machine layout rules below judge the composed preset without `--strict`, whichever file writes the +keys. Beside a written variant list this rule reports it instead of the width +rule, so it is reported once. A process that +lists variants without `print_extruder_id` gets a **warning** when a variant repeats (every entry then +reads as extruder 1, so the repeated variant is unreachable), nothing otherwise. + +On a machine the layout keys are held to [Printer rules 1–4](extruder-variants.md#printer-machine), +every failure an error unless marked: + +- With `extruder_variant_list` written: the list has one entry per extruder, as many as + `nozzle_diameter`; every variant starts with its extruder's `extruder_type`; + `default_nozzle_volume_type` names a nozzle volume type that extruder lists; + `printer_extruder_variant` is the list flattened extruder-major and `printer_extruder_id` gives each + entry its 1-based extruder (an id array left out reads as extruder 1 everywhere, which passes when + those are the flattening's ids). Without the pair, the list may offer one variant in total. +- With the pair written and no `extruder_variant_list`: one variant per extruder at most. A pair that + `single_extruder_multi_material` off would replace with the default at load is a **warning**; a pair + the rebuild would leave as it is passes. + +It does **not** see a base's own resize: it composes at the width each file wrote, so an array wider +than a base's list, which the loader cuts before any child inherits it, passes even with `--strict` +([composition](extruder-variants.md#padding-truncation-and-composition)). Nor does it see per-extruder +vectors outside the sets (`extruder_offset`, `printer_extruder_options`, …), which no variant list +sizes. What a variant holds (a High Flow variant copied from Standard, a variant inserted at the wrong +index) is review work +([item 14](review-checklist.md#14-per-extruder-vectors-not-checked-and-variant-arrays-widths-and-layout-checked)); +whether it is a name the engine can select at all is `check_variant_names`'. + +`python3 scripts/orca_profile_tool.py fix-variant` resizes every array the width rule rejects in the +selectable preset that writes it, leaves bases alone and adds no key: extra values are dropped, missing ones +repeat the last value (the last normal/silent pair at stride 2; a lone value fills normal and silent +alike). It leaves the variant lists and id arrays to you, since they address the variants rather than +fill them. `fix-variant --strict` then also writes each key that reaches a selectable preset at +another width: into the most general file on the way down to the preset whose own width is the +preset's and whose selectable presets taking it all need that width, else into the preset itself. +Presets of every bundle count towards that agreement; `--vendor` limits the files written and +`--dry-run` previews. The loader pads with the first value where `fix-variant` repeats the last, so a +padded array need not load as before, and +trimming deletes values: when the extra values were meant as per-extruder or per-variant values, +declare the variant layout instead ([Printer rule 2](extruder-variants.md#printer-machine)) and keep +them. `fix-variant` moves no value, so a family whose presets all wrote one value repeats the widened +array in each; put it on the family's base afterwards ([shared bases](shared-bases.md)). + +### Variant names + +`check_variant_names` reads the four list keys plus `extruder_type`, `nozzle_volume_type` and +`default_nozzle_volume_type` of every preset the bundle's index references, bases included, and holds +each entry to the names the engine's two enum maps define (`s_keys_map_ExtruderType`, +`s_keys_map_NozzleVolumeType`, read from `PrintConfig.cpp` on every run). The bundle's own files are +judged, not the composed config: a bad string is the writing file's error, once. Every finding is an +error, and no bundle is exempt: BBL, whose bundle is imported from BambuStudio, is held to OrcaSlicer's +enums like any other. + +- A variant string outside ` ` is a **dead variant**: it still + counts toward the variant length the arrays are sized by, so the values written for it silently never + reach the G-code. `Hybrid` too, which is runtime-only, and an empty entry. A name BambuStudio's enum + has and OrcaSlicer's lacks is dead here as well, and passes with no tool change once the engine gains + that nozzle volume type. +- A legacy name the loader still rewrites in these keys (`Normal` → `Standard`, `Big Traffic` → + `High Flow`) is an error that names the enum name to write; the profile has to spell the enum + name. `DirectDrive` is only rewritten in `extruder_type`, so a variant string carrying it is dead. +- A variant list naming one variant twice is an error: the lookup returns the first equal string, so + the repeat is unreachable and its value sits at an index no extruder reads. A filament list takes + strings, `extruder_variant_list` takes them per extruder, and a process takes `(extruder id, variant)` + pairs — one string on two extruders is two pairs, not a repeat. +- An `extruder_type`, `nozzle_volume_type` or `default_nozzle_volume_type` value that is not an enum + name is an error: they are enum options, so an unknown value fails the validator's load of the + whole bundle, while the app silently loads the option's default instead. A legacy spelling + (`DirectDrive`, `Normal`, `Big Traffic`) and `Hybrid`, an enum value no profile writes, are errors + too. + +The variant *order*, the choice of variants, and the values themselves are not checked. ### `normalize` and `update-index` are part of the check -`check` fails when either command would still change something, so they are not optional polish — the +`check` fails when either command would still change something, so they are not optional polish: the file that gets reviewed has to be the file that ships. What `normalize` changes is narrow and fixed: -adds a missing `type`, deletes a `version` or `is_custom_defined` key from a *preset* file, deletes six -print-speed keys from filament profiles (`initial_layer_print_speed`, `outer_wall_speed`, -`inner_wall_speed`, `infill_speed`, `top_surface_speed`, `travel_speed`), deletes the -obsolete keys in `PrintConfigDef::handle_legacy`'s `ignore` set across preset types, resolves the -`extruder_clearance_*` conflict pair by keeping the larger, arrayifies five filament options besides -`filament_type`, and hoists `type`, `name`, `renamed_from`, `inherits`, `from`, `setting_id`, -`filament_id`, `instantiation` to the front. A file it changes is then rewritten whole — tab-indented, -LF, one trailing newline, keys reordered. + +- adds a missing `type`; +- deletes a `version` or `is_custom_defined` key from a *preset* file; +- deletes six print-speed keys from filament profiles (`initial_layer_print_speed`, `outer_wall_speed`, + `inner_wall_speed`, `infill_speed`, `top_surface_speed`, `travel_speed`); +- deletes the obsolete keys the loader ignores (the `ignore` set in `PrintConfigDef::handle_legacy`), + across preset types; +- resolves the `extruder_clearance_*` conflict pair by keeping the larger; +- arrayifies six filament options (`filament_type`, `filament_cost`, `filament_density`, + `temperature_vitrification`, `filament_max_volumetric_speed`, `filament_vendor`); +- hoists `type`, `name`, `renamed_from`, `inherits`, `from`, `setting_id`, `filament_id`, + `instantiation` to the front. + +A file it changes is then rewritten whole: tab-indented, LF, one trailing newline, keys reordered. A +file committed with CRLF line endings therefore changes on every line; read the diff before committing +it. **Set `type` explicitly when authoring.** For a file in `machine/` without it, normalization guesses -`machine` only if its name contains `nozzle`, otherwise `machine_model`. That heuristic cannot -reliably classify shared machine bases or unusually named variants. +`machine` only if its name contains `nozzle` (case-insensitive), otherwise `machine_model`. That +heuristic cannot reliably classify shared machine bases or unusually named variants. -The Python obsolete-key set is checked against the C++ source by a unit test. Active options -and legacy aliases that the loader migrates (such as `extruder_type` and -`extruder_clearance_max_radius`) are preserved. +The tool's obsolete-key set is checked against the loader's ignore list by a unit test. Active options +are preserved, including live keys whose *values* the loader rewrites (`extruder_type`: `DirectDrive` → +`Direct Drive`; the variant-string keys: `Normal` / `Big Traffic` → `Standard` / `High Flow`), and so are +legacy key names the loader migrates (such as `extruder_clearance_max_radius`). Two things it therefore does **not** enforce: - **Formatting and key order on their own.** A file with none of those problems is skipped entirely, so 4-space indent, a missing trailing newline, and a file that leads with `compatible_printers` all pass - `check`. They stay latent until something else trips `normalize` and the whole file reformats inside an - unrelated diff. (`normalize --force` rewrites every file, which is not something to run on a shipped - bundle.) + `check`. They stay latent until something else trips `normalize` and the whole file reformats inside + an unrelated diff. (`normalize --force` rewrites every file; do not run it on a shipped bundle.) - **A misspelled setting key.** `inital_layer_height` and `sparse_infill_densiti` pass `check` cleanly. - Verify new keys against `PrintConfig.cpp` and `PrintConfigDef::handle_legacy`. + Verify new keys against `src/libslic3r/PrintConfig.cpp` and the loader's legacy handling + (`PrintConfigDef::handle_legacy`: renamed keys, rewritten values and ignored keys). + +`check` does not catch a dangling `default_print_profile` either; check that name by hand. ## The validator binary -Built from `src/dev-utils/OrcaSlicer_profile_validator.cpp` (`-DORCA_TOOLS=ON`). -Both scripts find a local build under `build*/` — `check_profile.sh` tries Release, RelWithDebInfo, then -Debug, and `check_profile.ps1` adds MinSizeRel — else they download the nightly into the -`validator` subdirectory of the per-user cache dir (see above). Pass `--download` / `-Download` to -match CI exactly, since a stale local build is used silently. Windows looks for +Built from `src/dev-utils/OrcaSlicer_profile_validator.cpp` with `-DORCA_TOOLS=ON`. Both scripts use a +local build under `build*/` when one exists, else they download the nightly into the `validator` +subdirectory of the cache dir. `check_profile.sh` searches Release, then RelWithDebInfo, then Debug +(each under `build*/src/` and `build*/*/src/`), then single-config `build*/src`, and +prefers a host-architecture build tree; `check_profile.ps1` tries Release, RelWithDebInfo, MinSizeRel, +then Debug. A stale local build is used silently; `--download` / `-Download` skips local builds and uses the +nightly. The download and the fixtures stay cached until `--refresh` / `-Refresh`, so +`--download --refresh` (`-Download -Refresh`) matches CI exactly. Windows looks for `OrcaSlicer_profile_validator.exe`. -If your build lives somewhere else entirely, point at it with `--validator` / `-Validator`, or set +If your build lives somewhere else, point at it with `--validator` / `-Validator`, or set `ORCA_PROFILE_VALIDATOR` (`$env:ORCA_PROFILE_VALIDATOR` in PowerShell). | Flag | Meaning | @@ -167,11 +330,12 @@ If your build lives somewhere else entirely, point at it with `--validator` / `- | `-l ` | log level; CI uses 2 | | `-v ` | load only that vendor **plus** OrcaFilamentLibrary | | `-s` | slice sweep | +| `-o ` | with `-s`, save each printer's G-code there | | `-f` | no-op (see above) | | `-g 1` | regenerate user-preset fixtures; takes a value, and wipes the user preset dir first | -On ARM64 Linux the nightly is x86-64 only — the script warns and downloads anyway, producing a binary -that will not run. Build it locally instead. +On ARM64 Linux the nightly is x86-64 only: the script warns and downloads anyway, producing a binary +that will not run. Build it locally with `-DORCA_TOOLS=ON` and pass `--validator`. Running the validator directly uses the profile tree as its data directory and can create `user/` there. Prefer the wrappers, which stash existing user presets and restore them afterward. After a @@ -185,16 +349,27 @@ Use `--profiles DIR` on the Python tool and `-p DIR` on the validator. The wrapp ```bash ./scripts/check_profile.sh --profiles "" +# Windows: scripts\check_profile.bat -ProfilesDir "" ``` -On Windows use `scripts\check_profile.bat -ProfilesDir ""`. +To slice a process or filament that is not a printer's default, or to read the G-code, work on a copy: +copy `resources/profiles` and `resources/info` into one scratch dir (the validator reads `info/` next to +the tree), point the printer's `default_print_profile` or first `default_filament_profile` at the preset +in the copy, and run the validator with `-o`: + +```bash + -p /profiles -v "" -s -o +``` + +Each printer's G-code is saved as `__.gcode`; its embedded config +(`; print_settings_id = …`, `; filament_settings_id = …`) shows what was actually sliced. ## Testing in the app -Editing this checkout's `resources/profiles` does not update a separately installed application. -Test with a build using the edited resources and a bumped bundle version; the updater installs newer -bundles under `/system/`, and the preset cache also depends on the bundle version. -Use Help ▸ Show Configuration Folder to locate the active data directory: +Editing this checkout's `resources/profiles` does not update a separately installed application. Test +with a build using the edited resources and a bumped bundle version: the updater installs newer bundles +under `/system/`, and the preset cache also depends on the bundle version. Use Help ▸ Show +Configuration Folder to locate the active data directory: | Platform | Default data directory | | --- | --- | @@ -202,58 +377,71 @@ Use Help ▸ Show Configuration Folder to locate the active data directory: | Linux | `$XDG_CONFIG_HOME/OrcaSlicer`, or `~/.config/OrcaSlicer` when unset | | Windows | `%APPDATA%\OrcaSlicer` | -A portable `data_dir` next to the executable takes precedence. Use a separate test configuration -for a clean-install check; preserve the normal configuration and user presets. - -## Cross-platform paths - -Match the exact case of each `sub_path` and asset filename; Linux filesystems commonly distinguish -case even when a macOS or Windows checkout does not. Preset-name references are case-sensitive -on every platform. Avoid Windows-invalid characters (`< > : " | ? *`), reserved device names -such as `CON` / `NUL` (including with extensions), and trailing spaces or dots in path components. -Keep stems tidy too, but a space immediately before `.json` is not a trailing path-component space. +A portable `data_dir` next to the executable takes precedence. Use a separate test configuration for a +clean-install check; preserve the normal configuration and user presets. ## Error → remedy | Message | Fix | | --- | --- | -| `can not find inherits for ` | parent missing, unregistered, or listed **after** the child | -| `can not find filament_id for ` | nothing in the chain declares one — run `generate-id` | -| `can not find parent for config !` | a shipped name disappeared — add `renamed_from` | -| `Missing instantiation attribute for ` | key absent **or** not the string `"true"`/`"false"` | +| `can not find inherits for ` | parent missing, unregistered, misspelled, or listed **after** the child | +| `can not find include` | the template is misspelled, registered after the includer, or selectable | +| `can not find filament_id for ` | nothing in the chain declares one: run `generate-id` | +| `can not find parent for config !` | a shipped name disappeared: add `renamed_from` | +| `Failed loading configuration file ` | that file could not be loaded and the whole bundle was discarded: a JSON error, or a value its option cannot take, such as `nil` in a non-nullable key (`Invalid value provided for parameter : nil`, `Deserializing nil into a non-nullable object`); the lines above it name the cause | +| `Missing instantiation attribute for ` | key absent **or** not the string `"true"` / `"false"` | | `contains incorrect keys: , which were removed` | a key valid for a different preset type | -| `defines invalid printer variant ""` | not in the model's `nozzle_diameter` list | -| `has printer_variant "" that does not match its nozzle_diameter` | the set comparison in [machine-profiles.md](machine-profiles.md) | -| `references unknown compatible_printers "

"` | the printer was renamed or deleted; fix the reference | +| `defines invalid printer variant ""` | not a token of the model's `nozzle_diameter` list | +| `has printer_variant "" that does not match its nozzle_diameter` | [the set comparison](machine-profiles.md#printer_model-and-printer_variant) | +| `references unknown compatible_printers "

"` | the printer was renamed or deleted, or a `machine_model` name was used instead of a variant name: fix the reference. Under `--vendor`, usually another vendor's printer ([why](#the-five-checks)) | | `references renamed compatible_printers "" (now "")` | in-tree references must name the current preset; `renamed_from` does not excuse them | -| `Filament preset "" 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 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 | +| `Filament preset "" is missing compatible_printers setting` | non-library filaments need a non-empty list in their **own** file; the resolved-vs-own-key trap is in [filament-profiles.md](filament-profiles.md#compatible_printers) | +| `Ambiguous AMS filament match: N filament presets share filament_id "X" and are all compatible with 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 product's `@base`. `orca_profile_tool.py check` does not catch this; only `validate_system` does | +| `Layer height cannot exceed nozzle diameter.` / `Line width too small` / `Line width too large` | the [slicing limits](process-profiles.md#values-to-review-per-nozzle) | | `[ERROR] … no .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` | +| `[ERROR] … no .json list references it and it declares no profile type` | set the correct `type` explicitly, then `normalize` and `update-index` | | `[ERROR] … normalize would ` / `.json: update-index would rebuild ` | run that command and commit the result | | `[ERROR] has N profiles named ""` | identify the intended preset and remove or rename the duplicate; use `trim --dry-run` only for deliberate unindexed-file cleanup | -| `[ERROR] … must not have a setting_id` / `is missing a setting_id` | `generate-id --setting-id` | -| `inherits filament_id "X" but its own triple … mints "Y"` | `generate-id` will **not** fix this — see [ids.md](ids.md) | -| `vendor 's config version: invalid` | the `version` string is not Semver-parseable | -| `[json.exception.type_error.302] type must be string` | locate the non-string value in the index or model; see [failure scopes](vendor-bundle.md#failure-modes-ranked-by-blast-radius) | -| `Printer "

" fell back to a default preset` | final process or filament selection is a generic Default preset; check named defaults, visibility and available compatible presets. An incompatible default may instead be replaced without this error | -| `Printer "

" sliced but the filament change never fired` | `change_filament_gcode` never expanded | +| `Duplicate key error in : Duplicate key detected: ` | a key written twice in one file; keep the intended one | +| `… must not have a setting_id` / `… is missing a setting_id` / `setting_id "X" in does not match the expected "Y" …` | `generate-id --setting-id` (by hand in `BBL/`, see [ids.md](ids.md#bbls-exception-precisely)) | +| `filament_id "X" declared by … does not match the mint of its triple …` | `generate-id --filament-id`; if the id should not be declared here at all, remove it so the preset inherits its root's | +| `inherits filament_id "X" but its own triple "V/T/N" mints "Y"` | `generate-id` will **not** fix this; see [ids.md](ids.md#what-generate-id-does-and-does-not-fix) | +| `"" has N values for variant length S at stride k, which takes M` (with ` (no , so …)` after `S`, naming where `S` came from, when the preset writes no list, and ` (it comes from )` at the end under `--strict` for an array the preset does not write) | exactly `S × k` values in variant order, or leave the key out ([widths](extruder-variants.md#widths)); on a list-less multi-extruder printer whose extruders differ, declare the layout; `fix-variant` cuts or pads to that width ([variant arrays](#variant-arrays)); an `S` you did not expect means the variant list did not resolve through `include` or `inherits` | +| `printer_extruder_variant […] is not extruder_variant_list flattened extruder-major […]` / `printer_extruder_id […] does not give each entry of printer_extruder_variant its 1-based extruder […]` / `printer_extruder_id has N entries for the M entries of printer_extruder_variant` | write the pair as the flattening of the list, ids in step ([Printer rule 2](extruder-variants.md#printer-machine)) | +| `extruder_variant_list has N entries for M extruder(s)` / `extruder_variant_list entry i "…" holds a variant that does not start with extruder i's extruder_type` / `default_nozzle_volume_type "…" is not a nozzle volume type extruder i lists` | [Printer rules 1, 3 and 4](extruder-variants.md#printer-machine) | +| `extruder_variant_list offers N variants but the preset writes no printer_extruder_variant/printer_extruder_id` / `printer_extruder_variant lists several variants for extruder N but the preset writes no extruder_variant_list` / `[WARNING] … with single_extruder_multi_material off the loader replaces printer_extruder_variant …` | write all three layout keys ([Printer rule 2](extruder-variants.md#printer-machine)) | +| `print_extruder_id has N entries for the M entries of print_extruder_variant` / `[WARNING] … print_extruder_variant repeats a variant but print_extruder_id is absent` | one id per variant entry, mirroring the printer's pairs ([Process rule 1](extruder-variants.md#process)) | +| ` holds "…", which no extruder can select: "…" is not a nozzle volume type the enum has (…)` / `… it does not start with an extruder type the enum has (…)` / `… is empty` / `… Hybrid names the sub-nozzles of one hybrid extruder at runtime` | write a legal variant string, ` ` from the two enums ([variant names](#variant-names), [variant strings](extruder-variants.md#variant-strings)); in every bundle, BBL included | +| `… holds the legacy variant "…"` / `extruder_type spells the legacy name "…"` / `nozzle_volume_type spells the legacy name "…"` / `default_nozzle_volume_type spells the legacy name "…"` | write the enum name the message gives: the loader still rewrites the legacy one, but `check` rejects it | +| ` lists "…" N times` / `print_extruder_variant lists the pair (extruder N, "…") N times` | drop the repeat and its value from every variant array: the lookup returns the first equal string | +| `extruder_type "…" is not one of (…)` / `nozzle_volume_type "…" is not one of (…)` / `default_nozzle_volume_type "…" is not one of (…)` / `… names "Hybrid", which the engine computes for a hybrid extruder at runtime` | they are enum options, so an unknown value fails the validator's load of the whole bundle and silently becomes the default in the app; use `s_keys_map_ExtruderType` / `s_keys_map_NozzleVolumeType`, `Hybrid` excepted ([variant strings](extruder-variants.md#variant-strings)) | +| `[WARNING] No profiles found for vendor:

` | a directory with no matching index (an emptied folder, or a `user/` left by a direct validator run); remove it | +| `… has no compatible system filament in its model's "default_materials"` | add a system filament preset compatible with that variant to the model's `default_materials` | +| `… names the unknown system filament "" in its "default_materials"` / `… "default_filament_profile"` | name an existing system (not user, not base) filament exactly; `;` separators, exact case | +| `Missing filament profile: '' referenced in ` | the same, caught by `check`; usual causes are `,` instead of `;`, wrong case (`@system`), or a `;`-joined list packed into one array element | +| `machine_model name "" is declared by N bundles` | model names are unique across the tree; rename the new model | +| `vendor 's config version: invalid` | the `version` string does not parse; write `MM.mm.pp.bb` | +| `[json.exception.type_error.302] type must be string` | locate the non-string value in the index or a model; see [failure scopes](vendor-bundle.md#failure-scopes) | +| `Printer "

" fell back to a default preset` | the final process or filament selection is a generic Default preset: check the named defaults, their visibility and that compatible presets exist. An incompatible default may instead be replaced without this error | +| `Printer "

" sliced but the filament change never fired (no CP TOOLCHANGE START)` | `change_filament_gcode` never expanded | ## CI -`.github/workflows/check_profiles.yml`, job **"Check profiles"**, on `pull_request` into `main` or -`release/*`, paths `resources/profiles/**`, `resources/printers/**`, `scripts/**` and the workflow itself. -There is no push trigger — a direct push to main runs no profile validation. +`.github/workflows/check_profiles.yml`, job **"Check profiles"**, runs on `pull_request` into `main` or +`release/*` touching `resources/profiles/**`, `resources/printers/**`, `scripts/**`, +`src/libslic3r/PrintConfig.cpp` (where the tool reads the variant key sets) or the workflow itself. +There is no push trigger: a direct push to main runs no profile validation. -The job opens with `python3 -m unittest discover -s scripts/tests -t scripts`, the tool's own unit -tests. That step is deliberately **not** `continue-on-error`: a broken tool makes everything it then says -about the profiles worthless. Every check after it is `continue-on-error` with a final gate, so one run -reports all five results. On failure a second workflow posts or replaces a single PR comment marked -``, with each failing log truncated to 30 KB; it deletes the comment -once the run is green. +The job opens with `python3 -m unittest discover -s scripts/tests -t scripts`, the tool's own unit tests +(run them locally after changing `scripts/`, with `py -3` on Windows, and keep `-t scripts` or the +imports fail). That step is deliberately **not** `continue-on-error`: a broken tool makes everything it +then says about the profiles worthless. Every check after it is `continue-on-error` with a final gate, +so one run reports all five results. On failure a second workflow posts or replaces a single PR comment +marked ``, holding the start of each failing log (30 KB per check, +12 KB per `validate_custom` fixture; reproduce locally for the full list); it deletes the comment once +the run is green. The job name is also the required check for the delegated-merge bot, which lets a vendor maintainer -self-merge a `resources/profiles//` PR with no human review — so whatever CI does not check -is what ships unreviewed. Its denied patterns refuse `^scripts/` and any `.py`, so a PR that touches the -tooling always needs a maintainer. +self-merge a PR limited to their own `resources/profiles//` folder with no human review, so +whatever CI does not check is what ships unreviewed. Its denied patterns refuse `^scripts/` and any +`.py`, so a PR that touches the tooling always needs a maintainer. diff --git a/.claude/skills/orca-profiles/references/vendor-bundle.md b/.claude/skills/orca-profiles/references/vendor-bundle.md index 29aac13331..d6c7710469 100644 --- a/.claude/skills/orca-profiles/references/vendor-bundle.md +++ b/.claude/skills/orca-profiles/references/vendor-bundle.md @@ -1,7 +1,7 @@ -# The vendor bundle and the loader +# Vendor bundles -A bundle is `resources/profiles/.json` (the index) plus `resources/profiles//`. -The **vendor id is the filename stem**, not the `name` inside — several differ (`BBL.json` is named +A bundle is `resources/profiles/.json` (the index) plus `resources/profiles//`. The +**vendor id is the filename stem**, not the `name` inside; the two may differ (`BBL.json` is named "Bambulab"). Asset paths and the `setting_id` formula use the id; the `validate_custom` fixture prefix uses the `name`. @@ -13,16 +13,16 @@ uses the `name`. "version": "02.04.00.03", "force_update": "0", "description": "Phrozen configurations", - "machine_model_list": [ { "name": "...", "sub_path": "machine/....json" } ], - "machine_list": [ ... ], - "process_list": [ ... ], - "filament_list": [ ... ] + "machine_model_list": [ { "name": "Phrozen Arco", "sub_path": "machine/Phrozen Arco.json" } ], + "machine_list": [ … ], + "process_list": [ … ], + "filament_list": [ … ] } ``` -The loader reads `name`, `version`, `url` and the four `*_list` arrays. -`description` is only logged. `force_update` is read by `PresetUpdater`, never by the loader. -`sub_path` is relative to the **vendor folder**. +The loader reads `name`, `version`, `url` and the four `*_list` arrays. `description` is only logged; +`force_update` is read by the profile updater, never by the loader. `sub_path` is relative to the +**vendor folder**. | List | Holds | | --- | --- | @@ -35,141 +35,180 @@ The loader reads `name`, `version`, `url` and the four `*_list` arrays. 1. **Everything is registered, bases included.** Every preset file on disk has exactly one entry in the matching list, and no unindexed preset file is left in the tree. -2. **Parents before children.** `inherits` resolves against a per-kind map filled as the list is walked - (`configs.clear()` then process, filaments, printers). A parent listed after its child produces - `can not find inherits for ` and the bundle is discarded. -3. **The index entry's `name` must equal the `name` inside the sub_path file.** `check_name_consistency` - walks the index looking for the files; `check_index_coverage` walks the files looking for them in the - index. The `renamed_from` escape hatch `check_name_consistency`'s docstring promises is commented out. +2. **Parents before children, includes before includers.** The lists load processes first, then + filaments, then printers, each in index order, and `inherits` and `include` resolve only against + presets of that type already loaded from it. A parent + listed after its child produces `can not find inherits for ` and the bundle is + discarded; an include listed after its includer is `can not find include`, a counted error that + leaves the includer without those keys. +3. **The index entry's `name` equals the `name` inside the `sub_path` file.** `renamed_from` does not + excuse a mismatch. -All three are `check` errors now, and `update-index` writes an index that satisfies all three from the -files on disk — including the parents-first ordering, by topological sort. Hand-editing the index is +All three are `check` errors, and `update-index` writes an index that satisfies all three from the +files on disk, including the dependency ordering (parents and templates before the presets that use +them, then, in name order, entries that neither depend on nor are depended on by another entry of their own +list, and any entry on a dependency cycle). Hand-editing the index is fine for a one-line addition, but the committed result must equal what `update-index` writes, because `check` compares them. -The loader itself reports none of this: an unregistered file, or an entry with a typo'd key -(`"subpath"`), is silently dropped. (A typo'd `sub_path` is a `check` error naming the entry.) +The loader itself reports none of this: an unregistered file, or an entry with a misspelled key +(`"subpath"`), is silently dropped. (A misspelled `sub_path` value is a `check` error naming the entry.) -`BBL/cli_config.json` and `BBL/filament/filaments_color_codes.json` are auxiliary data loaded by path, -not presets. The tool's `NON_PROFILE_FILES` excludes these basenames from preset maintenance. +`BBL/cli_config.json` and, in `BBL/filament/`, `filaments_color_codes.json`, `filament_id_map.json`, +`filament_name_map.json` and `support_recommended_params.json` are auxiliary data files read by path, +not presets. The last three carry a `type` key and look like presets; the tool excludes all five from +preset maintenance. ## `version` -Parsed by a four-component Semver where the 4th is folded in as `patch = patch*100 + value`. Write it -zero-padded, `MM.mm.pp.bb`; a couple of bundles drop a component or the padding, but do not imitate them. +Four components, `MM.mm.pp.bb`, compared as a version number in which the fourth is folded into the +third (`patch × 100 + build`). Write all four components, zero-padded. -- **Bump the version for every bundle the PR touches.** `PresetUpdater` installs bundled resources - only when their version is newer than the installed version; the `.opc` preset cache is also - versioned. Nothing in profile CI checks the bump. -- **Keep the last component ≤ 99.** `02.04.00.100` and `02.04.01.00` both parse to `2.4.100`. A bundle - that reaches `.99` carries into the third component (`02.03.02.99` → `02.03.03.00`). -- An **absent** version is worse than a stale one: the validator still passes, but `Semver::valid()` - excludes `0.0.0`, so the vendor is dropped from the configuration wizard entirely and the preset cache - is disabled for it. An *unparseable* version is not silent — it throws and discards the whole bundle - (see the failure table below). +- **Bump the version for every bundle the change touches.** The app installs bundled profiles only + when their version is newer than the installed one, and the `.opc` preset cache is also keyed on + the version. Nothing in profile CI checks the bump. +- **Keep the last component ≤ 99.** `02.04.00.100` and `02.04.01.00` both read as + `2.4.100`. A bundle that + reaches `.99` carries into the third component (`02.03.02.99` → `02.03.03.00`). +- An **absent** version is worse than a stale one: it reads as `0.0.0`, which is not a valid version. + `check` and the validator still pass, but the vendor is dropped from the setup wizard entirely and gets no preset cache. Confirm the key exists. An + *unparseable* version is not silent: it discards the whole bundle (`vendor 's config version: + invalid`). ## Common preset keys | Key | Value | | --- | --- | -| `type` | `machine_model` / `machine` / `process` / `filament` | -| `name` | the preset name; the filename is *not* authoritative | -| `inherits` | the parent's exact `name` — no path, no `.json` | +| `type` | `machine_model`, `machine`, `process` or `filament` | +| `name` | the preset name, the identity every reference uses; the filename is *not* authoritative | +| `inherits` | the parent's exact `name`: no path, no `.json` | +| `include` | a template's exact `name`, or an array of them, layered under this preset's own keys ([below](#inherits-and-include)) | | `instantiation` | the **string** `"true"` (selectable) or `"false"` (base) | -| `from` | `"system"` by convention; the vendor loader never reads it | -| `setting_id` | required on instantiated presets, forbidden on bases — generated | -| `renamed_from` | `;`-separated list of old names this preset supersedes | +| `from` | `"system"` for shipped presets | +| `setting_id` | generated; required on instantiated presets, forbidden on bases | +| `renamed_from` | `;`-separated old names this preset supersedes ([below](#renamed_from)) | These are config-preset keys; `machine_model` records have their own -[schema](machine-profiles.md#a-machine_model-is-not-a-config-preset). Keep `from` as `"system"` -for shipped presets. The vendor loader ignores it, but the CLI config-file loader accepts only -`system`, `user` or `User` and handles their inheritance differently. +[key set](machine-profiles.md#machine_model-a-record-not-a-config-preset). Keep `from` as `"system"`: +the bundle loader ignores it, but loading the file as a CLI config accepts only `system`, `user` or +`User` and handles their inheritance differently. -`instantiation` is the one metadata key that is hard-gated: a missing key or any value other than the -strings `"true"`/`"false"` is an error (`Missing instantiation attribute for `). A JSON boolean -`true` fails harder — it throws inside `load_from_json` and takes the **whole vendor bundle** down. +`instantiation` is the one metadata key the validator gates: a missing key or any value other than the +strings `"true"` / `"false"` is a counted error (`Missing instantiation attribute for `) that fails +the validator, though the preset still loads and is treated as selectable. A file with no +`instantiation` whose name contains `gcode`, or that has no `name`, silently becomes an include-only +template. A JSON boolean `true` fails harder: it takes the **whole vendor bundle** down. -### `inherits` +## `inherits` and `include` -Resolution is an exact-name lookup **within the same bundle**, plus one exception: filaments may inherit -from `OrcaFilamentLibrary`, which is loaded first and becomes the base bundle. Vendor-to-vendor -inheritance always fails. You can inherit from an instantiated preset as well as from a base; it is -common. +`inherits` resolves by exact name **within the same bundle**, plus one exception: filaments may inherit +from OrcaFilamentLibrary, which is loaded first. Vendor-to-vendor inheritance always fails, and an +unresolved `inherits` discards the bundle. You can inherit from an instantiated preset as well as from a +base. -### `renamed_from` +`"include": ["", …]` (or one bare name) pulls in `instantiation: "false"` presets of the same type +from the same bundle (never the library), registered before the includer. It shares a block of keys +between presets that do not share a parent: a variant layout, a G-code template. Only `"false"` presets +can be included, so a name that resolves to nothing (misspelled, registered after the includer, or a +selectable preset) is a counted error (`can not find include`) and the preset loads without it. + +**How a preset's config is composed:** start from the parent's stored config (a root starts from the +built-in defaults), apply each preset named in `include` in the order listed, then the preset's own +keys. Later layers win, so precedence is own keys > later includes > earlier includes > the `inherits` +chain. Only then is every variant key of the composed config resized to its variant length +([widths](extruder-variants.md#widths)), and keys of another preset type removed. The two routes hand +down different widths: + +- **`inherits` hands down the resized config.** A base is stored *after* its own resize, at the length + of its own `*_extruder_variant` (one variant for a base of any type that writes none, whatever its + extruder count). A child therefore inherits the base's arrays at the base's width: an array wider than + that is cut to its first values before any child sees it, and a child that adds variants gets those + first values padded. So widen an array only on a preset whose own variant list already has the + entries; a wide array on a narrow base is silently lost at load, and `check`, which composes at the + width each file wrote and judges selectable presets only, misses that cut. +- **`include` hands down the template's diff, at its pre-resize width.** An included preset contributes + every key where its own composed config (its parent, its own includes and its own keys) differs from + the built-in defaults, taken *before* its resize. So keys the template inherits are passed on too, + arrays it writes arrive at the width its file wrote, and a key it sets to the built-in default value + is not passed on at all, so it cannot override what the includer inherited. Resizing happens on the + includer, not on the template. + +## `renamed_from` One JSON string, `;`-separated for several old names. -- Write `"A;B"`, never `"A ; B"` — an unquoted item keeps its trailing space and can never match. +- Write `"A;B"`, never `"A ; B"`: a space after a `;` is skipped, but a space before it stays part of + the name (`"A "`), which can never match. - When `renamed_from` is **absent** and the name contains `@`, the loader auto-adds the `@`-removed form (`X @Y` → `X Y`) as a rename alias. Declaring an explicit `renamed_from` **suppresses** that, so a - preset that needs both the `@`-removed form and a real old name must list both. No shipped profile - currently does, which means any preset that gained a `renamed_from` quietly lost its `X Y` alias. + preset that needs both the `@`-removed form and a real old name must list both; a preset that gains + a `renamed_from` without it quietly loses its `X Y` alias. - It rescues names stored **outside** the tree: user presets and 3MF projects. It does **not** rescue - in-tree `inherits` (exact lookup), it does **not** satisfy `check_name_consistency`, the validator - reports an in-tree reference that only resolves through it (`references renamed compatible_printers - "OLD" (now "NEW")`), and `machine_model` records never read it at all. -- Only one preset may claim a given old name — two that do is a counted error + in-tree `inherits` (exact lookup), it does **not** satisfy the index-name rule, the validator reports + an in-tree reference that only resolves through it (`references renamed compatible_printers "OLD" + (now "NEW")`), and `machine_model` records never read it at all. +- Only one preset may claim a given old name; two that do is a counted error (`… was marked as renamed from "Y" … as well`). But the redirect is **inert while a live preset still - carries that name**, and nothing checks *that*; Z-Bolt ships a folder of such dead entries. + carries that name**, and nothing checks *that*, so a neighbour's `renamed_from` is no model. -## Failure modes, ranked by blast radius +## Failure scopes | Scope | Cause | | --- | --- | -| **All vendors, zero system profiles** | a non-string `version`, `name` or `url` at the top level of a vendor index (`"version": 2`), or non-string `nozzle_diameter` on a model — `nlohmann::type_error` escapes the per-vendor `std::runtime_error` catch | -| **The whole vendor bundle** | unparseable `version`; index JSON parse error; a `sub_path` file missing or unparseable; unresolvable `inherits`; duplicate preset name within the vendor; empty/unknown `printer_model` or `printer_variant`; a filament resolving no `filament_id` | -| **One preset** | `instantiation` missing or a wrong string; keys belonging to another preset type (`contains incorrect keys: …, which were removed`); a non-string inside a `*_list` entry (`invalid value type for `) | -| **Logged, not counted** | a raw JSON number in a preset — `invalid json type for `, the value is dropped and the exit code stays 0 | -| **Nothing reported by the loader** | unregistered file; misspelled setting key; missing bed/hotend asset. Only the first of those is a `check` error; the other two reach users | +| **Every vendor except OrcaFilamentLibrary, and all user presets** | a non-string where the index or a `machine_model` expects a string (`"version": 2` at the top level of an index, a numeric `name` or `url`, a non-string `nozzle_diameter` or other model key): `[json.exception.type_error.302] type must be string`, and the validator reports `Validation failed` | +| **The whole vendor bundle** | index JSON parse error; unparseable `version`; a listed file missing or unparseable; a value its option cannot take, such as `nil` in a non-nullable key (`Failed loading configuration file`); unresolved `inherits`; two selectable presets with one name; empty or unknown `printer_model` / `printer_variant`; a filament resolving no `filament_id`; a JSON boolean `instantiation` | +| **A counted error; the preset still loads** | `instantiation` missing or not `"true"` / `"false"`; keys belonging to another preset type (`contains incorrect keys: …, which were removed`); a non-string inside a `*_list` entry (`invalid value type for `); an `include` naming nothing usable (`can not find include`, loads without it) | +| **The rest of the file, logged only** | an array with a non-string element (`[0.4]`, `invalid json array`): that key and every key after it in the file are dropped, and no error is counted | +| **One value, logged only** | a raw JSON number in a preset (`invalid json type for `): the value is dropped and the exit code stays 0 | +| **Nothing reported by the loader** | unregistered file; two bases with one name, or a base and a selectable preset with one name (the first in the index wins); misspelled setting key; missing bed, hotend or cover asset. `check` catches the first two; the others reach users | -Deleting a file the index still lists surfaces as a *parse error* on line 1, not "file not found" — the -loader `ifstream`s the missing path and nlohmann reports `unexpected end of input`. +Deleting a file the index still lists surfaces as a *parse error* on line 1 (`unexpected end of input`), not "file +not found". -Preset names are a **single global namespace across every vendor**: a duplicate within one vendor is a -hard bundle failure, a duplicate across vendors is reported as `Found duplicated preset: in -vendor: ` and still counts as an error. `check_preset_name_uniqueness` catches the within-bundle -case earlier and more precisely — including an *unindexed* twin, which is one `sub_path` edit away from -silently becoming the parent every child resolves to (`std::map::emplace` keeps the first insertion, so -index order decides). Base names, by contrast, repeat across bundles by design: `fdm_process_common` -exists in nearly all of them. +Selectable preset names are a **single namespace across every vendor**: a duplicate within one vendor +is a hard bundle failure, and a duplicate across vendors is reported as `Found duplicated preset: +in vendor: ` and still counts as an error. `check` catches the within-bundle case earlier and +more precisely, bases included, and including an *unindexed* twin, which is one `sub_path` edit away +from silently becoming the parent every child resolves to (the first registered preset of a name wins, +so index order decides). Base names, by contrast, repeat across bundles by design: +every bundle may have its own `fdm_process_common` ([uniqueness](naming.md#uniqueness)). ## Starting a whole new vendor bundle -Nothing generates one; copy the smallest bundle that resembles the hardware. **`Voxelab` or `M3D`** are -the minimal shape — a shared machine base, the model, one variant, a shared process base, two -processes, and an empty `filament_list` that takes the library generics. Do *not* start from `Phrozen`: -it carries local `fdm_filament_*` copies that have drifted from the library, and a filament preset that -restates most of its parent — the style this skill advises against. +Nothing generates one; copy the smallest bundle that resembles the hardware. **`Voxelab`** is the +minimal shape: a shared machine base, the model, one variant, a shared process base, two processes, and +an empty `filament_list`, so the printer takes the library generics. Do *not* start from a bundle that +carries local `fdm_filament_*` copies, which drift from the library, or filament presets that restate +most of their parent, the style this skill advises against. Write the machine files **last**, so you only visit them once: -1. **Choose the names first** — model, variant(s), process(es). Everything else references them. +1. **Choose the names first**: model, variant(s), process(es). Everything else references them + ([naming.md](naming.md)). 2. `resources/profiles/.json`: `name`, `version` (`01.00.00.00`), `force_update: "0"`, - `description`, and all four `*_list` arrays (an empty `filament_list` is fine). -3. The shared bases — `/machine/fdm_machine_common.json` and - `/process/fdm_process_common.json`, both `"instantiation": "false"` with no `setting_id`. - For a Klipper printer add your own `/machine/fdm_klipper_common.json` inheriting the machine + `description`, and all four `*_list` arrays (empty is fine: `update-index` fills them once the files + exist, so this step only needs the bundle metadata to be right). +3. The shared bases: `/machine/fdm_machine_common.json` and + `/process/fdm_process_common.json`, both `"instantiation": "false"` with no `setting_id`. For + a Klipper printer add your own `/machine/fdm_klipper_common.json` inheriting the machine base; there is no shared one, because a `machine` preset can only inherit inside its own bundle. 4. One selectable process per variant, each naming its variant in `compatible_printers`. 5. Bed assets and `_cover.png`, all directly in `/`. None of them is needed for the - bundle to load, and nothing in CI checks them — but the bed files are inert unless the `machine_model` - names them in `bed_model` / `bed_texture`, and the cover is found by convention as + bundle to load, and nothing in CI checks them; but the bed files are inert unless the + `machine_model` names them in `bed_model` / `bed_texture`, and the cover is found by convention as `_cover.png`. -6. The `machine_model` record and the `machine` variants, now that every value they reference exists — +6. The `machine_model` record and the `machine` variants, now that every value they reference exists; the minimum key sets and the `default_*` shapes are in - [machine-profiles.md](machine-profiles.md#the-machine-variant). -7. Run the tool and validate — follow + [machine-profiles.md](machine-profiles.md#machine-the-variant). +7. Run the tool and validate: follow [Creating or modifying a profile](../SKILL.md#creating-or-modifying-a-profile). `generate-id` is not optional for a new bundle: the validator loads presets that have no `setting_id`, but `check` fails - every one of them. `update-index` will fill the four `*_list` arrays for you once the files exist, so - step 2 only needs the bundle metadata to be right. + every one of them. ## `resources/profiles_template/` A separate tree (`Template.json` + `Template/`) holding filament and process templates. It is **not** a -scaffold for shipped profiles — `CreatePresetsDialog.cpp` reads it for the in-app "create a custom -printer/filament" wizard, so editing it changes what users get when they create a custom preset. -`check_profile.sh`'s validator checks default to `resources/profiles` (redirectable with `-p`), and so -does `orca_profile_tool.py` (redirectable with `--profiles`); -neither covers this tree. +scaffold for shipped profiles: the app's "create a custom printer / filament" dialog reads it, so +editing it changes what users get when they create a custom preset. `check_profile.sh`'s validator +checks default to `resources/profiles` (redirectable with `-p`), and so does `orca_profile_tool.py` +(redirectable with `--profiles`); neither covers this tree. diff --git a/.claude/skills/orca-profiles/scripts/shared_settings.py b/.claude/skills/orca-profiles/scripts/shared_settings.py new file mode 100644 index 0000000000..261fe19da4 --- /dev/null +++ b/.claude/skills/orca-profiles/scripts/shared_settings.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python3 +"""Find settings to move onto shared bases, and prove a move changed nothing. + + snapshot OUT.json write every selectable preset's config as the loader stores it + compare BEFORE.json report every value that differs from the snapshot; exit 1 if any + candidates --vendor V restated values; per base, the settings its presets all share and the + defaults with exceptions that would pay + +Every subcommand takes --profiles DIR (default resources/profiles). + +Configs are composed the loader's way: the parent's stored config, then each include at +the width its file wrote, then the preset's own keys, and every variant key resized to the +preset's own variant list (one variant without one), padded with its first value or cut. +A base is stored after that resize, so a variant array wider than a base's list reaches its +children cut. Not modelled: the built-in defaults. A key no file in a preset's chain writes +loads its default, so compare reports a key written on one side only separately: it is no +change when the written value is the option's default in PrintConfig.cpp. Nor is it modelled +that an include template does not pass on a key equal to the default. Reads +scripts/orca_profile_tool.py. +""" +import argparse +import json +import os +import sys +from collections import Counter, defaultdict + +# The profile tool lives in /scripts; this file in /.claude/skills/orca-profiles/scripts. +sys.path[:0] = [os.path.join(os.getcwd(), "scripts"), + os.path.join(os.path.dirname(os.path.abspath(__file__)), *[os.pardir] * 4, "scripts")] +import orca_profile_tool as tool # noqa: E402 + +TYPES = ("machine", "process", "filament") +# Keys the loader reads from each file as metadata; neither inherits nor include passes them on. +PER_FILE = {"type", "name", "from", "instantiation", "setting_id", "renamed_from", "description", + "inherits", "include", "version", "url", "is_custom_defined"} +# Keys the app replaces with the selected presets' names before slicing: a file's value never counts. +REPLACED = {"print_settings_id", "printer_settings_id", "filament_settings_id"} +# What a restructure changes by design, or what never reaches a slice. +MOVED_BY_DESIGN = {"inherits", "include"} | REPLACED +# Keys that stay in their own file: metadata, identity, and each preset's compatibility. +NEVER_SHARED = PER_FILE | REPLACED | {"filament_id", "compatible_printers", "compatible_prints", + "printer_variant", "printer_model"} + + +class Tree: + def __init__(self, profiles_dir): + self.dir = profiles_dir + self.scheme = tool._variant_scheme() + self.vendors = tool.list_vendor_names(profiles_dir) + self.bundles = {v: tool.load_vendor_configs(profiles_dir, v) for v in self.vendors} + self.cache = {} + + def lookup(self, vendor, ptype, name, in_ofl=False): + """(vendor the name resolves in, (rel, data)); filaments fall back to the library.""" + if not in_ofl and name in self.bundles[vendor][ptype]: + return vendor, self.bundles[vendor][ptype][name] + if ptype == "filament" and tool.OFL in self.bundles and name in self.bundles[tool.OFL][ptype]: + return tool.OFL, self.bundles[tool.OFL][ptype][name] + return None, None + + def composed(self, vendor, ptype, name, drop=None, seen=frozenset()): + """Config before the preset's own resize: parent stored, includes, own keys.""" + owner, found = self.lookup(vendor, ptype, name, vendor == tool.OFL) + if found is None or (owner, name) in seen: + return {} + seen = seen | {(owner, name)} + data = found[1] + config = {} + if data.get("inherits"): + config.update(self.stored(owner, ptype, data["inherits"], seen)) + include = data.get("include") or [] + for included in [include] if isinstance(include, str) else include: + if included in self.bundles[owner][ptype]: + config.update(self.composed(owner, ptype, included, seen=seen)) + config = {k: v for k, v in config.items() if k not in PER_FILE} + config.update((k, v) for k, v in data.items() if k != drop) + return config + + def stored(self, vendor, ptype, name, seen=frozenset()): + key = (vendor, ptype, name) + if key not in self.cache: + self.cache[key] = self.resize(ptype, self.composed(vendor, ptype, name, seen=seen)) + return self.cache[key] + + def resize(self, ptype, config): + list_key, strides = self.scheme[ptype] + length = len(tool._as_list(config[list_key])) if list_key in config else 1 + out = dict(config) + for key, stride in strides.items(): + if key in out: + values = tool._as_list(out[key]) + need = length * stride + out[key] = values[:need] + values[:1] * (need - len(values)) + return out + + def presets(self, vendors=None, ptypes=TYPES): + for vendor in vendors or self.vendors: + for ptype in ptypes: + for name, (rel, data) in sorted(self.bundles[vendor][ptype].items()): + yield vendor, ptype, name, rel, data + + +def snapshot(tree): + return {f"{vendor}/{ptype}/{name}": {k: v for k, v in tree.stored(vendor, ptype, name).items() + if k not in MOVED_BY_DESIGN} + for vendor, ptype, name, _rel, data in tree.presets() + if data.get("instantiation") == "true"} + + +def compare(before, after): + changed, one_sided = 0, [] + for preset in sorted(before.keys() | after.keys()): + old, new = before.get(preset), after.get(preset) + if old is None or new is None: + print(f"{preset}: {'added' if old is None else 'removed'}") + changed += 1 + continue + for key in sorted(old.keys() | new.keys()): + if key not in old or key not in new: + one_sided.append(f"{preset}: {key} " + f"{json.dumps(old[key]) if key in old else '(built-in default)'} -> " + f"{json.dumps(new[key]) if key in new else '(built-in default)'}") + elif old[key] != new[key]: + print(f"{preset}: {key} {json.dumps(old[key])} -> {json.dumps(new[key])}") + changed += 1 + for line in one_sided: + print(line) + print(f"{changed} difference(s)") + if one_sided: + print(f"{len(one_sided)} key(s) written on one side only: each is a difference unless the " + f"written value is the option's default in src/libslic3r/PrintConfig.cpp") + return changed + len(one_sided) + + +def candidates(tree, vendor, ptypes, group_by): + for ptype in ptypes: + entries = {name: data for _v, _t, name, _rel, data in tree.presets([vendor], (ptype,))} + selectable = [n for n, d in entries.items() if d.get("instantiation") == "true"] + stored = {n: tree.stored(vendor, ptype, n) for n in entries} + list_key = tree.scheme[ptype][0] + + # Restated: a key a file writes that it would inherit unchanged without writing it. + restated = {} + for name, data in entries.items(): + restated[name] = sorted( + k for k in data if k not in NEVER_SHARED and k != list_key + and (data.get("inherits") or data.get("include")) + and tree.resize(ptype, tree.composed(vendor, ptype, name, drop=k)).get(k) == stored[name][k]) + if restated[name]: + print(f"{vendor}/{ptype} {name}: restates what it inherits: {', '.join(restated[name])}") + + # Groups: every preset with selectable presets below it, or the --group-by values. + chain = {n: [] for n in selectable} + for name in selectable: + node = entries[name].get("inherits") + while node in entries and node not in chain[name]: + chain[name].append(node) + node = entries[node].get("inherits") + groups = defaultdict(list) + for name in selectable: + if group_by: + groups[json.dumps(stored[name].get(group_by))].append(name) + else: + for base in chain[name]: + groups[base].append(name) + printed = {} + for label, members in sorted(groups.items(), key=lambda g: -len(g[1])): + if len(members) < 2 or label == "null": + continue + if frozenset(members) in printed: + print(f"\n{vendor}/{ptype} {label}: the same presets as {printed[frozenset(members)]}") + continue + common = [b for b in chain[members[0]] if all(b in chain[m] for m in members[1:])] + home = common[0] if group_by and common else None if group_by else label + + def below(m): + """m and the files between it and the group's home.""" + return [m] + chain[m][:chain[m].index(home)] if home in chain[m] else [m] + shared, defaults = [], [] + for key in sorted(set().union(*(entries[m].keys() for m in members)) - NEVER_SHARED): + loaded = [json.dumps(stored[m].get(key)) for m in members] + counts = Counter(loaded).most_common(2) + if len(counts) == 1: + writers = sum(key in entries[m] and key not in restated[m] for m in members) + if writers >= 2: + shared.append(f"{key} ({writers} write it)") + continue + (top, held), (_, runner_up) = counts + if held == runner_up or top == "null" or home is None: + continue + # Balance 5: w presets drop their copy; a presets that take the key from the home + # (no file on their way to it writes it) and load another value must write theirs. + w = sum(key in entries[m] and v == top for m, v in zip(members, loaded)) + a = sum(v != top and not any(key in entries[f] for f in below(m)) + for m, v in zip(members, loaded)) + if w - a > 1: + shown = top if len(top) <= 40 else top[:37] + "..." + defaults.append(f"{key} = {shown}: {held} load it, {w} write it, " + f"{a} would have to write their own") + if shared or defaults: + where = f"; nearest common base {common[0]}" if group_by and common else "" + title = f"{group_by} = {label}" if group_by else label + print(f"\n{vendor}/{ptype} {title}: {len(members)} presets{where}") + printed[frozenset(members)] = title + for line in shared: + print(f" {line}") + if defaults: + print(" default with exceptions:") + for line in defaults: + print(f" {line}") + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + profiles = argparse.ArgumentParser(add_help=False) + profiles.add_argument("--profiles", default=os.path.join("resources", "profiles"), + help="profiles directory (default: resources/profiles)") + sub = parser.add_subparsers(dest="command", required=True) + sub.add_parser("snapshot", parents=[profiles]).add_argument("out") + sub.add_parser("compare", parents=[profiles]).add_argument("before") + cand = sub.add_parser("candidates", parents=[profiles]) + cand.add_argument("--vendor", required=True) + cand.add_argument("--type", choices=TYPES, action="append") + cand.add_argument("--group-by", help="group selectable presets by this key's value instead of by " + "base: printer_model, gcode_flavor, extruder_type, filament_id, layer_height, ...") + args = parser.parse_args() + tree = Tree(args.profiles) + if args.command == "snapshot": + presets = snapshot(tree) + with open(args.out, "w", encoding="utf-8") as f: + json.dump(presets, f, sort_keys=True) + print(f"{len(presets)} selectable presets written to {args.out}") + elif args.command == "compare": + with open(args.before, encoding="utf-8") as f: + sys.exit(1 if compare(json.load(f), snapshot(tree)) else 0) + else: + candidates(tree, args.vendor, args.type or TYPES, args.group_by) + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 24317b0add..d45ec215b8 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -183,9 +183,11 @@ jobs: os: ${{ vars.SELF_HOSTED && 'orca-macos-arm64' || 'macos-14' }} artifact: ${{ github.sha }}-tests-macos-arm64 test-dir: build/arm64/tests - # Slice a two-colour cube through every shipped printer so all custom g-code - # (change_filament_gcode, machine start/end, etc.) is expanded - catches - # slicing regressions the static profile checks and unit tests can't see. + # Slice a two-colour cube through every shipped printer, and through every + # system process/filament whose templates no printer's own slice reaches, so + # every custom g-code and filename_format shipped is expanded (names in {if} + # branches not taken included) - catches slicing regressions the static + # profile checks and unit tests can't see. # Profile-only PRs are covered by check_profiles.yml's nightly binary; this # covers src/engine PRs with the PR-built binary. slice_check_linux: diff --git a/.github/workflows/check_profiles.yml b/.github/workflows/check_profiles.yml index e668482bfd..2a6ed8f0a4 100644 --- a/.github/workflows/check_profiles.yml +++ b/.github/workflows/check_profiles.yml @@ -14,6 +14,9 @@ on: # this workflow. - 'resources/printers/**' - 'scripts/**' + # orca_profile_tool.py reads the variant key sets from PrintConfig.cpp, and its + # tests the obsolete keys, so a PR changing either must be checked against the profiles. + - 'src/libslic3r/PrintConfig.cpp' - ".github/workflows/check_profiles.yml" workflow_dispatch: @@ -71,8 +74,10 @@ jobs: set +e ./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 2>&1 | tee ${{ runner.temp }}/validate_system.log exit ${PIPESTATUS[0]} - # Slice a two-colour cube through every printer so all custom g-code (incl. change_filament_gcode) - # is expanded - catches undefined-placeholder / invalid-flow bugs the static checks above cannot see. + # Slice a two-colour cube through every printer, and through every system process/filament whose + # templates no printer's own slice reaches, so every custom g-code and filename_format shipped is + # expanded (names in {if} branches not taken included) - catches undefined-placeholder / + # invalid-flow bugs the static checks above cannot see. - name: validate slice (expand custom g-code) id: validate_slice continue-on-error: true diff --git a/.github/workflows/ofl-ota-cronjob.yml b/.github/workflows/ofl-ota-cronjob.yml index 9d027190ae..501508eafa 100644 --- a/.github/workflows/ofl-ota-cronjob.yml +++ b/.github/workflows/ofl-ota-cronjob.yml @@ -146,7 +146,7 @@ jobs: "repos/${{ github.repository }}/actions/workflows/post_merge_profiles.yml/runs" \ -f branch="$branch" -f event=workflow_dispatch -f per_page=100)" run_id="$(jq -r --arg marker "[OFL cron $dispatch_id]" \ - '[.workflow_runs[] | select((.display_title // "") | contains($marker))] \ + '[.workflow_runs[] | select((.display_title // "") | contains($marker))] | sort_by(.created_at) | last | .id // empty' <<< "$runs_json")" [ -n "$run_id" ] && break sleep 5 diff --git a/.github/workflows/pr-label-bot.yml b/.github/workflows/pr-label-bot.yml index fe74841831..199b4dd7e7 100644 --- a/.github/workflows/pr-label-bot.yml +++ b/.github/workflows/pr-label-bot.yml @@ -35,6 +35,7 @@ jobs: // kind of change 'crash', 'bug-fix', + 'SECURITY', 'enhancement', 'QoL', 'optimization', @@ -193,6 +194,7 @@ jobs: // kind of change 'crash', 'bug-fix', + 'SECURITY', 'enhancement', 'QoL', 'optimization', diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index f5850d9fd7..41ef0b1f4b 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -44,6 +44,14 @@ jobs: uses: actions/download-artifact@v8 with: name: ${{ inputs.artifact }} + # run_unit_tests.sh installs the plugin tests' numpy with the uv the build stages + # beside them; the Windows arm64 build bundles none, so put one on PATH there. + - name: Install uv + if: runner.os == 'Windows' && runner.arch == 'ARM64' + uses: astral-sh/setup-uv@v10.2.0 + with: + version: "0.11.21" # ORCA_UV_VERSION in CMakeLists.txt + enable-cache: false - uses: lukka/get-cmake@latest with: cmakeVersion: "~4.3.0" # use most recent 4.3.x version diff --git a/.gitignore b/.gitignore index b029afa180..5224ecad6b 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,6 @@ internal_docs/ __pycache__/ *.pyc *.opc -docs/superpowers/ \ No newline at end of file +/.test/ +docs/superpowers/ +ctest_results.xml diff --git a/TEXTURE_DISPLACEMENT.md b/TEXTURE_DISPLACEMENT.md new file mode 100644 index 0000000000..b5c69a060a --- /dev/null +++ b/TEXTURE_DISPLACEMENT.md @@ -0,0 +1,581 @@ +# Texture Displacement - Technical Notes + +Branch: `feature/texture_displacement`. Reference for the feature as it stands: what it does, how the +algorithms work, and where the code lives. + +## What it does + +A paint-style gizmo (`GLGizmoTextureDisplacement`) that lets you: +- Paint one or more "layers" onto a model's surface, each a height-map texture with its own + depth/tiling/rotation/offset/invert/tile-mode/projection-mode/blend-mode. +- Pick a texture from a shipped library (`resources/textures/displacement/`) or import your own + (saved into `/textures/displacement/`, kept separate so app updates can't clobber it). +- Combine overlapping layers with image-editor-style blend modes (Add/Subtract/Multiply/Divide). +- Preview the true displaced result live, before baking (background job, not on the UI thread). +- Preview via a fast GPU shader instead (no real geometry movement) for a lighter-weight alternative. +- Bake into real mesh geometry on demand, restricted to the painted area only. +- Remesh and subdivide so a low-poly model has enough vertices to show fine detail. +- Unwrap a painted patch with a real CGAL LSCM parameterization and view it in a dedicated, + dockable 2D "UV Editor" pane. + +## Standard vs Pro mode + +A two-position slider in the panel header, right of the Dock/Undock button. + +**Pro** shows every mesh-preparation control; Remesh, Subdivide and Bake are run separately by the user, +in whatever order they like. + +**Standard** hides all of it and folds one fixed recipe into the Bake button, because a height map only +ever *moves vertices that already exist* - painting onto an imported 12-triangle box and pressing Bake +would otherwise do nothing visible. Standard's Bake is: + +1. `plan_remesh()` + `replace_mesh_keep_all_paint()` - isotropic remesh to 1 mm, sharp edges above 40 + degrees protected. Gives the subdivider an even starting density whatever the input looked like. +2. `plan_adaptive_subdivision()` + `apply_adaptive_subdivision()` - feature-adaptive refinement, max + edge 20 mm, detail 0.02 mm, min edge 0.02 mm. +3. `bake()` - the ordinary background displacement job. + +Both preparation stages are *planned* before the undo snapshot and *applied* after it, so a stage with +nothing to do is skipped without leaving an empty undo step. The standalone Pro buttons share the same +plan/apply split. + +**All three stages sit under one undo step.** `Plater::take_snapshot()` records the state *before* the +change, so a single snapshot taken at the top of `bake_standard()` means one Undo returns the mesh to +exactly what was imported. `TextureDisplacementBakeInput::take_snapshot` lets the caller say who owns +the undo step - true for the Pro-mode button, false for the pipeline, whose background job commits long +after that snapshot's scope has closed. + +The presets live in one place (`STD_*` constants) and `apply_standard_mode_presets()` pins the hidden +controls to them every frame while Standard is active, so the live preview cannot disagree with what +Bake will do. Switching to Standard also closes the subdivision preview, whose controls have just gone. + +One control survives into Standard: **"Added triangles (k)"**, the subdivision budget. It is deliberately +*not* pinned - pinning would fight the user's own slider every frame - because unlike the rest of the +recipe its right value depends on the part rather than on the method (a big model, or a fine texture, +simply needs more triangles). Default 1500. The widget is one lambda shared by both layouts. + +Standard remeshes *after* painting, so the remesh has to preserve paint: `ModelVolume::restore_painting()` +only remaps the four standard channels, so `replace_mesh_keep_all_paint()` additionally runs +`TriangleSelector::remap_painting()` over the eight texture-displacement masks. The Pro Remesh button +goes through the same helper. If the remap comes back empty the pipeline stops with a message rather +than baking a flat mesh. + +## Architecture + +### Data model (per `ModelVolume`) + +Each of up to `TEXTURE_DISPLACEMENT_MAX_LAYERS` (8) layers gets its **own independent +`FacetsAnnotation`** paint mask - the same `TriangleSelector`/`FacetsAnnotation` machinery every other +paint gizmo (FdmSupports, Seam, MMU, FuzzySkin) already uses, just one full instance per layer slot +instead of one per volume. This is what makes layered/blended painting work for free: the same triangle +can be `ENFORCER` in layer 2's mask and layer 5's mask simultaneously, and at bake/preview time each +layer displaces the surface left by the previous one (image-editor-layer semantics). + +Whole-stack settings (border handling, post-process smoothing) live beside the layers in +`texture_displacement_options` (`TextureDisplacementOptions`), since they belong to no single layer. + +### Bake algorithm (`libslic3r/TextureDisplacement.cpp`) + +`build_texture_displacement(base_mesh, layers, facets_data, options)` is **accumulate-then-displace, +and topology-preserving**: the returned mesh has exactly the input's vertices and triangles, in the +same order - only the positions of displaced vertices differ. + +1. `its_compactify_vertices()` on a copy of the input. In practice a no-op (it only drops + *unreferenced* vertices, and preserves the order and indices of the rest). It is there to + guarantee the index alignment step 3 depends on. +2. Area-weighted vertex normals of the **undisplaced** mesh, computed once. Every layer both projects + and displaces along these, so a vertex covered by several layers moves along one single well-defined + direction. Where the paint does *not* cover every triangle around a vertex, the normal is recomputed + from the painted triangles alone (the union over all layers, so it stays one direction per vertex): + on the rim of a fully painted top face the whole-mesh normal is the 45-degree bisector it shares with + the side wall, and displacing along that flares the rim outwards instead of raising it. Interior + vertices are unaffected - all their triangles are painted, so the two normals coincide. Paint + coverage per original triangle comes straight off `TriangleSplittingData::triangles_to_split`. +3. For each layer in slot order: deserialize its stored paint mask into a `TriangleSelector` against + the **base mesh** (never against a previous layer's output), then + `selector.get_facets_strict(ENFORCER)` -> the painted patch. Two facts are exploited: + - `get_facets_strict()` returns the mesh's **entire** referenced vertex array regardless of which + state was asked for - only `.indices` is filtered by state. So `get_facets_strict(ENFORCER)` + and `get_facets_strict(NONE)` share identical vertex indexing, which is what lets boundary + detection be a plain index check instead of a position-hash lookup. + - The selector's vertex array *starts with* the mesh's own vertices (extra ones created where a + brush stroke split a triangle are appended after them), and `get_facets_strict()` emits the + referenced ones in order. Combined with step 1, **selector vertex index `i` is our vertex `i`**. + Split vertices live past the end of our array and are simply skipped - they sit on the paint + boundary anyway (splitting only happens at partial coverage). +4. A vertex used by at least one **unpainted** triangle is a border vertex. Whether it moves is + `TextureDisplacementOptions::displace_border`, and it does by default. Nothing can tear: the bake is + topology-preserving, so a border vertex is *one* vertex shared by both regions and moving it simply + tilts the unpainted triangles that use it. Pinning it instead clamps the outermost ring of relief to + zero, which on a fully painted face collapses the pattern into a ring of steep ramps at the edge; it + is kept as an option for when the relief must not spill past the paint at all. Either way the border + drives the `edge_smoothing` falloff. +5. Per interior vertex: sample the height texture (`sample_layer_height()`, see Projection methods) + and fold `height * depth_mm * (invert ? -1 : 1)` into that vertex's running total via the layer's + `TextureBlendMode` (see Blend modes). A `visited` set makes each layer fold in exactly **once** + per vertex, no matter how many of the patch's triangles share it - otherwise a Multiply/Subtract + layer would apply two or three times over depending on local triangle fan-out. +6. Move each touched vertex along its (step 2) normal by its accumulated total. +7. Optionally (`TextureDisplacementOptions::smooth_*`) relax the result - see Post-process smoothing. + +### Post-process smoothing + +`smooth_mesh_vertices(mesh, movable, strength, iterations)` - Laplacian relaxation, run after all layers +have been folded in, restricted to the vertices flagged in `movable`. Each pass moves a movable vertex a +`strength` fraction of the way to the average of its one-ring, read from a **snapshot** of the previous +pass so the result does not depend on vertex order (a Gauss-Seidel sweep would smooth several times as +hard at the end of the array as at the start). Neighbours come from a CSR-style adjacency built once per +call. Topology-preserving, like the bake. + +Its job is to round off the hard steps a bitmap height map leaves behind - a different knob from +`TextureDisplacementLayer::smoothing`, which blurs the *height map* before it is ever sampled. + +Two ways in, sharing one set of settings on the volume: +- The **"Smooth result"** checkbox + "Smoothing (%)" / "Passes" ride along with Preview and Bake. + `movable` is exactly the set of vertices the displacement moved, so the untouched part of the model + keeps its exact geometry and the ring just outside the displaced set anchors the relaxation (the + relief cannot creep outward). +- **"Smooth baked mesh now"** (`GLGizmoTextureDisplacement::smooth_model()`) applies the same settings to + the volume's *committed* geometry, for relief that is already baked in. `movable` there is the painted + triangles' vertices. Because smoothing never touches the triangle list, this is the one geometry + operation in the gizmo that keeps **every** paint channel verbatim - it saves and restores the eight + texture-displacement masks around `set_mesh()` rather than remapping or dropping them. + +**"Ignore outer ring"** (`smooth_skip_border`, on by default) drops the patch's own outermost ring of +vertices from `movable`. That ring's neighbours *outside* the paint never move, so relaxing it drags the +rim of the relief down toward the flat surface and the pattern comes out half-melted where it meets the +edge. Held out, the border keeps the full depth the texture asked for and only the interior relaxes. +Turning it off softens the outer edge deliberately (a blunter version of the per-layer edge-smoothing +falloff). This is the *smoothing* rim, independent of whether that rim is displaced at all +(`displace_border`, step 4 above); both default to keeping the border sharp. + +### Blend modes + +`TextureBlendMode` {Add, Subtract, Multiply, Divide}, per layer, applied per vertex against the +total accumulated by the layers **below** it (lower slots). The quantity blended is a signed +displacement in **mm**, not a pixel value. + +Add/Subtract are self-explanatory. Multiply/Divide are *scaling* operations and so need a unit +convention: they treat the layer's own value as a **factor relative to 1 mm**. That makes `depth_mm` +a gain, and - the property that makes a Multiply layer usable as a mask - a layer with depth 1 mm +sampling a white (1.0) texel multiplies by exactly 1, i.e. leaves the layers below unchanged. +Divide floors its divisor's magnitude at 0.05: a black texel samples to *exactly* zero, so the divisor +really does hit zero in ordinary use, and an unbounded `1/0` would fling vertices thousands of mm away +and poison the mesh's bounding box (and every plate/print-volume check downstream). The floor doubles as +a cap on how far Divide can amplify the relief beneath it: at most 20x. + +The **lowest painted layer ignores its blend mode**: it has nothing beneath it, and Multiply/Divide +against an implicit zero base would annihilate (or blow up) it. Enforced in +`build_texture_displacement()` (the first layer to reach a given vertex always folds in additively) and +surfaced in the UI, which labels that layer "Base layer" instead of offering a control that does nothing. + +### Projection methods + +Five choices per layer (`TextureProjectionMethod`), all funneling through `apply_uv_transform()` +(scale by `1/tiling_scale`, rotate by `rotation_deg`, add `offset`). They are dispatched by +`sample_layer_height()`, which returns a **height**, not a UV - because Triplanar takes three +texture samples per vertex and so has no single UV that represents it. + +- **Triplanar** (default) - samples the texture on all three world planes (`(y,z)`, `(x,z)`, `(x,y)`) + and blends the three by the vertex's own normal raised to `TRIPLANAR_BLEND_SHARPNESS` (4). Hard-picking + the single axis most aligned with the normal instead is discontinuous wherever that dominant axis + flips: on a +X face the planar coordinate is `(y, z)`, on a -Y face it is `(x, z)`, so at the shared + edge `u` jumps. A weighted blend is continuous across the transition by construction, since the weight + of the axis being left behind falls smoothly to zero. This removes the hard *seam*; some cross-fade + blurring in the band right at a 90° edge is inherent to triplanar mapping. A genuinely seam-free wrap + around a box needs a real unwrap - that is what the LSCM mode is for. +- **Cylindrical** - wraps around an axis through the patch centroid, axis auto-picked as the world + axis *least* aligned with the average normal (perpendicular to the outward radial normal, as a + cylinder's own axis would be). `u = angle * local_radius` (arc length in mm), `v = distance along + axis`. An approximation, not an exact fit for arbitrary geometry, and the axis/centre are not + user-overridable. +- **Spherical** - longitude/latitude around the centroid, scaled by local radius. Same caveat. +- **LSCM** - real UV unwrap via `MeshBoolean::cgal::parameterize_lscm()` (CGAL's + `Surface_mesh_parameterization` package, LSCM algorithm). Computed **once per patch** (not + per-vertex like the others - it's a single global least-squares solve), then each vertex looks up + its precomputed UV. Requires the patch to be a single topological disk (one connected component, + one boundary loop) - `compute_lscm_uvs()` returns empty and the layer falls back to Triplanar if not + (e.g. multiple disconnected painted islands, or a fully closed patch). CGAL's parameterizer needs a + mesh with no isolated/unreferenced vertices, but `get_facets_strict()` returns the *whole* mesh's + vertex array - so `compact_patch_with_map()` builds a clean sub-mesh plus an index map back to the + original vertex numbering, purely local to this file. +- **ViewProjected** ("From view") - a flat projection along a fixed direction captured from the 3D + camera, like a slide projector. `capture_view_projection()` takes the camera's right/up axes, + transforms them into the volume's *local* frame (so the projection rides along if the part is later + moved), and stores them as `TextureDisplacementLayer::view_project_right/up` (unit vectors, so the + projected coordinate stays in mm and `tiling_scale` keeps meaning mm). `sample_layer_height()` + projects `Vec2f(dot(pos, right), dot(pos, up))`. Single-valued per point, so - like LSCM but unlike + blended Triplanar - the fast preview and UV-check overlay precompute it per vertex + (`compute_layer_vertex_uvs()`) and drive the shader's `use_vertex_uv` path. Faces angled away from + the projector smear; that is inherent to view projection. + + Two companions to this mode: + - **Projection frame overlay** (`TextureProjectorFrame`, see below) - a semi-transparent window + dragged over the 3D view whose border becomes the projection's edge. Applying it stores an exact + **projective** map in `view_project_matrix`, which supersedes the affine `right`/`up` axes above + for that layer (`view_project_projective`). + - **"Project only on visible"** (`select_visible_faces()`) - repaints the layer with exactly the + facets the camera can see, so the projected area matches the viewpoint the projector was captured + from. Two tests: a facing test (normal vs. view direction, per triangle - under perspective the + view direction varies across the model, so it is taken from the eye to each centroid), then + `MeshRaycaster::get_unobscured_idxs()` on the survivors to drop facets hidden behind other + geometry, so a concave part's far inner wall is correctly excluded. One ray query per front-facing + facet, hence click-driven (on the checkbox and on each "Capture current view"), never per frame. + It **replaces** the layer's paint rather than adding to it - "project onto what I can see" would + otherwise accumulate every angle the user had ever looked from. + +### Manual seams and island cutting + +`TextureDisplacementLayer::lscm_seam_edges` - undirected mesh-vertex-index edge pairs the unwrap is +forced to cut along, on top of the dihedral-angle seams. `segment_into_charts()` takes a set of these +(translated from mesh -> compacted-patch numbering inside `compute_patch_unwrap()`) and refuses to +union two triangles across a marked edge whatever their angle. Both the unwrap cache key and the +gizmo's `UVEditorState` include the seam list, so marking a seam (which leaves the paint mask +untouched) still forces a re-solve. Like the paint masks, seams are mesh-index-space and so dropped on +any topology change. + +Two ways to write to it: +- **Mark seam (manual)** - a "Mark seams" click mode (`m_seam_edit_mode`) that suppresses painting. A + click raycasts the volume (`m_c->raycaster()->raycasters()[idx]->unproject_on_mesh()`, `idx` = the + volume's slot among model-part volumes), finds the facet's edge nearest the hit point, and toggles it. + Marked edges render as a red overlay (`render_seam_overlay()`), pulled toward the camera so they read + on top. This is the Blender mark-seam workflow. +- **Cut island (auto)** - `cut_island()` takes the selected chart's triangles (back-mapped from the + unwrap via `source_vertex`), finds their 3D bounding box, and marks every edge that straddles the + mid-plane perpendicular to the longest axis. The re-unwrap then splits the chart across its narrow + waist. Exposed as the UV pane's **Cut** button. + +### UV-check overlays (checker / distortion) + +`resources/shaders/{110,140}/texture_displacement_uvcheck.{vs,fs}`, one shader with a `mode` uniform, +drawn over the painted patch (`rebuild_uvcheck_mesh()`/`render_uvcheck_mesh()`, P3N3T2: `normal.x` = +distortion, `tex_coord` = uv), pulled forward with a polygon offset. **Checker** samples a procedural +checkerboard at the layer's uv (per-vertex for LSCM/ViewProjected, in-shader triplanar otherwise) - +squares that stay square mean low distortion. **Distortion** colours each triangle blue->green->red by +`log2(uv_area / surface_area)` centred on the patch's *median* stretch (so a globally-scaled unwrap +reads as uniformly ideal and only relative stretch shows), averaged to vertices. A separate **Show mesh +wireframe** toggle draws the whole volume's triangle edges, rebuilt only when the vertex count changes +(not per stroke). + +### Tiling + +`DecodedHeightTexture::sample(uv, tile_enabled, tile_method)`. Two tile methods when enabled +(Repeat, MirroredRepeat). **When `tile_enabled` is false, sampling outside `[0,1)` returns `0` +directly** rather than clamping the *coordinate* into range, which would smear the border row/column of +pixels outward to infinity in every direction (streaky lines radiating out from the painted patch). + +### Subdivision - two modes + +**Uniform (`subdivide_mesh_uniform()`)** - whole-mesh, 1-to-4 split. Recursive edge-midpoint split with +a shared per-pass midpoint cache (keyed by sorted vertex-index pair) so triangles sharing an edge get +the *same* new vertex - capped at `max_iterations` (default 6). Whole-mesh so it never leaves a +T-junction, at the cost of densifying everywhere. Wired as a "Subdivide steps" slider (**0-5**, 0 = +no subdivision), Apply snaps back to 0. Drops texture-displacement paint (no remap) via the standard +`save_painting()`/`set_mesh()`/`restore_painting()` dance; the other four channels are remapped. + +**Adaptive (`subdivide_mesh_adaptive()`)** - refine **only the painted area**, by **Rivara longest-edge +bisection**, which is *conformal by construction*. Only **terminal** edges are ever bisected - an edge +that is the longest edge of *every* triangle sharing it - which splits both those triangles along one +shared midpoint at once, so a hanging node is never created. The edge to split for a triangle that wants +refining is found by **longest-edge propagation (LEPP)**: walk to the longest edge of ever-longer-edged +neighbours until a terminal one is reached, and bisect that. Edge length strictly increases along the +path (ties broken by mesh-vertex key, which both sides of an edge compute identically), so the walk +cannot cycle, and Rivara's result is that repeating it refines the original triangle in a bounded number +of bisections. The transition triangles it pulls in just outside the painted patch are the graded band +that makes the size change conformal. + +The win: a small decal on a big model no longer quadruples the *whole* model's triangle count. + +**Run to completion, worst-first, against a triangle budget.** The refinement loop is not a fixed number +of sweeps: it holds every triangle that is over its criteria in a max-heap keyed by *how many times over* +it is, pops the worst, walks its LEPP, bisects, and re-scores. Edge adjacency (`nb[e]`, the triangle +across each edge) is built **once** and maintained incrementally through each bisection, so the cost +scales with the refined region rather than with the whole model. `max_triangles` is the only bound; +stopping on it leaves a perfectly valid, still-conformal mesh that spent its budget on the largest +errors. A fixed sweep count instead spends itself grading the *coarse surroundings* - whose edges are +the longest, so they win every terminal-edge contest - and never reaches the painted patch. + +**It carries the paint forward**, which is what makes it usable (uniform subdivide drops paint). Because +the refinement is *driven by* the paint, the remap is trivial: `subdivide_mesh_adaptive()` fills an +`out_source[new_tri] = input_tri` map (children inherit their parent), and the gizmo rebuilds each +layer's mask on the new mesh - a new triangle is painted iff its source was fully painted in that +layer. `collect_paint_region()` derives both: +- the union refine-region: **exactly** the original triangles the brush touched, read straight off + `TriangleSplittingData::triangles_to_split` (`serialize()` records an entry per original triangle that + is either split - i.e. partially painted, the patch boundary - or carries a non-default state). No + dilation: marking every triangle that shares a *vertex* with the patch drags in a whole fan of huge + unpainted neighbours and refines *those* down to the resolution floor, since the height field the + detail test samples is not restricted to the painted area. The conformal closure already grades the + size change outward on its own. +- the per-layer fully-painted-triangle sets (a `get_facets_strict(ENFORCER)` sub-triangle with all three + *original* vertex indices == a whole, fully-painted original triangle; a partial stroke's sub-triangles + always carry a split vertex). + +The other four channels ride the normal `restore_painting()` remap. + +Both modes share the gizmo's Preview/Apply/Done flow; the **"Only painted area (adaptive)"** checkbox +picks the mode, and the adaptive preview follows the paint live (`rebuild_preview()` refreshes the +wireframe while the subdivide preview is open in adaptive mode). The panel shows the previewed triangle +count. + +**Feature-adaptive (follow texture detail).** A sub-mode of adaptive (the **"Follow texture detail"** +checkbox) that puts triangles where the *displaced surface actually bends*, not evenly. A flat region or +a linear **ramp** needs no extra vertices (linear interpolation is exact for a ramp); what needs them is +**curvature** - the *second* derivative, not the gradient. So the extra predicate is a **chord-error** +test: sample the combined displacement at the triangle's three edge midpoints *and its centroid* +(sampling the interior is what catches a hill sitting inside a triangle, the blind spot of an edge-only +test) and take the largest departure from the flat triangle's barycentric interpolation. Refine while +that exceeds `chord_tolerance_mm` ("Detail (mm)"). Zero chord error on a ramp => untouched; high on a +hill/ridge/noise => refined until captured. Same conformal machinery, so still crack-free. The +per-triangle error is cached and recomputed only for the children of a split. + +Four knobs bracket it, and all four matter: +- **"Max edge (mm)"** (`target_edge_length_mm`) is a **baseline that applies in feature mode too**. + Without it the chord test aliases: a big triangle over a fine pattern can sample four points that all + land at similar heights, report no error, and stall before refinement ever starts. The baseline + guarantees a sampling density fine enough for the curvature test to see the texture at all. +- **"Detail (mm)"** is the chord tolerance above. +- **"Min edge (mm)"** is a hard floor under both, and is what guarantees termination across a sharp + texture *step*, where the error never falls however fine the mesh gets. +- **"Added triangles (k)"** is the budget, passed as `max_triangles` (the model's own triangle count plus + the slider, so the control still means something on an already-dense model). + +The height field is `make_combined_displacement_sampler()` - it mirrors `build_texture_displacement()`'s +per-layer setup (decode, patch centroid, cylinder axis, blend order, "lowest layer folds additively") +but evaluated per point. Two deliberate simplifications, both erring toward *more* detail (safe - +over-refinement is never a crack): every sampleable layer is sampled at every point (no per-point paint +test), and edge-smoothing falloff is ignored. The first is *why* the refine region must not be dilated - +outside the paint the sampler still reports full relief. **LSCM layers are skipped** (no per-point UV); a +purely LSCM stack yields a null sampler and the code falls back to the length baseline alone. Per-vertex +heights are sampled lazily, so a small patch on a huge model never pays for the rest of it. + +### Fast preview (GPU-only, no CPU meshing) + +`resources/shaders/{110,140}/texture_displacement_shaded.{vs,fs}`, registered as +`"texture_displacement_shaded"`. Shades the *displaced* surface without moving geometry - active-layer +only, selected from the View row, and the default when the gizmo opens (`m_use_shaded_preview = true`). +Vertex format is `GLModel::Geometry::EVertexLayout::P3N3T2`: `normal.x` carries the per-vertex paint +weight (0/1), `normal.y` flags the UV island currently being dragged, and `tex_coord` carries a +precomputed texture UV, so it can use `GLModel` normally instead of a hand-rolled VBO/VAO manager. + +The mesh is **flat** (vertices not shared between triangles): every corner of a painted triangle gets +weight 1, every corner of an unpainted one weight 0. A coarse mesh needs that - one painted face of a raw +cube has no strictly-interior vertex, so per-vertex weighting would either bleed onto the neighbours or +vanish outright. Duplicating vertices costs no shading quality here because the shader takes its surface +normal from screen-space derivatives of position, not from a per-vertex normal. + +**Both preview meshes work in the patch's vertex space, not the mesh's.** Those agree only until a +*brush* stroke splits a triangle: `get_facets_strict()` then appends the split vertices, so the patch +array is longer. `rebuild_shaded_preview_mesh()` and `rebuild_uvcheck_mesh()` therefore index +`patch.vertices` throughout. The weight buffer is rebuilt at the same cadence as the true-displacement +preview (stroke-end/slider-release) but from the **live** `TriangleSelector` state, not the flushed model +facets, so it does not lag by a full model round-trip. + +The perturbed normal is the analytic one for a height field `H = +/-depth_mm - h(uv)` displaced along +`N` over any orthonormal surface tangent pair `T`/`B`: + + N' = normalize(N - (dH/da)-T - (dH/db)-B), a = dot(p,T), b = dot(p,B) + +The two slopes have to be genuine **mm-per-mm** derivatives for the preview's apparent depth to match +the bake's. + +**Two projection paths (`use_vertex_uv` uniform):** +- **Triplanar (`use_vertex_uv = 0`)** - `uv` and the `T`/`B` axes are both derived in-shader from + the dominant normal component, mirroring `project_planar()`/`apply_uv_transform()`, and the slope is + formed analytically. `T`/`B` are the projection's axis-aligned pair, exact only when the face is + axis-aligned; the shader drops the along-normal component to keep the gradient in the surface. Here + one `uv` unit is exactly `tiling_scale` mm, so the `1/tiling_scale` gradient factor is right. +- **Precomputed UV (`use_vertex_uv = 1`, used for LSCM and ViewProjected)** - `uv` comes per-vertex from + the CPU (`compute_layer_vertex_uvs()`, so island placement + tiling/rotation/offset are already folded + in), and the perturbed normal is built with **Mikkelsen's method** ("Bump Mapping Unparametrized + Surfaces on the GPU"): the surface gradient taken directly from the screen-space derivatives of the + *sampled height* and position. **This makes no uv->mm scale assumption**, which is essential, because an + LSCM map is **conformal, not isometric**: it is globally area-scaled but the *local* mm-per-uv varies + across the chart, so a single global `1/tiling_scale` factor gets the apparent depth wrong. `dFdx(h)` + captures the true on-screen rate of change however the chart is stretched. This path is also what makes + the fast preview follow the UV editor: move an island and its uv - hence its shading - moves with it + (the mesh rebuilds on drag-end, `on_island_edited(finished)` -> `rebuild_preview()` -> + `rebuild_shaded_preview_mesh()`). The branch is uniform and the paint weight gates by multiply, so the + texture derivatives stay well defined. A triangle straddling a seam has a discontinuous uv -> the + `det~0` guard skips it (a localised preview-only artifact, never in the bake). + +**Parallax (triplanar path).** Perturbing the shading normal alone welds the pattern to the base surface: +it does not slide as the camera orbits, and does not get deeper as `depth_mm` grows. The triplanar path +therefore shades at the point the *displaced* surface would show at this pixel, found by **ray marching** +(parallax occlusion mapping). A point at ray parameter `s`, i.e. `P + V-s` (`P` the base point, `V` the +unit direction to the eye), sits at height `s-dot(V,n)` above the undisplaced surface. The displaced +surface lives in a shell between the extreme values of `amp-(h - midlevel)` - taken from both ends of +`h in [0,1]`, so it holds for an inverted layer and a raised midlevel too, where the surface sits *below* +the undisplaced one. The march starts at the top of that shell, where the ray is outside the surface by +construction, and steps inward until the ray height drops below the sampled height. That crossing *is* +the visible point. + +Solving `Q = P + V-(H(Q)/dot(V,n))` by fixed-point iteration instead is geometrically exact but the +divisor goes to zero edge-on; the sample then lands a large fraction of a tile away and the iteration +oscillates, which reads as a second, flat copy of the pattern ghosted over the real one. Clamping the +step to one tile does not help - a tile-sized shift lands on the neighbouring tile, the same pattern +again. Offset limiting (stepping along the tangential part of `V`) is stable but understates parallax +enough that the relief still flattens as soon as the camera tilts. Marching has neither problem. + +The hit is interpolated between the last two samples, which keeps `PARALLAX_STEPS` (24) affordable, and +the whole march is skipped when sweeping the shell would move the sample point less than half a texel - +the head-on case, so the common view pays almost nothing. The 140 variant samples with +`textureLod(..., 0.0)` inside the loop, since implicit derivatives are undefined in non-uniform control +flow. Two uniforms exist for this: `midlevel` (parallax needs the real height, not just its derivative) +and `eye_model_pos` (the camera in the volume's local frame). + +Parallax cannot change the model's silhouette or cast shadows; the View row's Normal mode is one click +away for that. The LSCM path stays plain Mikkelsen normal perturbation - it has no closed-form uv, so there is no cheap +way to re-project a marched position. One further approximation: the GPU sampler's wrap mode stands in +for `tile_enabled`/`tile_method`, so with tiling *off* the GPU repeats where the CPU returns 0 outside +`[0,1)`. + +### On-canvas "Adjust Texture" gizmo + +A per-active-layer toggle ("Adjust placement") that disables painting and shows a flat pan panel (free +2D drag on both axes) plus two arrows along the patch's own U/V axes (constrained single-axis drag). +Anchored to the painted patch's centroid/average-normal (`compute_layer_paint_anchor()`). Hit-testing is +screen-space distance/point-to-segment, not real 3D ray intersection against the handle geometry - simple +and good enough at this handle size. + +### Projection frame overlay (ViewProjected) + +`src/slic3r/GUI/TextureProjectorFrame.hpp/.cpp` - a semi-transparent, resizable `wxFrame` the user +drags **over the 3D view**, like a slide projector's gate. Whatever the model shows through it is what +the texture is projected onto, and the window's border becomes the hard edge of the displacement. +Press **Apply projection frame** and the gizmo reads the window's rectangle and commits it. + +The window is deliberately **dumb**: it owns no placement state and reports nothing continuously. Its +position and size *are* the placement, read on demand at Apply - which is also when the expensive +visible-facet raycast runs. So dragging it is free and nothing recomputes until asked. + +Plain 2D (`wxPaintDC`), not a `wxGLCanvas`: a second GL canvas would have to share the app's one real +`wxGLContext`. It only ever draws a bitmap and a border. + +**The projective mapping (`apply_projection_frame()`)**. The frame defines a **screen-space** rectangle, +but the bake samples from a **local-space** position, so the two have to be reconciled. +`view_project_right/up` can only express an *affine* projection - exact under an orthographic camera, but +wrong under perspective, where the near end of a part projects larger than the far end and no pair of +axes reproduces that. So the layer instead stores a full projective map (`view_project_matrix`, row-major +3x4, `uv = (row0-p/row2-p, row1-p/row2-p)`), built like this: + +- `K = projection - view - (instance - volume)`, i.e. local -> clip, the same product the renderer uses. + Note `Camera::get_projection_matrix()` is typed `Transform3d` (nominally affine) but its perspective + form explicitly writes a `(0, 0, -1, 0)` bottom row into the underlying 4x4, so `clip.w = -z_eye` is + genuinely carried. The build therefore multiplies **`.matrix()` products** (plain `Matrix4d`), never + `Transform3d` products, which would not compose that row correctly. +- Window coordinates follow `igl::project`'s convention (as `CameraUtils::project` does), with y + measured downward. Writing `uv = (win - rect_origin) / rect_size` makes u and v affine in + `ndc = clip.xyz / clip.w`; multiplying through by `clip.w` leaves a plain linear combination of `K`'s + rows, which is exactly the 3x4 matrix - the perspective divide survives intact. +- `w > 0` is checked rather than divided blindly. A point behind the projector has `w < 0` and divides + to a plausible-looking but **mirrored** uv - the classic way a projected decal reappears on the back + of a model. `project_uv_projective()` returns false there and the caller treats it as no height. + +The map already includes placement, so `apply_uv_transform()` is **not** applied on top of it - the +window's own position and size are the placement, and the tiling/rotation/offset sliders would shove +the result off the frame the user just aligned. A "Clear" button drops back to the affine path where +those controls mean something again. + +Apply also sets `tile_enabled = false`, so `DecodedHeightTexture::sample()` returns 0 outside `[0,1)` +and the border is a hard edge rather than the first seam of an endless repeat, and repaints the layer +via `select_visible_faces(&matrix)` - the frame's uv square clips the selection, which both matches the +paint to the border and keeps the ray queries proportional to the framed area instead of the model. + +Owned by the gizmo and **destroyed** (not just hidden) in `on_shutdown()`. Closing it only hides it, so +reopening keeps it where it was left. + +### UV Editor pane + +`UVEditorCanvas` (`src/slic3r/GUI/UVEditorCanvas.hpp/.cpp`) - a standalone `wxGLCanvas` rendering the +flattened LSCM islands (per-island wireframe + outline + fill) over the height texture (background +quad tiled across the whole unwrap), with mouse pan/zoom. It is wrapped in a **`UVEditorPanel`** +(same file) that adds a button row (Frame / Snap / Avg scale / Cut / Join / Unjoin) and a status line +along the bottom naming the current gesture and the shortcuts in play. The *panel* is what is +registered as a `wxAuiPaneInfo` pane on `Plater`'s `m_aui_mgr`; `Plater::show_uv_editor(bool)` +shows/hides it (deferred via `CallAfter`, since the gizmo calls it mid-3D-frame), and +`get_uv_editor_canvas()` returns the inner canvas the gizmo talks to. + +Deliberately **shares the app's one real `wxGLContext`** (`wxGetApp().init_glcontext(*this)`, the +same call `View3D`/`Preview`/`AssembleView` make) rather than creating an independent context like +`SkipPartCanvas` does elsewhere in this codebase - this is what lets it reuse the already-registered +`"flat"`/`"flat_texture"` shaders and `GLModel` as-is, instead of needing its own shader +compilation/VBO management. + +**Geometry is uploaded once, in the unwrap's own (raw, mm) coordinates**, one `GLModel` set per island; +each island is then drawn through its own 2x3 affine (`island_transform_matrix()` composed with the +layer's tiling/rotation/offset) passed as the `flat` shader's `view_model_matrix`. A drag updates one +matrix per island and touches no vertex buffer - `on_island_edited(!finished)` calls only +`set_island_transforms()`, and the full `set_islands()` rebuild happens solely when the unwrap itself +changes (`unwrap_changed` in `update_uv_editor()`). + +**Gestures** (canvas-owned, reported to the gizmo as incremental deltas via `IslandEditFn`): left-drag += move, right-drag or **R** = rotate (hold **Shift** to snap to 15° steps - quantised on the +*cumulative* rotation, not each delta, so it doesn't judder, and accumulated incrementally so it +survives crossing +/-180°), **S** = scale (R/S modal, click/Enter to confirm, Esc to cancel), wheel = +zoom about the cursor, middle-drag = pan, **Home**/**F** = frame all. Scale writes +`TextureIsland::scale`; "Avg scale" (`average_island_scales()`) sets every island to the mean, so +one island scaled by hand can be matched back to its neighbours' texel density. **Snap** (canvas-owned +`m_snap_enabled`, toggled from the toolbar) sticks a dragged island's nearest boundary vertex onto a +neighbouring island's at drag-*end* only - a magnet that re-applies mid-drag is very hard to pull out +of. Toolbar commands the canvas can't service itself (Avg scale, Cut, Join, Unjoin) are forwarded to the +gizmo via `CommandFn`; view-only ones (Frame, Snap) it handles directly. + +## File map + +**libslic3r (core, no GUI dependency):** +- `src/libslic3r/TextureDisplacement.hpp/.cpp` - data model, bake algorithm, projection methods, + tiling, subdivision (uniform + adaptive longest-edge bisection), post-process smoothing + (`smooth_mesh_vertices()`), and `TextureDisplacementOptions` (the whole-stack settings). See doc + comments throughout, they're kept accurate and up to date. +- `src/libslic3r/MeshBoolean.hpp/.cpp` - `parameterize_lscm()` and `remesh_isotropic()` in the `cgal` + sub-namespace, reusing the existing `CGALMesh`/`_EpicMesh`/conversion-helper infrastructure already + there for mesh boolean ops. CGAL includes: `Polygon_mesh_processing/border.h`, + `Polygon_mesh_processing/connected_components.h`, `Surface_mesh_parameterization/{Error_code, + LSCM_parameterizer_3, parameterize}.h`. No new dependency - CGAL 5.6.3 is already vendored and the + `Surface_mesh_parameterization` package headers were already present. +- `src/libslic3r/Model.hpp/.cpp` - the 8 named `FacetsAnnotation` fields + accessor, + `texture_displacement_layers`, `texture_displacement_options`, and all the mirrored touch points + (see Data model above). + +**GUI:** +- `src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp/.cpp` - the gizmo and its whole panel. +- `src/slic3r/GUI/TextureLibrary.hpp/.cpp` - scans the shipped + user texture folders, imports an + arbitrary image into the user folder (converting it to the 8-bit grayscale PNG libslic3r decodes), + and loads a library file's bytes for a layer. The image->grayscale-PNG conversion lives here, on the + GUI side, because libslic3r has no image toolkit; both the import path and the "pick a shipped + texture" path go through the same one function. +- `resources/textures/displacement/*.png` - the 10 shipped height maps (Bricks, Grid, Hexagons, + Knurl, Noise, Quilt, Studs, Waves, Weave, Wood Grain). All 512x512 8-bit grayscale and **seamless** + (each is periodic over the full image in both axes, so tiling shows no seam). Generated + procedurally; the whole `resources/` tree is installed recursively by CMake, so a new folder under + it ships with no build-system change. +- `src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp/.cpp` - background bake commit. +- `src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp/.cpp` - background preview compute + (mirrors the bake job's shape but commits nothing to the Model). +- `src/slic3r/GUI/TextureProjectorFrame.hpp/.cpp` - the semi-transparent projection-frame overlay for + ViewProjected layers (plain 2D `wxPaintDC`, no GL context - see its section above). +- `src/slic3r/GUI/UVEditorCanvas.hpp/.cpp` - the 2D UV unwrap viewer widget. +- `src/slic3r/GUI/Plater.hpp/.cpp` - `uv_editor_canvas` member, AUI pane registration, + `get_uv_editor_canvas()`/`show_uv_editor()`. +- `src/slic3r/GUI/GLShadersManager.cpp` - registers `"texture_displacement_shaded"`. +- `resources/shaders/{110,140}/texture_displacement_shaded.{vs,fs}` - the fast-preview shader. +- `src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp` - `PainterGizmoType::TEXTURE_DISPLACEMENT`. +- `src/slic3r/GUI/Gizmos/GLGizmosManager.hpp/.cpp` - `EType::TextureDisplacement` registration. + +## Tests + +`tests/libslic3r/test_texture_displacement.cpp`. Covers `decode_height_texture` round-trip, empty-layer +no-op, full-cube uniform displacement, a second layer over the same area contributing, all four blend +modes (table-driven), the lowest layer ignoring its blend mode, border displace/pin, post-process +smoothing and its mask guarantees, and adaptive subdivision: conformality (`every_edge_used_twice` on a +partially-refined cube - an exact crack detector for a closed mesh), the target edge length actually +being reached, the triangle budget capping the result without opening a crack, curvature-driven +refinement (a Gaussian hill refines at its centre, a linear ramp adds nothing), and the max-edge +baseline. + +`BUILD_TESTS` is `OFF` in the checked-in build cache; flip it on to run them: + + cmake -S . -B build -DBUILD_TESTS=ON + cmake --build build --config Release --target libslic3r_tests -- -m + ./build/tests/libslic3r/Release/libslic3r_tests.exe "[TextureDisplacement]" --order rand diff --git a/TEXTURE_DISPLACEMENT_GUIDE.md b/TEXTURE_DISPLACEMENT_GUIDE.md new file mode 100644 index 0000000000..5abc9b94e2 --- /dev/null +++ b/TEXTURE_DISPLACEMENT_GUIDE.md @@ -0,0 +1,326 @@ +# Texture Displacement - Feature & Controls Guide + +Texture Displacement is a paint-style gizmo that stamps height-map textures onto a model's surface +and turns them into real relief - engraved or embossed detail - either as a live preview or baked +into actual mesh geometry. You paint where the texture applies, stack multiple textures as blended +layers, choose how each is projected onto the surface, and (for the unwrap projection) lay the result +out by hand in a dedicated 2D **UV Editor** pane. + +This document describes every feature and control. For the internal architecture and algorithms, see +`TEXTURE_DISPLACEMENT.md`. + +--- + +## Table of contents + +1. [Quick start](#quick-start) +2. [Entering the tool](#entering-the-tool) +3. [Selection modes](#selection-modes) +4. [View modes](#view-modes) +5. [Auto update](#auto-update) +6. [Texture layers](#texture-layers) +7. [Per-layer settings](#per-layer-settings) +8. [Projection methods](#projection-methods) +9. [The UV Editor](#the-uv-editor) +10. [Seams](#seams) +11. [Adjust placement (on-model)](#adjust-placement-on-model) +12. [Preparing the mesh: Subdivide & Remesh](#preparing-the-mesh-subdivide--remesh) +13. [Baking & resetting](#baking--resetting) +14. [Controls reference](#controls-reference) +15. [Tips & limitations](#tips--limitations) + +--- + +## Quick start + +1. Select an object and open the **Texture displacement** gizmo from the left toolbar. +2. A texture layer is added automatically. Pick a texture from the layer's picker, or import your own. +3. **Paint** the area you want the texture to affect (or press **Select whole model**). +4. The relief appears live on the model. Tune **Depth**, **Tile size**, **Rotation**, etc. +5. If the model is low-poly, use **Subdivide** or **Remesh** so there are enough vertices for detail. +6. Press **Bake** to convert the preview into real geometry, or leave it as a live preview. + +> The tool only ever affects the **painted** area. Everything you don't paint keeps its original +> surface, and bake blends the relief seamlessly into it. + +--- + +## Entering the tool + +The gizmo lives on the left gizmo toolbar (icon: `toolbar_texture_displacement.svg`). Its settings +panel opens beside the toolbar. You can **Dock panel / Undock panel** (top of the panel) to pin it or +float it freely over the 3D view, and **Close** at the bottom exits the gizmo. + +When you first open the tool on a never-textured object it starts with **one texture layer already +added**, so you can paint straight away. + +--- + +## Selection modes + +Choose *how* you paint. All three write into the **active layer's** mask. + +| Mode | What it does | +|------|--------------| +| **Brush** | Free-hand painting with a round brush. Shows a **Brush size** slider and a **Circle / Sphere** choice (circle = surface disc, sphere = 3D ball that also paints around curves). | +| **Face** | Click a single triangle to paint it. | +| **Connected area** | Click to flood-fill a region; the **Angle threshold** slider limits how far the fill spreads across changes in surface angle. | + +- **Select whole model** - marks the entire model as painted for the active layer, instead of + brushing it by hand. + +--- + +## View modes + +A row of icon buttons labelled **View** controls how the painted area is shown. The first four are a +radio group; **Wireframe** is an independent toggle. Hover any icon for its tooltip. + +| View | Meaning | +|------|---------| +| **Normal** | The true displaced geometry - exactly what **Bake** produces. Rebuilt in the background. | +| **Fast** | A GPU shaded approximation of the *active layer only*. No real geometry movement - quick to update, not exact. Best while tuning or dragging islands. | +| **Checker** | A test grid painted over the unwrap so you can see stretching (squares stay square where the map isn't distorted). | +| **Distortion** | A blue->green->red heatmap of how much each area is compressed or stretched in UV space. Needs the **Unwrap (LSCM)** projection. | +| **Wireframe** | Overlays the mesh edges (white). Independent of the view above; in **Normal** view it sits on the displaced surface. | + +--- + +## Auto update + +**Auto update** (on by default) rebuilds the true displaced geometry as soon as *anything* changes - +painting, swapping textures, moving sliders. Turn it off on very heavy models to only rebuild when you +release a slider (painting still updates on stroke end). + +--- + +## Texture layers + +You can stack up to **8** texture layers. Each has its own independent paint mask, its own texture, +and its own parameters, and they combine in slot order like layers in an image editor. + +- **Add a layer** - the **+ icon** to the right of the *Texture layers* heading (reuses the tool icon + for now). +- **Remove** - the button on each layer's header row. +- **Active layer** - click a layer's header (or anywhere in its block) to make it active. The active + layer is the one you paint into and the one whose block is tinted. Only one layer is active at a time. +- **Erase all** - clears the active layer's paint. + +Each layer shows a texture **picker** (large preview + name). Open it to choose from the shipped +library or import your own image (any png/jpg/bmp; it's converted to an 8-bit grayscale height map and +copied into your user texture folder so app updates can't overwrite it). + +--- + +## Per-layer settings + +| Control | Range / options | What it does | +|---------|-----------------|--------------| +| **Depth (mm)** | 0.01-10 (log) | Maximum displacement along the surface normal. | +| **Tile size (mm)** | 0.2-200 (log) | Physical size of one texture tile on the surface. | +| **Rotation** | 0-360° | Rotates the texture on the surface. | +| **Midlevel** | 0-10 | The grey level that means "don't move". At 0 the texture only pushes outward; raise it and darker texels cut *inward* (one map both embosses and engraves). 0.5 makes mid-grey neutral. | +| **Smoothing** | 0-1 | Blurs the height texture before it displaces - rounds hard edges and removes speckle without needing a softer source image. | +| **Edge smoothing** | checkbox + **Edge amount** 0-1 | Fades the relief to flat toward the *edge of the painted area*, so it blends into the surrounding surface. A small amount softens only a thin band at the very edge; the maximum flattens the whole painted face. | +| **Invert** | checkbox | Flips the height map (peaks become valleys). | +| **Blend** | Add / Subtract / Multiply / Divide | How this layer combines with the layers **below** it where they overlap. Add/Subtract pile relief on or carve it away; Multiply/Divide scale the relief underneath (a mask). The lowest painted layer is the **Base** and always behaves additively. | +| **Tile** | checkbox + **Repeat / Mirrored repeat** | When off, the texture is placed once (a decal) instead of repeating. Mirrored repeat flips every other tile to hide seams. | +| **Projection** | see below | How the texture is mapped onto the painted surface. | + +> **Midlevel warning:** cutting inward can fold the surface through itself in sharp concave corners or +> thin walls. Keep Depth small relative to the feature you're cutting into; the panel warns when a deep +> inward setting is risky. + +--- + +## Projection methods + +How the 2D texture is wrapped onto the 3D painted area. + +| Method | Best for | Notes | +|--------|----------|-------| +| **Triplanar (blended)** | Patches wrapping around edges | Projects from all three axes at once and blends, so there's no seam across a sharp edge. | +| **Cylindrical** | Round, tube-like selections | Wraps the texture around the patch's own centre/axis. | +| **Spherical** | Ball-like selections | Longitude/latitude wrap around the patch centre. | +| **Unwrap (LSCM)** | Flat, controlled layout | A real conformal unwrap. Cuts the area into pieces at sharp edges (see **Seam angle**), flattens each, and lets you lay them out by hand in the **UV Editor**. Unlocks Checker/Distortion, seams, and island editing. | +| **From view** | Decals / slide-projector look | Projects straight onto the surface from the current camera direction. Use **Capture current view** to re-lay it from wherever you're looking. | + +### LSCM-only controls + +These appear when a layer uses **Unwrap (LSCM)**: + +- **Seam angle** (5-90°) - edges sharper than this are cut so each piece lies flat. Lower cuts more + (less stretching, more seams); raise to keep more in one piece. A box's 90° corners are cut by + default. *Ignored once you've marked any seam by hand* (your seams then define the pieces). +- **Connect islands** (on by default) - lays the unwrap out as a **connected net**: pieces that share + an edge are unfolded next to each other (a cube becomes a joined net instead of six loose squares). + They stay separate islands, so you can still move any of them by hand. Turn off for the classic + packed-grid layout. +- **Open UV editor** - shows the flattened unwrap in a side pane (see below). Opens *only* when you + turn this on - it never pops up on its own. +- **Mark seams** / **Path** / **Clear seams** - see [Seams](#seams). +- An **Unwrap: N islands, F faces, V verts** read-out tells you what the unwrap actually produced. + +--- + +## The UV Editor + +A dockable 2D pane (enable **Open UV editor** on an LSCM layer) showing the flattened unwrap over the +height texture. Islands are the flattened pieces; you can rearrange them freely - nothing re-packs them +behind your back. Moving an island updates the model **live** (in Fast view it tracks the cursor +smoothly, via a shader uniform - no rebuild until you release). + +### Navigation + +| Action | Control | +|--------|---------| +| Pan | Middle-drag | +| Zoom | Mouse wheel (zooms about the cursor) | +| Frame everything | **Home** or **F**, or the **Frame** toolbar button | + +### Editing an island + +| Action | Control | +|--------|---------| +| Select | Left-click an island | +| Move | Left-drag | +| Rotate | Right-drag, or press **R** then move the mouse (click/Enter to confirm, Esc to cancel) | +| Rotate snapped | Hold **Shift** while rotating - snaps to **global** 15° marks (0/15/30...). A protractor dial with tick marks and the current angle is shown. | +| Scale | Press **S** then move the mouse (click/Enter to confirm, Esc to cancel) | +| Undo / Redo | **Ctrl+Z** / **Ctrl+Shift+Z** or **Ctrl+Y** | + +The **selected** island gets a bold light-green outline and a brighter wireframe; unselected islands +are a translucent light-green wash. The texture underneath repeats exactly as it will when baked. +A **status line** along the bottom always names the current gesture and the shortcuts in play. + +### Toolbar + +| Button | Action | +|--------|--------| +| **Frame** | Frame all islands (same as Home). | +| **Snap** | Toggle magnetic snapping - a dragged island sticks its boundary to a neighbour's when they come close. | +| **Avg scale** | Give every island the same texel density (Blender's "Average Islands Scale"). | +| **Cut** | Split the selected island across its long axis (useful for very long islands). | +| **Join** | Unfold the selected island onto its nearest neighbour along their shared edge - keeps both as separate islands with their own borders. | +| **Unjoin** | Send the selected island back to its own packed position. | + +> **Checker / Distortion in the UV editor:** selecting those View modes also colours the UV pane - a +> checker background, or a per-island distortion heatmap - so you can judge stretch in 2D as well as +> on the model. + +--- + +## Seams + +Seams are edges the unwrap is forced to cut along, on top of whatever the Seam angle cuts - the +Blender "mark seam" workflow. They let you control exactly where the unwrap splits. + +Enable **Mark seams** on an active LSCM layer, then: + +- **Click an edge** on the model to mark it (it turns **red**); click a red edge again to unmark it. + The edge under the cursor is highlighted **yellow** so you can see what a click will toggle. +- **Path mode** (the **Path** checkbox) - for dense meshes where clicking each edge is tedious: click a + start point, then an end point, and the whole **shortest path** between them is seamed at once. It + chains (each click extends from the last point); the start vertex is shown in **green**. +- **Ctrl+drag** rotates/pans the camera while in seam mode. +- **Clear seams** removes them all. + +Once any seam is marked, the automatic Seam-angle cutting is disabled so *your* seams define the +islands - pieces you leave un-seamed merge together. + +--- + +## Adjust placement (on-model) + +**Adjust placement** (on an active layer) lets you position the texture by dragging a handle on the +model instead of nudging the Rotation/offset numbers. The handle is a flat panel in the patch's +tangent plane (drag anywhere on it to move freely) plus U/V arrows for single-axis nudges. It's +anchored to the painted patch, so paint something first. + +--- + +## Preparing the mesh: Subdivide & Remesh + +Displacement can only move vertices that exist, so a coarse model needs more of them first. + +### Subdivide + +Splits every triangle into four, **1-5 times** (each step roughly quadruples the triangle count). + +- **Subdivide steps** (1-5) - how many times to split. +- **Preview subdivision** - shows the result as a **cyan wireframe** without changing the model. +- **Apply** - commits the subdivision to the geometry. +- **Done** - ends the preview and leaves the model as it is. + +### Remesh + +Rebuilds the whole model with triangles close to a target edge length - evens out a mesh with wildly +varying triangle sizes (CGAL isotropic remeshing). + +- **Target edge (mm)** - desired triangle edge length (seeded to the model's current average). +- **Remesh** - splits the big triangles and merges the small ones to that size. + +> Both Subdivide-Apply and Remesh **replace the geometry** and clear any *not-yet-baked* paint on it +> (already-baked relief is kept). If you had the mesh **Wireframe** on before, it stays on afterward. + +--- + +## Baking & resetting + +- **Bake** - converts the current preview into real, permanent mesh geometry, restricted to the + painted area. Runs in the background; the button shows *Baking...* while it works. +- **Erase all** - clears the active layer's paint. + +Baking is the exact same algorithm as the **Normal** preview, so what you see is what you get. + +--- + +## Controls reference + +### Mouse - 3D view (while painting) + +| Input | Action | +|-------|--------| +| Left-drag | Paint the active layer | +| Ctrl + drag | Rotate / pan the camera (works in seam mode too) | +| Wheel | Zoom | + +### Mouse & keys - UV Editor + +| Input | Action | +|-------|--------| +| Left-click | Select island | +| Left-drag | Move island | +| Right-drag | Rotate island | +| **R** / **S** | Modal rotate / scale (mouse drives it, click or Enter confirms, Esc cancels) | +| **Shift** (while rotating) | Snap to global 15° marks | +| Middle-drag | Pan | +| Wheel | Zoom about cursor | +| **Home** / **F** | Frame all islands | +| **Ctrl+Z** / **Ctrl+Shift+Z** / **Ctrl+Y** | Undo / redo | + +### Seam mode + +| Input | Action | +|-------|--------| +| Click edge | Mark / unmark a seam (yellow = hover, red = marked) | +| Click (Path mode) | Set start, then seam the shortest path to the next click | +| Ctrl + drag | Rotate / pan camera | + +--- + +## Tips & limitations + +- **Paint first, then bake.** The preview is free to explore; only Bake changes the real mesh. +- **Not enough detail?** Subdivide or Remesh before painting fine textures. +- **Inward cuts** (high Midlevel + big Depth) can self-intersect on thin walls or sharp concave + corners - keep Depth modest there. +- **Fast vs Normal:** Fast preview only shades the relief and shows only the active layer; use it for quick + tuning and smooth UV dragging, but trust **Normal**/**Bake** for the exact result. +- **Topology changes drop unbaked paint.** Subdivide-Apply, Remesh, and Simplify replace the mesh, and + texture-displacement paint isn't remapped across that change (already-baked relief is unaffected). +- **Island placements** are tied to the current unwrap. Re-painting or changing the Seam angle can + re-segment the charts and renumber them, so a re-unwrap re-lays the connected net and discards + hand placements made before it. +- **Connect islands** is on by default; turn it off (per layer) for the classic packed-grid layout, or + if an unfold looks wrong on an unusual mesh. diff --git a/deps/OCCT/OCCT.cmake b/deps/OCCT/OCCT.cmake index 45263d6ae3..e1a65beef7 100644 --- a/deps/OCCT/OCCT.cmake +++ b/deps/OCCT/OCCT.cmake @@ -24,7 +24,7 @@ endif() # On macOS/Linux OCCT links statically, so an unreferenced toolkit costs build time and no # shipped bytes. The Windows figure is a real DLL cost and has NOT been measured -- an # earlier "3.77 MiB, Windows only" note here covered only two of the three toolkits and is -# not a number to quote. See docs/cad_dependency_weight.md. +# not a number to quote. See docs/HLSD/design-tab.md. if (IN_GIT_REPO) set(OCCT_DIRECTORY_FLAG --directory ${BINARY_DIR_REL}/dep_OCCT-prefix/src/dep_OCCT) diff --git a/deps/python3/python3.cmake b/deps/python3/python3.cmake index 3e063fac4e..6b4443ef3a 100644 --- a/deps/python3/python3.cmake +++ b/deps/python3/python3.cmake @@ -151,6 +151,12 @@ elseif(APPLE) # the post-install -add_rpath below. set(_python_ldflags "${_python_arch_flags} -Wl,-headerpad_max_install_names") + # The macOS 27 SDK declares pipe2() and dup3() as available from macOS 27, so + # configure finds them and CPython 3.12 calls them without a runtime check. + # Below a macOS 27 deployment target they are weak-linked and resolve to NULL + # on older systems, where os.pipe() then segfaults -- in `make install` + # (compileall, ensurepip) and in the shipped app alike. Every configure below + # keeps the pipe()/dup2() fallbacks (python/cpython#153711). if(IS_CROSS_COMPILE) set(_python_build_tgt --build=${_python_build_arch}-apple-darwin --host=${_python_host_arch}-apple-darwin) set(_python_build_arch_flags "-arch ${_python_build_arch_flag} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") @@ -174,7 +180,8 @@ elseif(APPLE) --enable-shared \ --without-static-libpython \ --disable-test-modules \ - --build=${_python_build_arch}-apple-darwin && \ + --build=${_python_build_arch}-apple-darwin \ + ac_cv_func_pipe2=no ac_cv_func_dup3=no && \ make -j${NPROC} python && \ cd '' && \ env \ @@ -191,6 +198,7 @@ elseif(APPLE) --without-static-libpython \ --with-openssl='${DESTDIR}' \ --disable-test-modules \ + ac_cv_func_pipe2=no ac_cv_func_dup3=no \ ${_python_build_tgt} \ --with-build-python='${_python_build_python}' \ py_cv_module__tkinter=n/a" @@ -213,6 +221,8 @@ elseif(APPLE) --with-openssl=${DESTDIR} --disable-test-modules ${_python_build_tgt} + ac_cv_func_pipe2=no + ac_cv_func_dup3=no # Tcl/Tk 9.0 (e.g. from Homebrew) is incompatible with CPython 3.12's # _tkinter; OrcaSlicer's embedded Python does not need tkinter anyway. py_cv_module__tkinter=n/a diff --git a/docs/CAD/GAP_ANALYSIS_vs_ONSHAPE.md b/docs/CAD/GAP_ANALYSIS_vs_ONSHAPE.md deleted file mode 100644 index bf603cf2c1..0000000000 --- a/docs/CAD/GAP_ANALYSIS_vs_ONSHAPE.md +++ /dev/null @@ -1,160 +0,0 @@ -# Orca-CAD vs Onshape — capability gap analysis - -Generated 2026-07-22 by enumerating the source, not from recollection: -`CadFeatureType` and `add_*` in `src/libslic3r/CAD/CadDocument.hpp`, `Tool` in -`src/slic3r/GUI/CAD/DesignPanel.hpp`, `Mode` in `src/slic3r/GUI/CAD/DesignSketchTool.hpp`, -`SketchConstraintType` + `SketchEntity::Type` in `src/libslic3r/CAD/SketchEngine.hpp`, -and the JSON-RPC dispatch in `src/slic3r/GUI/CAD/McpControl.cpp`. - -**Scope note.** Onshape is a cloud PLM platform; Orca is a Design tab inside a -slicer. A large share of Onshape's surface (release management, branching, real-time -collaboration, FEA, rendering, PDM) is out of scope by construction and is listed -separately at the bottom rather than counted as a "missing tool". - ---- - -## 1. What Orca already has - -### 2D sketcher — near parity with Onshape -This is the strongest area. Very little is missing. - -| Category | Orca | -|---|---| -| Entities | Line, Polyline, Arc (3-point / tangent / center), Circle (center / 2-point / 3-point), Point, Ellipse, Elliptical arc, B-spline | -| Shapes | Rectangle (corner / center / oblique / rounded), Slot, Arc-slot, Polygon | -| Edit ops | Fillet, Chamfer, Offset, Mirror, Trim, Extend | -| Transforms | Move, Rotate, Scale, Linear array, Polar array | -| Constraints (19) | Fix, Coincident, Horizontal, Vertical, Distance, LockX, LockY, EqualLength, Parallel, Perpendicular, Concentric, Tangent, Midpoint, Symmetric, Angle, Radius, Diameter, PointOnLine, PointOnObject | -| Dimensions | Length, Diameter, Radius, Angle, Distance, Distance-to-line | - -Solver: vendored SolveSpace (`libslvs`, GPL-3.0) — the same solver lineage as a -commercial-grade sketcher. - -### Part features - -| Present | Notes | -|---|---| -| Extrude | + up-to-face / up-to-point, taper, flip | -| Revolve | angle-arc gizmo | -| Sweep | along a path | -| Loft | multi-profile | -| Fillet / Chamfer | edge-level | -| Draft | face taper | -| Shell | wall thickness + open face | -| Hole / Thread | face-aware placement | -| Pattern | linear + circular | -| Boolean | New / Add / Cut / Intersect, with face-mating | -| Cut | plane-based, signed offset | -| Datum plane | offset / 2-face / 2-edge derived | -| Import | STEP (B-rep) + mesh→B-rep (native mesh2step port) | -| Export | STEP (native B-rep, not tessellated) | -| Multi-body | + per-body colour | -| Section view | with flip | -| Undo/redo | full feature-tree recompute | -| 3MF persistence | parametric recipe survives save/load | - -### Automation -9 MCP JSON-RPC methods: `describe_tools`, `describe_scene`, `query_topology`, -`measure`, `slice_body`, `import_step`, `import_mesh`, `validate_against`, plus -build actions `extrude`, `revolve`, `fillet`, `chamfer`, `hole`, `boolean`, `pattern`. -Onshape's equivalent is its REST API + FeatureScript. - ---- - -## 2. Missing tools — ranked by impact - -### Tier 1 — structural absences (whole subsystems) - -**1. Assemblies and mates.** Entirely absent. No assembly document, no mate -connectors, no fastened / revolute / slider / cylindrical / planar / ball / pin-slot -mates, no assembly patterns, no interference detection, no exploded views. -`bool_target_face` / `bool_tool_face` do face-to-face *mating* for a boolean, which -is geometric alignment, not a kinematic joint. -*Impact:* multi-part products cannot be positioned or validated as a mechanism. -*Note:* an MCP-side `align_instance_to_face` / `create_*_mate` vocabulary already -exists on the Onshape bridge in this workspace, so the target semantics are known. - -**2. Drawings / 2D documentation.** Absent. No drawing sheets, dimensioned views, -section/detail views, GD&T, title blocks, or BOM. -*Impact:* nothing manufacturable-by-a-third-party leaves the tool. For 3D printing -this matters less than for machining, which is the honest reason it is Tier 1 by -CAD convention but arguably Tier 3 for this product. - -**3. Variables, equations, configurations.** Absent — no `add_variable`, no -expression evaluation, no configuration table. Every dimension is a literal double. -*Impact:* this is the biggest *parametric* gap. "Make this bracket for an M4 vs M5 -bolt" requires re-editing every dependent feature by hand. Onshape's Variable -Studio + configurations are a core differentiator, and this is the cheapest Tier 1 -item to close for the size of the payoff. - -**4. Surface modelling.** Absent. No surface extrude/revolve/loft/sweep, no fill, -knit, trim/extend surface, offset surface, or thicken. Orca is solid-only. -*Impact:* organic/complex shapes and repair of imported junk geometry are impossible. -OCCT already provides all of it (`TKOffset`, `TKBRep`), so the kernel is not the -blocker — only UI and feature plumbing. - -**5. Sheet metal.** Absent. No flange, bend, tab, relief, or flat-pattern unfold. -*Impact:* arguably out of scope for an FDM slicer; listed for completeness. - -### Tier 2 — individual features with clear demand - -| Missing | Why it matters | Cheap? | -|---|---|---| -| **Mirror body** (part-level) | Sketch mirror exists; mirroring a *solid* about a plane does not. Extremely common. | Yes — OCCT `gp_Trsf` mirror + fuse | -| **Helix / spiral curve** | No helix ⇒ no springs, no custom threads, no spiral vase geometry. Sweep exists but has no helical path to sweep along. | Yes | -| **Move / rotate body as a real feature** | `m_body_xform` exists but is **display-only** (memory #1655) — it never enters the B-rep. Export/boolean see the original position. | Medium | -| **Split body** | Cut removes material; splitting one body into two independently-usable bodies is absent. Very relevant for print-in-parts. | Medium | -| **Thicken** | Solid from a surface/face offset. | Needs surfaces | -| **Rib** | Standard structural feature. | Medium | -| **Delete face / move face / replace face** | Direct/dumb-solid editing — the main tool for fixing imported STEP. Given Orca imports STEP *and* meshes, its absence is felt. | Medium | -| **Datum axis, coordinate system** | Only datum *planes* exist. Axes are needed for revolve/pattern references. | Yes | -| **Mass properties** | `GeometryEngine` computes a volume internally, but there is no volume/mass/COM/inertia readout. For print cost/time estimation this is nearly free to expose. | Yes — trivial | -| **Measure tool in the GUI** | `measure` exists over MCP but there is no interactive measure in the UI. | Yes | -| **Hole standards library** | Hole exists, but no counterbore/countersink/tapped standards (ISO/ANSI) with callouts. | Medium | -| **Project / convert edges into a sketch** | Cannot reference existing solid edges as sketch geometry ("Use" in SolidWorks). A significant sketcher gap given everything else is present. | Medium | -| **Construction geometry** | Could not confirm a construction/reference-line flag on sketch entities. | Yes if absent | -| **Curve tools** | Projected curve, bridging curve, composite curve, 3D fit spline. | Medium | -| **Pattern on curve / pattern faces** | Pattern is linear + circular of whole bodies only; no curve-driven pattern, no feature/face pattern. | Medium | -| **Wrap / emboss** | Text or sketch wrapped onto a curved face. | Hard | -| **Enclose** | Solid from bounded void regions. | Medium | - -### Tier 3 — platform capabilities (out of scope by construction) - -Version control with branching/merging, release management, real-time multi-user -collaboration, cloud PDM, FeatureScript custom-feature authoring, simulation/FEA, -photorealistic rendering, app store/integrations. These are Onshape-the-platform, -not Onshape-the-modeller. Not defects in Orca. - ---- - -## 3. Recommended priority - -If the goal is "credible parametric CAD inside a slicer", the ordering that buys -the most capability per unit of work: - -1. **Variables + expressions** — unlocks genuine parametric reuse; no new kernel work. -2. **Mass properties + GUI measure** — nearly free, immediately useful for printing. -3. **Mirror body, datum axis, helix** — small, self-contained, high-frequency features. -4. **Promote move/rotate body from display-only to a real B-rep feature** — closes a - correctness gap, not just a missing tool (exports currently disagree with the view). -5. **Split body** — high value for print-in-parts workflows. -6. **Project edges into sketch** — the sketcher's most conspicuous hole. -7. **Surface modelling** — large, but OCCT already ships the algorithms. -8. **Assemblies** — largest effort; only worth it if Orca targets multi-part products. - -Deliberately last: drawings and sheet metal — high cost, low relevance to an -FDM-oriented tool. - ---- - -## 4. Honest summary - -Orca's **sketcher is at or near Onshape parity**, and its **solid feature set -covers the mainstream modelling path** (sketch → extrude/revolve/sweep/loft → -dress-up → boolean/pattern). What is absent is *breadth*: assemblies, surfaces, -sheet metal, drawings, and — most importantly for a tool calling itself parametric — -**variables and configurations**. - -The single most defensible criticism is #3: without variables, the feature tree is -parametric in *structure* but not in *value*, so the promise of "change one number -and the model updates" is only half delivered. diff --git a/docs/CAD/cad_dependency_weight.md b/docs/CAD/cad_dependency_weight.md deleted file mode 100644 index 0b64ac8097..0000000000 --- a/docs/CAD/cad_dependency_weight.md +++ /dev/null @@ -1,136 +0,0 @@ -# Dependency weight of the Design/CAD subsystem - -What the Design tab actually costs a maintainer who merges it. Written to be checkable: -every number below is reproducible with the command that produced it, and the places where -a number is still missing say so instead of guessing. - -Measured on Linux x86_64, OCCT V7_6_0, in the `snapmaker-deps` build image. - -## Summary - -| | Cost | -|---|---| -| New third-party dependencies | **none** | -| OCCT build flag | `BUILD_MODULE_ModelingAlgorithms=ON` | -| Extra OCCT toolkits *built* | 3 (TKFillet, TKOffset, TKFeat) | -| Extra OCCT toolkits *linked* | 2 (TKFillet, TKOffset) | -| Vendored code | `src/libslic3r/slvs`, 9,339 lines, 380 KiB, GPLv3 | -| Own object code | 6.79 MiB unstripped `.o` (7.13 MiB with the solver) | - -OCCT is **already** an upstream dependency — Orca uses it for STEP import. The Design tab -does not add a library; it turns on one more OCCT module. - -## The OCCT module flag - -`deps/OCCT/OCCT.cmake` gates the module on `SLIC3R_CAD`: - -```cmake --DBUILD_MODULE_ModelingAlgorithms=${SLIC3R_CAD} # was hard-coded OFF -``` - -With `SLIC3R_CAD=OFF` the deps prefix matches upstream exactly. - -`ModelingAlgorithms` contains 12 toolkits, but **most were already being built**, because -`DataExchange` — the STEP path upstream already ships — depends on them. The honest delta is -only the toolkits that DataExchange's dependency closure does *not* reach: - -``` -ModelingAlgorithms = TKGeomAlgo TKTopAlgo TKPrim TKBO TKBool TKHLR - TKFillet TKOffset TKFeat TKMesh TKXMesh TKShHealing - -already required by DataExchange: TKBO TKBool TKGeomAlgo TKHLR TKMesh - TKPrim TKShHealing TKTopAlgo -true delta: TKFeat TKFillet TKOffset TKXMesh -``` - -Reproduce by walking `adm/MODULES` and each toolkit's `src//EXTERNLIB` in the OCCT -source tree. - -### Sizes of the delta toolkits - -Static archives in the deps prefix. These are *build artifacts*, not shipped bytes — a -static link pulls in only the objects it references: - -| Toolkit | Archive | Referenced by the Design tab? | -|---|---|---| -| TKFillet | 7.40 MiB | yes — `BRepFilletAPI` | -| TKOffset | 5.38 MiB | yes — `BRepOffsetAPI`, `BRepOffset_` | -| TKFeat | 4.42 MiB | **no** | -| TKXMesh | — | not produced at all | - -TKFeat is worth calling out: nothing in the Design tab references it, and it is absent from -the `TKFillet`/`TKOffset` dependency closure, so it is built for nothing. OCCT's module flag -is all-or-nothing per module, which is why it comes along. It costs build time and zero -shipped bytes on any platform that links OCCT statically. - -**A correction to the record.** The comment in `deps/OCCT/OCCT.cmake` and the earlier -summary both said the delta was "TKFillet + TKOffset — 3.77 MiB, Windows only". The toolkit -list was incomplete: TKFeat is built too. The 3.77 MiB figure covers 2 of the 3 built -toolkits and has not been re-derived here — see the gap below. - -## What is not measured yet - -Two numbers a maintainer may reasonably ask for are **not** in this document, because -producing them honestly needs a build this machine cannot do: - -1. **Windows DLL delta.** OCCT builds shared on Windows, so the shipped cost there is real - DLL bytes rather than linker-selected objects. That needs a Windows build to size — - tracked as the cross-platform build proof (`gix`). -2. **Clean-build time delta.** Measuring it means building the deps prefix twice, with the - flag ON and OFF, on the same machine. The incremental figures from day-to-day work do not - answer the question and are not offered as if they did. - -Do not quote a number for either until it has been measured. - -## Vendored solver - -`src/libslic3r/slvs` — the 2D sketch constraint solver extracted from SolveSpace. - -- 19 files: 8 `.cpp`, 11 `.h`, plus `LICENSE` -- 9,339 lines, 380 KiB of source, 0.34 MiB of object code -- **GPLv3**, `LICENSE` preserved verbatim in the vendored directory - -The fork is **AGPLv3**. GPLv3 code combines into an AGPLv3 work without difficulty: AGPLv3 -§13 provides explicit compatibility in that direction. No licence question to resolve. - -It is live code, not a carried corpse — `SketchSolver.cpp` is its only consumer and drives -every sketch constraint in the Design tab. - -## Own code - -Object sizes from the release build (unstripped, so these include debug information and -overstate the shipped contribution): - -| Object | Size | -|---|---| -| DesignPanel.o | 2.22 MiB | -| McpControl.o | 1.69 MiB | -| DesignSketchTool.o | 0.88 MiB | -| CadDocument.o | 0.76 MiB | -| SketchEngine.o | 0.40 MiB | -| DesignCanvas.o | 0.37 MiB | -| GeometryEngine.o | 0.32 MiB | -| SketchSolver.o | 0.15 MiB | -| slvs (all objects) | 0.34 MiB | -| **total** | **7.13 MiB** | - -For scale, the linked binary is 137.1 MiB. - -## Reproducing - -```bash -# toolkit membership and dependency closure -R= -cat $R/adm/MODULES # module -> toolkits -cat $R/src//EXTERNLIB # toolkit -> its dependencies - -# archive sizes -ls -l /lib/libTK{Fillet,Offset,Feat}.a - -# what the Design tab actually references -grep -rE 'BRepFilletAPI|BRepOffsetAPI|BRepOffset_|BRepFeat' src/libslic3r/ - -# vendored solver -wc -l src/libslic3r/slvs/*.cpp src/libslic3r/slvs/**/*.h -head -3 src/libslic3r/slvs/LICENSE -``` diff --git a/docs/CAD/cad_ux_guidelines.md b/docs/CAD/cad_ux_guidelines.md deleted file mode 100644 index d0290a1d3d..0000000000 --- a/docs/CAD/cad_ux_guidelines.md +++ /dev/null @@ -1,704 +0,0 @@ -# Orca-CAD — UX guidelines and design charter - -Status: proposed, v1. Owner: design working group. Applies to the Design tab — -the parametric CAD environment inside OrcaSlicer. - -This document is a **review instrument**, not an essay. Sections 3–9 are written -so that a reviewer can hold a pull request against them and get a yes or a no. -If a rule here cannot be failed, it is badly written and should be rewritten. - ---- - -## 1. Why this exists - -A CAD tool acquires its interface by accretion. Every feature arrives needing -"just one more field", the side panel is the cheapest place to put it, and after -forty features the product is FreeCAD: complete, respected, and abandoned by -almost everyone who opens it once. That end state is not a failure of any single -decision. It is the sum of forty locally reasonable ones taken without a written -rule to violate. - -So we write the rule down first, and we make additions argue against it. - -## 2. Product thesis - -**Orca-CAD is a modelling space for people who want a part, inside the tool that -prints it.** - -Three audiences, one interface: - -- **The fourteen-year-old on a school laptop.** Free software, on the machine - they already have, with no account, no subscription, no licence and no - tutorial. They open the tab because they want a bracket for a bike light, and - an hour later it is printing. This is not the charity case at the bottom of - the list — it is the reason the project is worth doing. A CAD tool that only - the equipped can run is a tool for people who were already going to design - something; this one has to be a creative instrument in the hands of someone - who did not yet know they could make things. Everything in §6.1 exists to - keep that door open, and nothing gets to close it for the convenience of the - other two audiences. -- **The maker** who has an idea and a printer, and who has bounced off FreeCAD. - They should be modelling something real within ten minutes of first opening - the tab, without a tutorial, without knowing the word "constraint". -- **The mechanical designer** who needs assemblies, mates, exploded views, - variables, and a feature history they can edit six months later. They should - not have to leave for SolidWorks the moment the work gets serious. - -The order matters. When a decision helps one audience and hurts another, the -earlier one wins unless there is a written argument for why not. - -The reference for *how it feels* is Shapr3D: direct, gestural, quiet, almost no -chrome, depth revealed by what you touch rather than by what is on screen. The -anti-references are Blender (a modal keyboard language you must learn before the -first success) and FreeCAD (a workbench-and-dialog architecture where the -geometry is a preview of a form you fill in elsewhere). - -We are not cloning Shapr3D's feature set. We are adopting its *interaction -economy*: the smallest number of visible controls that still makes an expert -fast. - -**And one thing neither reference has:** Orca-CAD lives inside a slicer. The -plate, the nozzle, the material and the print constraints are known to the -application at design time. Designing for print is not a plugin here, it is the -home advantage. Where a rule below trades generality for print-awareness, it -trades in favour of print-awareness. - -## 3. The laws - -Non-negotiable. A change that breaks one of these does not get merged on the -grounds that it was easier, that the alternative is more work, or that another -CAD does it that way. Each law carries a test — the question a reviewer asks. - -### L1 — Geometry first: you point, then you act - -Controls live **on the geometry**: handles, arrows, points, small circles and -boxes, with an inline label tab for typed values. Not in a side panel of combos -and spin fields. - -The canonical gesture: **select a face or plane in the viewport, then click the -sketch tool.** Never: click the sketch tool, then choose a plane from a list. -The tool consumes what you pointed at — and, better still, the thing you pointed -at offers the tool itself (§4). - -> **Test.** Can the operation be performed start to finish without the pointer -> leaving the viewport, except to press the tool itself? If a control had to be -> added to a panel to make it work, the design is not finished. - -This is the law the others serve. It was stated after two proposals in a row -reached for a dropdown, and the failure mode it names is real and recurrent: a -fix that "adds a row to the plane combo" is the side-panel pattern wearing a -different hat. - -### L2 — Everything draggable is typable, and everything typable is draggable - -Any value produced by direct manipulation (a fillet radius, an extrude depth, a -pattern spacing, a plane offset) shows a live label on the geometry, and that -label is an editable field. Any value entered numerically has a corresponding -handle in the viewport. - -Dragging is for finding the answer. Typing is for committing to it. A tool that -offers only one of the two is half a tool. - -> **Test.** Point at the number the tool produces. Can you drag it? Can you -> click it and type? Both must be yes. - -### L3 — Noun then verb, always the same way round - -Selection precedes action, without exception, across sketch tools, features, -dress-up, booleans and mates. There is no tool in the product that is armed -first and asks for its input afterwards. - -> **Test.** Does this tool work if the user has already selected the thing they -> want it applied to? Does it work *only* that way? - -### L4 — No modal dialog in the modelling loop - -Dialogs belong to document-level actions: open, save, import, export, preferences. -Modelling never opens one. A feature that needs three values gets three labels on -the geometry, not a form; a feature that needs confirming gets a ghost preview and -a confirm/cancel puck in the scene beside it (§4.2) — an object, not a window: the -camera still orbits, the values are still editable, nothing is blocked. - -> **Test.** Between starting an operation and seeing its result, does a window -> appear that must be dismissed? If yes, redesign. - -### L5 — One click, one visible change - -Every click either changes what is on screen or tells the user why it did not. -A click that opens something invisible, arms an invisible state, or requires a -second identical click to have any effect is a defect, not a design. - -This law exists because we shipped its violation twice. Sketch-tool family -buttons were flyouts whose first click only rendered a pressed state — three -separate sessions filed bugs against tools that were working. Solid picking used -a click *cycle* (first click selects the body, second refines to the face), so -sketching on a face appeared broken to anyone who clicked a face once, the way -every human does. - -> **Test.** Perform the gesture exactly once, as a first-time user would. Take a -> screenshot. Is the state visibly different, and is the difference the one the -> user intended? - -### L6 — The default is the answer four times out of five - -Every option that has a default must have the *common* answer as its default, -measured against real parts, not against generality. "New body" as the default -result of an extrude is wrong: most extrudes join. Radius as the input for a -circle is wrong: drawings give diameter. - -> **Test.** Take ten real parts. In how many is the default correct? Below eight, -> change the default or infer it from context. - -### L7 — Errors are caught before the commit, in the user's words - -A self-intersecting profile, a cut that removes no material, a wall thinner than -the nozzle: these are reported at the moment they become knowable, on the -geometry that is wrong, phrased as what happened and what to do — not as a kernel -exception after the fact, and never silently. - -> **Test.** Is the failure detectable before the user commits? Then it must be -> reported before the user commits. Read the message aloud: does it name a thing -> the user can see and an action they can take? - -### L8 — The camera is the application's job - -Selecting a sketch plane orients the view to it. Committing a feature does not -throw the camera away. Zoom-to-fit exists and is one keystroke. The user is never -required to fight the view in order to reach the geometry, and orbit is bound to -the gesture people actually try. - -> **Test.** Count camera manipulations in a representative modelling session. -> Any camera action the application could have performed for the user is a bug. - -### L9 — Accessible by construction, not by retrofit - -The floor, applied to every new interaction (details in §6.2): full keyboard -reach, no meaning carried by colour alone, hit targets that survive a shaky hand -and a HiDPI screen, legible labels over an arbitrary 3D background, no gesture -that depends on timing. - -> **Test.** Drive the whole interaction from the keyboard. Then drive it in -> greyscale. Both must work. - -### L10 — Vocabulary from the drawing office - -Names come from the language of people who make parts: fillet, chamfer, boss, -rib, counterbore, mate, exploded view. Not from the kernel (no "boolean -subtract", no "B-rep"), not from invented product-speak. Where the drawing-office -word and the beginner's word differ, use the drawing-office word and make the -tooltip teach it — an approachable tool that leaves the user unable to talk to a -machinist has failed them. - -> **Test.** Would a shop-floor engineer recognise this word? Would a first-time -> user be able to look it up and find a real definition? - -### L11 — The floor is a school laptop, and nothing is behind a door - -The product runs, completely, on a low-end laptop with integrated graphics and a -small screen, offline, with no account, no subscription and no feature withheld. -No capability in this document is reserved for a paid tier, a cloud service, a -plugin, or a machine with a discrete GPU — there is one product and everybody -gets all of it. - -> **Test.** On the reference low-end machine (§6.1), at 1366×768, with the -> network cable pulled and no account ever created: does this feature work, and -> is it usable at an honest frame rate? Any "no" is a defect, not a limitation. - -## 4. Interaction grammar — object-driven - -The rules above compose into one sentence the whole product obeys: - -> **Point at geometry → the geometry offers what can be done to it → choose the -> tool → manipulate handles and type exact values → confirm or cancel.** - -The selection does not merely feed the tool. **The selection determines which -tools exist.** Pick a planar face and the product shows you the small set of -things a planar face can become — sketch on it, extrude it, hole it, shell it, -put a datum on it. Pick an edge and that set is fillet, chamfer, and the sketch -tools that can use it as a reference. Nothing else is offered, because nothing -else is possible. - -This is the single largest thing we can do for a first-time user, and it is -worth stating as the reason: a beginner's difficulty is not operating a tool, -it is **not knowing which tools apply to what they are looking at**. A palette -of sixty icons answers a question they cannot yet ask. A face that offers its -own five verbs teaches the model of the product by using it. It also removes an -entire class of failure — a tool that silently does nothing because the -selection was wrong can no longer be reached. - -### 4.1 The offer, and the one thing that makes it work - -The flow, in full: - -> **left-click the geometry to select it → right-click to open the offer → a -> vertical list, always in the same order, each row an icon, a name and its -> keyboard shortcut → click.** - -- **Selecting and acting are separate gestures.** Left-click only ever selects, - so pointing at things is quiet — nothing pops up while you look around. - Right-click on the selection opens the offer, at the pointer, over the - geometry it acts on. -- **Order is fixed and it is the whole point.** A verb occupies one permanent - row, and that row is the same in every selection where the verb appears. - Dress-up is the fourth row on an edge, on a face, on a body, on the day the - product ships and two years later. The hand learns the position; the eye stops - being needed. -- **What does not apply is DISABLED IN PLACE, never removed.** This is the - single strongest thing the list does, and it is why it beat the radial we - drew first: a greyed row still carries its name *and the reason it is grey* — - "Create a sketch, or pick a solid face, first", "Create a solid body to - pattern first" — in the words the product already ships. On a first-run - document the offer is therefore not a mostly-empty control but a map of what - the product does and what you have to do first. -- **It is an accelerator, not a toll gate.** The toolbar and the single-letter - shortcuts keep working exactly as they do now, and pressing a tool directly - consumes the same selection (L3). An expert never has to open the offer; a - beginner never has to know the toolbar exists. Both routes land in the same - place — this is the only way one interface serves §2's three audiences. -- **Every row shows its keyboard shortcut**, right-aligned so the keys stack - into a column the eye learns without trying, beside the icon and the - drawing-office word (L10). This is deliberate: the offer is the path by which - a user stops needing the offer. You reach for fillet in its row, the row says - "F", and one day your hand types F before the menu has finished opening. A - menu that teaches its own shortcut is how a beginner becomes the power user - who never opens it — the same interface at two speeds, with no "advanced mode" - between them (§7). -- **A family with more than one applicable verb opens a submenu** to the side, - in its own fixed order. A family with exactly one shows that verb directly, so - the common path is never one click longer than it needs to be. -- **It never blocks the view of what it acts on**: it opens beside the pick, - never over it, with a thin leader back to the point it belongs to, and it - dismisses the moment the selection changes. -- **The header names what is selected** ("Top face · Body 1"), because a user - who mis-picked should find that out before choosing a verb, not after. - -#### Opening the offer on every machine - -Right-click is the primary gesture and every platform must have a first-class -equivalent — this is a reach requirement (L11), not a nicety: - -| Input | Gesture | -|---|---| -| Two-button mouse | right-click | -| Trackpad | two-finger tap (the OS-standard secondary click) | -| macOS, one-button mouse | **long-press**, and Ctrl-click, which is the platform convention | -| Keyboard | the Menu key, or Shift+F10, on the current selection | -| Touch / pen | long-press | - -The long-press is an **additional** route, never the only one — §6.2 forbids -press-and-hold as a sole path to a function, and it stays forbidden. Every -opening gesture is reachable at least two ways on every platform, and the -keyboard route exists everywhere. A long-press must show that it is charging -(a growing ring under the finger) so a user who holds too briefly learns why -nothing happened rather than concluding the product is broken (L5). - -#### The row-constancy invariant - -This is the rule that has to survive every future feature, so it is written as -an invariant rather than as advice: - -> **Every verb has exactly one row index in the offer. That index is identical -> for every selection type in which the verb appears. Verbs that do not apply to -> the current selection are DISABLED IN PLACE, with their reason — the offer is -> never compacted, re-sorted or re-ordered. Adding a verb never changes the -> index of an existing one.** - -Two consequences the group must accept together with the invariant: - -- **No adaptive ordering. Ever.** Not most-used-first, not recently-used-first, - not per-selection frequency. An offer that rearranges itself to be helpful - destroys the only thing that made it fast, and it does so precisely for the - user who has just started to learn it. (Office 2000's adaptive menus are the - textbook case; they were removed.) -- **Greyed rows are the price, and they are cheap.** A compacted menu is shorter - and unlearnable. A constant one is a few rows longer, teaches while it waits, - and is memorised in a week. - -#### The map — RATIFIED 2026-07-31 - -The invariant is not negotiable, and as of 2026-07-31 neither is the assignment: -the row order below is **ratified**. It was argued once; it is not argued again. -Changing an index from here on is a breaking change to every user's muscle -memory and needs the group, not a pull request (§9 q12). - -Eight families, ordered so the sequence itself has a logic: material is created, -grows, is taken away, is refined, is repeated, is moved, is referred to, is -edited. - -| Row | Family | On a face | On an edge | On a body | On text/art | -|---|---|---|---|---|---| -| **1** | Create | Sketch on it | — | — | Edit text | -| **2** | Add material | Extrude, thicken | — | Combine, thicken | Extrude | -| **3** | Remove | Hole, shell | Thread | Shell, cut, split | — | -| **4** | Dress-up | Draft | Fillet, chamfer | Fillet, chamfer | — | -| **5** | Repeat | Pattern | Pattern along it | Pattern, mirror | Pattern | -| **6** | Transform | Align to, mate | — | Move, mate | Move, size | -| **7** | Reference | Plane, axis, measure | Axis, measure | Project, measure, mass | — | -| **8** | Modify | Delete face, edit | — | Edit, colour, delete | Replace art | - -A dash means the row is drawn greyed for that selection, with its reason. - -The authoritative version of this table is **`docs/ux/tool_atlas.json`**, which -carries all 52 verbs with their preconditions and their refusal strings, taken -from the code rather than from memory. Every state it produces — 20 selection -kinds × 2 document states, 40 primary menus and 73 submenus — is rendered by -`docs/ux/mockups/gen_offer_mockups.py` into `docs/ux/offer_atlas.html`. Read the -atlas before proposing a change to the map; the generator refuses to render an -address collision, so the map cannot silently rot. - -#### Rejected: the radial ring - -The first design put the eight families at eight compass points around the pick. -It is recorded here because it is a good idea that loses on evidence, and -someone will propose it again: - -- an inapplicable slot could only be drawn empty, and **an empty slot says - nothing** — the reason text above has nowhere to live; -- the measured fill was **3.45 of 8 slots**, so most of the control was blank - most of the time, and on a fresh document only two of eight were live; -- sketch-mode *Create* needs **nine** addresses; eight forced two primitives - behind a "More" slot, and a ninth position costs the 45° spacing that made the - ring worth having; -- long translated names do not fit around a circle, and screen readers and arrow - keys need bespoke handling a list gets for free; -- a 380 px disc over the model costs more on a 1366×768 screen than a 324 px - list beside it (§6.1). - -What it kept — equidistant targets and a future flick gesture — buys little in a -product whose experts live on the keyboard by design. - -### 4.2 Confirm and cancel are objects, not gestures - -The old rule — click empty space to commit — is withdrawn. It was an invisible -gesture with a destructive meaning: nothing on screen said it, and a stray click -committed a feature the user was still adjusting. That is exactly what L5 -forbids, and it is hostile to the audience §6.1 exists for. - -- **A pending feature carries a confirm/cancel puck**, attached to the geometry - it is editing, next to its handles: ✓ commits, ✗ discards. Enter and Escape - mirror them for the keyboard (L9). It is drawn where the user's attention - already is, and it is the only thing in the viewport that commits. -- **Empty space now means "clear the selection"** — the safe meaning, and the - same meaning everywhere. -- **This is not a dialog** (L4). It is two objects in the scene, on the - geometry, non-modal: the camera still orbits, the tree is still there, the - values are still editable while it waits. -- **Continuous tools do not ask.** Drawing a line, a rectangle, a circle commits - each entity as its own gesture completes — a ✓ per line would destroy the - inner loop. The puck belongs to *features* (extrude, fillet, hole, pattern, - mate) and to sketch edits that hold a pending state. Enter/Escape end a - continuous tool rather than confirming an entity. -- **Ambiguity resolves toward keeping work, never toward losing it.** Starting - another operation while a valid feature is pending commits it rather than - discarding it; if it is not valid, the product says why (L7) and keeps it - pending. Since undo reaches everything (§6.1), the recoverable direction is - always the right default. - -### 4.3 The rest of the grammar - -- **The status line is one imperative sentence** naming what the tool wants - next, and it names the target when the target came from a selection - ("Circle — click centre, then radius · on the picked face"). It is the - authoritative feedback surface for the armed tool; the toolbar is not. -- **Hover previews, click commits.** A hover shows the ghost of what a click - would do wherever this is cheap to compute. -- **Selection is persistent and visible** until consumed or cleared. A tool that - consumes a selection clears it, so the next feature cannot silently inherit it. -- **Every gesture is undoable**, and the feature tree is editable history, not a - log. Re-editing a feature re-enters the same on-geometry interaction that - created it — including its offer and its puck. - -## 5. Layout and screen budget - -The viewport is the application. Chrome is a tax on it. - -- **One toolbar**, contextual to the mode (model / sketch). Tools are grouped by - what they make, not by which subsystem implements them. -- **A left rail for the document, not for parameters**: feature tree, bodies, - variables. It answers "what exists", never "what value should this be". -- **No parameter panel.** Where one exists today it is technical debt with a - scheduled removal (§10). -- **Print context is ambient**, not a panel: the plate is visible in the design - space, and print-domain warnings appear on the geometry that will fail. -- **Nothing is added to permanent chrome without removing something**, or - demonstrating that the addition is used in the majority of sessions. -- **The budget is set by the smallest screen we serve**, 1366×768 (§6.1) — not - by the reviewer's monitor. Chrome that fits a 27-inch display and swallows a - laptop's has not fitted, it has just failed somewhere the author cannot see. - -## 6. Accessibility — reach first, then the assistive floor - -"Accessible" means two different things and the product owes both. §6.1 is about -**who can get in at all**; §6.2 is about **who can operate it once inside**. -Neither is a phase. Both are merge requirements. - -### 6.1 Reach — the door has to be open - -The premise of the whole project: someone with no money, no licence, no account, -no fast machine and no teacher can open this and make a real thing. Free -software on a school laptop is the only path to a CAD tool that reaches people -who were never going to be handed one. If a design decision quietly raises the -cost of entry, it has broken the premise, however elegant it is. - -- **The reference machine.** A 5-year-old laptop: dual/quad-core CPU, - **integrated graphics**, 8 GB RAM, **1366×768** screen, no discrete GPU. The - Design tab must be usable there, and any interaction that needs more is a - design failure to be solved, not a requirement to be documented. The GPU path - degrades gracefully to software rendering rather than refusing to start; the - viewport stays interactive while the kernel thinks. -- **1366×768 is the layout target, not the stretch case.** A form-heavy side - panel is not merely inelegant on that screen — it takes the model off it. - This is the second, independent argument for the whole of L1 and §5. -- **No account, no cloud, no connection.** The product works forever with the - network unplugged. Nothing is uploaded, no sign-in gates any feature, no - telemetry is required to use it. A school network that blocks everything must - not be able to block this. -- **No tier, no plugin wall, no "pro".** Every feature named in this document is - in the product everyone downloads. Assemblies and exploded views are not the - paid half. -- **Files belong to the user**, on their disk, in a format that outlives the - project: the design travels inside the ordinary project file, and the geometry - exports to STEP and mesh formats anyone can open. -- **Learnable without instruction.** The first solid comes with no - documentation, no video and no tutorial mode — from noticing that a face can - be clicked. Tooltips teach the vocabulary (L10) at the moment it is needed; - nothing is explained in a manual the user will never open. -- **Plain language at the entry tier.** The Make tier speaks in words a - thirteen-year-old reads without stopping. Precision comes with the tier that - needs it, and everything is translated, because "accessible" in English only - is not accessible. -- **Exploration must be free.** Undo reaches everything, work is never lost to a - wrong click, and no dialog ever asks the user to be sure. A tool that punishes - experiments teaches people to stop experimenting, which is the one thing this - audience cannot afford to learn. -- **The product never blames the user.** Failures are stated as what happened - and what to do (L7). "Invalid input" is not an acceptable sentence anywhere. - -### 6.2 Assistive floor - -- **Keyboard**: every operation reachable and completable without a pointer. - Single-letter shortcuts for sketch tools, shown in the offer itself (§4.1) as - well as in the tooltip. The offer opens from the keyboard (Menu key or - Shift+F10) and walks by arrow key and by type-ahead, so the row map works for - someone who never touches the pointer. A visible focus state on every - focusable element. No shortcut that only works while the pointer happens to be - over the canvas. -- **Colour**: never the sole carrier of meaning. Selection is colour *and* - outline; an error is colour *and* an icon *and* text. Verify in greyscale. -- **Contrast**: labels over the 3D viewport get a scrim or halo so 4.5:1 holds - against any background the model can produce, including a white body under a - white plate. -- **Targets**: handles and grips no smaller than 32 px at 100 % scale, scaling - with the OS factor; the grab tolerance is larger than the drawn glyph. -- **Timing**: no double-click-to-mean-something-else, no press-and-hold as the - only route to a function, no cycle that depends on repeated clicks - (see L5). The long-press that opens the offer on a one-button Mac and on touch - (§4.1) is explicitly an *additional* route — Ctrl-click, two-finger tap and - the keyboard all reach the same place — and it shows its own progress while - charging, so it never fails silently. -- **Motion**: animation is functional (showing where a thing went), never - decorative, and it respects the reduced-motion preference. -- **Text**: no fixed-width assumptions; the UI holds together in German and in - Chinese, at 125 % and 200 % scale. Every string routed through the normal - translation path. - -## 7. Depth without clutter — the three tiers - -Power for experts is delivered by **progressive disclosure of tools, never by -relocation of tools**. A tool that appears in a later tier is in the same place -it will always be; it is simply not shown yet. - -| Tier | Who | What appears | -|---|---|---| -| **Make** | first hour | Sketch, extrude, revolve, hole, fillet/chamfer, move, commit to plate | -| **Model** | competent user | Patterns, shell, draft, sweep/loft, booleans, reference geometry, variables, import/export | -| **Mechanism** | mechanical designer | Assemblies and mates, exploded views, interference detection, surfaces, feature-level editing of imported solids | - -Rules that keep this honest: - -1. **Tiers are non-modal.** No mode switch, no workbench selector, no "advanced - mode" toggle that changes the meaning of anything. The tier only governs what - is *offered*. -2. **A tier reveals itself by use.** Using a body reveals boolean tools; adding - a second body reveals assembly tools. The product notices what you are doing. -3. **Nothing moves when a tier appears.** A user who learned where fillet lives - finds it in the same place forever. -4. **An expert tool obeys the same grammar** as a beginner tool. Mates are - picked in 3D like everything else, not configured in a table. -5. **Exploded views are a view state**, not a document mode — reversible, - draggable along mate axes, and never a separate file. - -## 8. Designing for print — the home advantage - -Design-time knowledge the application already has, and must use: - -- **The plate is present** in the design space, at the real size, with the real - origin. Committing a body to the plate is one action and preserves placement. -- **Print-domain checks run on the model, on the geometry, before slicing**: - walls thinner than the nozzle, unsupported overhangs beyond the material's - angle, features smaller than the layer height, a part that does not fit the - build volume. -- **These are warnings on the geometry, never a report.** The thin wall glows; - the tooltip says how thin and what the nozzle is. -- **Material and machine context is inherited** from the active slicer profile, - not re-entered in the Design tab. -- **The round trip is preserved**: editing a design after slicing returns to the - feature history, not to a mesh. - -## 9. The review gate - -Every pull request that touches the Design tab UI answers these, in the PR body. -A "no" that is not accompanied by an argument is a request for changes. - -1. Which law (L1–L11) does the change most directly serve? -2. Can the whole operation be completed without the pointer leaving the - viewport? If not, why is this the exception? - And: does the relevant selection *offer* this tool (§4.1), or must the user - already know it exists? -3. Are the values draggable *and* typable? -4. Screenshot of the state after **exactly one** click of the new gesture, - performed as a first-time user. -5. Keyboard-only walkthrough: does it complete? -6. Greyscale screenshot: is every state still distinguishable? -7. What was **removed**? (Net additions to permanent chrome require an argument.) -8. Which tier does it belong to, and does it appear without moving anything else? -9. What does it do when the geometry is invalid, and is that reported before the - commit? -10. Interaction cost: actions required for the canonical task it addresses, - before and after. -11. Reach (L11): screenshot at 1366×768 with the panel open — is the model still - on screen? Does it run on integrated graphics? Does it need the network, an - account, or a file the user cannot keep? -12. If the change adds or moves a verb in the offer: which row, and is it that - verb's row in **every** selection where it appears? Did any existing verb's - index change? (If yes, this is not a UI change, it is a breaking change to - every user's muscle memory, and it needs the group — see §4.1.) Was - `docs/ux/tool_atlas.json` updated and the atlas regenerated? -13. If the change adds a pointer gesture: what is its keyboard equivalent, and - what does a one-button Mac, a trackpad and a touch screen do (§4.1)? - -## 10. Where we stand today — honest inventory - -Complying with the laws already: - -- Sketch inline editors — draw an entity and its dimension tab opens on the - geometry; Tab walks Length → Width → Angle. -- Fillet/chamfer draggable radius arrow with an editable value label. -- Extrude depth arrow; move-body three-axis arrows. -- Datum-plane resize handles and offset arrow; ghost reference planes picked in - 3D. -- Imported-art place/size gizmo. -- Sketch plane taken from the picked face, with the target named in the status - line, and the sketch-plane dropdown deleted outright. - -Violating them, with removal scheduled: - -- **Every tool card is a two-column form** of combos and spin fields in the left - panel. This is the single largest debt in the product and the reason this - document exists. Tracked as an epic; each card is replaced by its on-geometry - equivalent, not improved in place. It fails L1 and it fails L11 twice over — - on a 1366×768 screen the cards leave the model a strip. -- Seven remaining plane pickers still populate a combo instead of consuming a - viewport selection. -- Pattern has no on-geometry spacing arrow or count badge. -- Hole is positioned by X/Y fields rather than by a point on a face. -- Booleans and cuts pick their operands from lists rather than in 3D. -- Fillet/chamfer edge selection still requires the click cycle L5 forbids. -- **Selecting geometry offers nothing.** There is no contextual offer (§4.1): - the user faces the full toolbar whatever they have picked, and finds out that - a tool did not apply by it doing nothing. This is the largest single item of - new work the charter asks for. The map and every state of it are already - drawn (`docs/ux/offer_atlas.html`); what the group owes itself before the code - is ratifying the row order, since every verb built before that lands has to be - addressed afterwards anyway. -- **Committing is an invisible click in empty space** rather than the - confirm/cancel puck of §4.2 — the exact gesture that rule withdraws. - -Nothing on the violating list is defended. The only open question for each is -what its on-geometry replacement should be. - -## 11. How the group works - -**Roles.** Product/UX lead (owns this document and casts the tie-break vote on -interaction questions); kernel maintainer; GUI maintainer; a print-domain -reviewer; a mechanical-design reviewer who uses the product on real work; an -accessibility reviewer covering both senses of §6 — reach and assistive — who -owns the reference machine and actually runs on it. One person may hold more -than one role; the UX lead and the mechanical-design reviewer should not be the -same person, and nobody reviews reach from a workstation. - -**The absent audience needs a seat.** The fourteen-year-old is not in the room -and cannot file an issue. Someone in the group is accountable for B5 and B6, and -the group watches real first-timers use the product on the reference machine at -least once a quarter — school, makerspace, or a friend's kid. Everything else in -this document can be argued from principle; approachability can only be -observed. - -**Cadence.** A short weekly review of open interaction proposals. A monthly pass -over the violating inventory in §10 — anything that has not moved in two months -is either scheduled or explicitly accepted as permanent, with a reason written -into this document. - -**How a change moves.** - -1. *Problem* — a described user difficulty, ideally with an interaction-cost - measurement, never a solution in disguise. -2. *Sketch* — one or two on-geometry interaction proposals, drawn or described - as a gesture sequence. Reviewed against §3 before any code. -3. *Prototype* — built behind whatever the smallest safe path is, driven end to - end on a real display, and screenshotted at each state. -4. *Gate* — §9 answered in the PR. -5. *Merge*, then update §10. - -**Decisions are written down.** Any resolution that constrains future work is -appended to this document as a numbered law or as an accepted exception with its -reasoning. A decision that lives only in a call is not a decision. - -**How disagreements resolve.** Against the laws first. If the laws do not decide -it, the tie-break is the interaction cost measured on the canonical tasks in -§12; if that does not decide it, the UX lead chooses and records why. - -## 12. Canonical tasks — the benchmark - -The measure of every UX change is the cost of these five tasks. Each is timed and -counted (clicks, keystrokes, camera actions, mode switches) on the headless rig -and, periodically, with real users who have not seen the product. - -| # | Task | What it exercises | -|---|---|---| -| **B1** | Bracket: sketch an L, extrude, two holes, fillet the inside corner, send to plate | The inner loop | -| **B2** | Change a hole diameter and the plate thickness, six features deep, and rebuild | Parametric editability | -| **B3** | Take an imported STEP, delete a boss, close the face, thicken a wall to nozzle width | Direct editing + print awareness | -| **B4** | Two parts, one revolute mate, check interference, produce an exploded view | The Mechanism tier | -| **B5** | First-run: from opening the Design tab to a print-ready solid, no documentation | Approachability | -| **B6** | B1 again, on the reference machine at 1366×768, offline, on a fresh account-less install | Reach (L11) | - -Every task is run on the reference machine of §6.1, not on a workstation — a -number measured on a fast desktop describes an experience most of our users will -never have. B6 repeats the inner loop under the full entry conditions so that -reach is a measured quantity and not an intention. - -Targets are set once each task has been measured on the current build. B5's -target is expressed in minutes-to-first-solid **by someone who has never seen a -CAD program**, and it is the number this project is ultimately judged by. - ---- - -### Appendix — anti-patterns we have already paid for - -Kept because each cost real time and each is easy to reintroduce. - -- **The dropdown that grew a row.** Fixing "cannot sketch on a face" by adding a - "Face of Body 1" entry to a plane combo. It reads as a small fix and it is the - side-panel architecture reproducing itself. -- **The invisible first click.** Flyout buttons and pick cycles whose first click - changes nothing meaningful. Filed as bugs three separate times against working - code, and made a real bug look fixed when it was not. -- **The fix verified through a path the user will never take.** A face-sketch fix - confirmed by double-clicking to reach face level. Users click once. A fix - reachable only by an undiscoverable gesture is indistinguishable from no fix. -- **The wrong feedback surface.** Measuring an armed tool by the toolbar, which - never renders keyboard-armed state. The status line is the surface that - answers. -- **The silent success.** A cut that removed no material, reported as done. Now - an error naming the likely cause. diff --git a/docs/CAD/design/mate-connectors/BEAR_CONNECTOR_REVIEW.md b/docs/CAD/design/mate-connectors/BEAR_CONNECTOR_REVIEW.md deleted file mode 100644 index cc2d4b22aa..0000000000 --- a/docs/CAD/design/mate-connectors/BEAR_CONNECTOR_REVIEW.md +++ /dev/null @@ -1,169 +0,0 @@ -# BearConnector.step — examination - -> **Scope.** One file was supplied and it contains **one object: the male.** Everything below is -> measured from that single solid. Earlier drafts of this note reasoned about a female pocket and a -> mating pair — those objects were never supplied, so any statement about them was speculation and -> has been removed. The clearance, the fit, and the pocket's legibility are all **unassessed**. - -Measured, not eyeballed. Imported into the Design tab's own OpenCascade kernel -(`import_step` → one valid closed solid), topology queried, geometry checked numerically. -Flat drawing: `artifacts/shots/bear-flat.png`. Viewport: `artifacts/shots/bear-02-zoom.png`. - -**File:** AP242 Edition 2, ST-Developer. 1 `MANIFOLD_SOLID_BREP`, 1 `CLOSED_SHELL`. -**Size:** 83.06 × 66.69 × 17.27 mm. **Faces:** 30 — 24 planar + 6 cylindrical. -**Curves:** 69 lines + 12 circles. **No** splines, spheres, tori or cones. -**Relief:** only four Z levels — 0, 3.00, 10.66, 17.27. - ---- - -## What is right, and precisely so - -**The sloping ridge is implemented exactly as briefed.** From (0.00, 18.40, 17.27) to -(0.00, 46.72, 10.66): 28.3 mm long, 6.61 mm drop, **13.1° slope**, and both ends sit dead on -x = 0.00. It breaks 180° rotation on its own. - -**20.0° uniform draft on all four snout flanks**, identical to within 0.1°: -`(0,−0.94,0.342) (0.936,0.08,0.342) (0,0.94,0.342) (−0.936,0.08,0.342)`. That is a real, -deliberate lead-in — it self-centres into a matching pocket, and it demoulds and prints. - -**The eyes are exactly symmetric**: Ø9.87 at x = ±16.43, y = 48.01, matching to 0.01 mm. -Someone mirrored those on purpose. - -**The mating feature is extremely economical**: only **five edges** exist above the 3 mm plate — -the ridge plus two flank edges at each end. Base plate is exactly 3.00 mm. - -The low-poly constraint is honoured. All six cylinders are outline rounds and eye holes; none of -them is a mating surface. - ---- - -## The asymmetry is deliberate, and it is complete - -**Correction.** A first pass read the left/right differences as an unfinished mirror. That was wrong: -the asymmetry is intentional. Tested properly — every candidate self-symmetry, in the part's own -centred frame, with a generous 0.1 mm tolerance: - -| operation | edges mapped onto the part | -|---|---| -| identity | 81 / 81 — 100 % | -| mirror about x = 0 (left/right) | **0 / 81** | -| mirror about y = 0 (top/bottom) | **0 / 81** | -| rotate 180° about Z | **0 / 81** | -| rotate 90° about Z | **0 / 81** | -| mirror about the diagonal | **0 / 81** | - -**The symmetry group is trivial.** No rigid motion or reflection maps this part onto itself, so -**every partial view determines the orientation uniquely** — you never need to see the whole face to -know which way round it goes. That is the strongest possible result for a keying interface and it is -exactly what the earlier abstract glyph work kept failing to achieve: a symmetric shape seen at a -grazing angle, or half-occluded, gives an ambiguous read. - -### Does it let you GRASP the orientation? Measured, not asserted. - -Unique-in-principle and graspable-at-a-glance are different claims. The symmetry table proves the -first. For the second, the front-on picture (outline + eyes + mouth, filled) was rasterised and -compared against its own mirror and its own 180° rotation — the two ways a person can get it wrong. - -**By size** (percentage of pixels that differ): - -| width | vs mirror | vs rotated 180° | -|---|---|---| -| 16 px | 20.7 % | 26.0 % | -| 24 px | 21.9 % | 30.9 % | -| 32 px | 23.0 % | 28.1 % | -| 48 px | 22.4 % | 30.6 % | -| 80 px | 24.7 % | 31.0 % | -| 160 px | 23.6 % | 31.0 % | - -**The curve is flat.** The full signal is already there at 16 pixels and more resolution adds -nothing. That is the whole result: **the orientation cue lives at low spatial frequency**, carried by -the overall shape rather than by any detail. It therefore survives distance, blur, poor light, -peripheral vision, a small print and a low-resolution screen. It is the exact opposite of the abstract -disc glyph, whose roll cue was a small high-frequency feature and died at a grazing angle. - -**Partial views — a claim I made and then withdrew.** I ran a masked-window test and concluded that -a single quarter of the face was enough to read the orientation. **That test was invalid and the -conclusion is wrong.** It compared a window of the original against *the same window* of the mirrored -and rotated versions — which silently hands the observer the registration. It assumes you already -know that the patch you are looking at is the top-left quarter, which is exactly the thing you would -not know if you could only see a quarter. - -**You need to see the whole face.** The cues here are *relational*: the big ear only means something -next to the small ear, and the mouth offset only means something relative to the centreline. None of -them is self-locating. Whole-face is the operating condition, and the design should be judged and -used on that basis. - -That does not weaken the size result above, which always used the complete silhouette: the whole face -reads at 16 px. Needing all of it, and needing very little resolution of it, are compatible — and for -a part held in a hand, seeing all of it is the normal case. - -**The signal is allocated to the right risks.** The strongest cue (up to 41.7 %) guards against -inserting it upside down — the mistake people actually make. The weakest (~23 %) guards the mirror -case, which needs the part flipped over and which the protrusion already prevents mechanically. - -It also does mechanical work beyond the ridge. The ridge alone breaks 180° rotation; the asymmetric -outline additionally defeats the **mirrored-part** case — a mirror-image copy will not fit, so a -modelling or printing mirror is caught at assembly rather than three steps later. - -And for children specifically, a symmetric cartoon face reads as a mask; illustrators asymmetrise -deliberately so a face reads as a *character*. The asymmetry is earning its keep three ways at once. - -### What is worth keeping in mind anyway - -**The ears differ by 42 %** — left 8.33 mm wide (top y 65.68), right 11.81 mm (top y 66.69). Both -start at the same y = 60.79, so they read as a deliberate pair rather than an error. 42 % is well -above the perceptual threshold: you see it instantly. Good cue. - -**The mouth is a smirk** — x −21.93 … 0.00, centred at x = −10.96, stopping on the centreline. A -classic character device and a strong asymmetry. - -**The rounds are the best cue and the one safety question.** All four are on the left — Ø11.71 at -(−40.82, 7.38), Ø11.71 at (−34.76, 0.58), Ø10.00 at (−29.85, 60.83), Ø2.90 at (−26.70, 65.95) — and -the right side is entirely sharp. This is the *most locally readable* cue in the design: the ears -differ only by comparison (you must see both to know which is which), whereas a rounded corner tells -you "this is the left" from that corner alone, by eye **or by fingertip**. For children assembling by -feel that is the cue doing the real work. - -The tension is that "sharp" on a children's part is a hazard, and the obvious safety fix — round -everything — destroys the cue. The resolution is not round-vs-sharp but **large-vs-small radius**: -keep R≈6 on the left and give the right R≈1. R1 still reads and feels sharp locally, so the cue -survives, and the actual edge hazard goes away. That is the one recommendation that outlives the -correction. - -**One measurement that does not fit the story:** the outline is off-centre by **0.54 mm** (left reach -40.99, right reach 42.07). A deliberate cue should be unmissable; 0.54 mm is invisible. It is -probably a by-product of the other features rather than intent — worth a look, not a defect. - ---- - -## Two judgement calls, not defects - -**The snout is highest at the nose tip and slopes down toward the brow** — a real bear's muzzle -does the opposite. Anatomically it reads more like a beak or a horn than a snout. But mechanically -it is the better choice: the nose tip enters the pocket first and does the finding. Keep it if the -lead-in matters more than the likeness; flip it if "it must look like a bear" wins. - -**Only the male was supplied**, so the clearance, the fit and the pocket are unassessed. Nothing in -this note should be read as a judgement on them. - ---- - -## The strategic point, which is the real reason this design is good - -It gives orientation **a name**. "Ears up, nose down" needs no legend, no convention and no -documentation. Face recognition is the most robust pattern-matching humans have: it survives low -resolution, poor light, partial occlusion and peripheral vision. That is exactly the robustness the -abstract ridge key was reaching for, and here it comes for free. - -**One earlier objection does not transfer — noting it only so it is not carried over by mistake.** -In §8c of the design doc a female *pocket* measured as visually invisible — flat-shaded, a recess -reads as a blank rectangle — and I concluded male/female -is the wrong polarity cue. **That was a viewport finding, and it does not apply to a physical part.** -Nobody looks into the pocket of a toy; they feel it. For a part in a child's hands, male/female is -exactly the right polarity language. The earlier conclusion stands for the on-screen glyph and must -not be carried over to this. - -**The one rule to write down now:** the face and the key must never be allowed to disagree. People -will trust the face over the mechanics every time. Here they agree — ridge on the centreline, ears -up. If the face is ever restyled independently of the key, a user will orient by the bear and be -wrong. Tie them permanently, in the model and in whatever generates it. diff --git a/docs/CAD/design/mate-connectors/BearConnector_Cutter.step b/docs/CAD/design/mate-connectors/BearConnector_Cutter.step deleted file mode 100644 index c78e19e536..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Cutter.step +++ /dev/null @@ -1,998 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T12:46:26',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 1', - 'Open CASCADE STEP translator 7.8 1','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#958); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#229,#260,#497,#514,#531,#548,#565,#582,#599, - #616,#633,#650,#667,#684,#701,#718,#735,#747,#770,#794,#810,#822, - #839,#856,#878,#895,#912,#929,#946)); -#17 = ADVANCED_FACE('',(#18,#68,#79,#213),#224,.F.); -#18 = FACE_BOUND('',#19,.F.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(19.029295926024,-0.2,-17.63009960955)); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(16.626582997737,-0.2,-8.940188245231)); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(19.849519003668,-0.2,-20.59660707692)); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#30 = ORIENTED_EDGE('',*,*,#31,.F.); -#31 = EDGE_CURVE('',#32,#22,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(22.059435554995,-0.2,-3.734519760785)); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(17.698510515043,-0.2,-23.73280021221)); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#38 = ORIENTED_EDGE('',*,*,#39,.F.); -#39 = EDGE_CURVE('',#40,#32,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(-21.72552223146,-0.2,-3.734519760785)); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(0.297084840953,-0.2,-3.734519760785)); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(1.,0.,0.)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#48,#40,#50,.T.); -#48 = VERTEX_POINT('',#49); -#49 = CARTESIAN_POINT('',(-21.72552223146,-0.2,-8.903751135252)); -#50 = LINE('',#51,#52); -#51 = CARTESIAN_POINT('',(-21.72552223146,-0.2,-19.83215600037)); -#52 = VECTOR('',#53,1.); -#53 = DIRECTION('',(0.,0.,1.)); -#54 = ORIENTED_EDGE('',*,*,#55,.F.); -#55 = EDGE_CURVE('',#56,#48,#58,.T.); -#56 = VERTEX_POINT('',#57); -#57 = CARTESIAN_POINT('',(4.383041634064E-04,-0.2,-8.903751615529)); -#58 = LINE('',#59,#60); -#59 = CARTESIAN_POINT('',(-5.279852300138,-0.2,-8.903751135252)); -#60 = VECTOR('',#61,1.); -#61 = DIRECTION('',(-1.,0.,0.)); -#62 = ORIENTED_EDGE('',*,*,#63,.F.); -#63 = EDGE_CURVE('',#24,#56,#64,.T.); -#64 = LINE('',#65,#66); -#65 = CARTESIAN_POINT('',(4.347099726942,-0.2,-8.913277437397)); -#66 = VECTOR('',#67,1.); -#67 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#68 = FACE_BOUND('',#69,.F.); -#69 = EDGE_LOOP('',(#70)); -#70 = ORIENTED_EDGE('',*,*,#71,.F.); -#71 = EDGE_CURVE('',#72,#72,#74,.T.); -#72 = VERTEX_POINT('',#73); -#73 = CARTESIAN_POINT('',(21.163799345768,-0.2,-48.00951684793)); -#74 = CIRCLE('',#75,4.735522705283); -#75 = AXIS2_PLACEMENT_3D('',#76,#77,#78); -#76 = CARTESIAN_POINT('',(16.428276640485,-0.2,-48.00951684793)); -#77 = DIRECTION('',(-0.,1.,0.)); -#78 = DIRECTION('',(1.,0.,0.)); -#79 = FACE_BOUND('',#80,.F.); -#80 = EDGE_LOOP('',(#81,#91,#100,#108,#116,#125,#133,#142,#150,#158,#166 - ,#174,#182,#190,#198,#206)); -#81 = ORIENTED_EDGE('',*,*,#82,.T.); -#82 = EDGE_CURVE('',#83,#85,#87,.T.); -#83 = VERTEX_POINT('',#84); -#84 = CARTESIAN_POINT('',(-27.86158468659,-0.2,-65.78852163128)); -#85 = VERTEX_POINT('',#86); -#86 = CARTESIAN_POINT('',(-29.08766684168,-0.2,-64.52156932717)); -#87 = LINE('',#88,#89); -#88 = CARTESIAN_POINT('',(-29.44004200272,-0.2,-64.15744811364)); -#89 = VECTOR('',#90,1.); -#90 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#91 = ORIENTED_EDGE('',*,*,#92,.F.); -#92 = EDGE_CURVE('',#93,#85,#95,.T.); -#93 = VERTEX_POINT('',#94); -#94 = CARTESIAN_POINT('',(-28.96712497021,-0.2,-57.16864680227)); -#95 = CIRCLE('',#96,5.2); -#96 = AXIS2_PLACEMENT_3D('',#97,#98,#99); -#97 = CARTESIAN_POINT('',(-25.35093464349,-0.2,-60.90537900045)); -#98 = DIRECTION('',(0.,-1.,0.)); -#99 = DIRECTION('',(-1.,0.,0.)); -#100 = ORIENTED_EDGE('',*,*,#101,.T.); -#101 = EDGE_CURVE('',#93,#102,#104,.T.); -#102 = VERTEX_POINT('',#103); -#103 = CARTESIAN_POINT('',(-26.93875323652,-0.2,-55.20570756731)); -#104 = LINE('',#105,#106); -#105 = CARTESIAN_POINT('',(-14.90185526362,-0.2,-43.55710346492)); -#106 = VECTOR('',#107,1.); -#107 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#108 = ORIENTED_EDGE('',*,*,#109,.T.); -#109 = EDGE_CURVE('',#102,#110,#112,.T.); -#110 = VERTEX_POINT('',#111); -#111 = CARTESIAN_POINT('',(-41.17904151244,-0.2,-10.52828909594)); -#112 = LINE('',#113,#114); -#113 = CARTESIAN_POINT('',(-32.39120436163,-0.2,-38.09921113329)); -#114 = VECTOR('',#115,1.); -#115 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#116 = ORIENTED_EDGE('',*,*,#117,.F.); -#117 = EDGE_CURVE('',#118,#110,#120,.T.); -#118 = VERTEX_POINT('',#119); -#119 = CARTESIAN_POINT('',(-39.69176606491,-0.2,-4.408923352436)); -#120 = CIRCLE('',#121,6.054044962965); -#121 = AXIS2_PLACEMENT_3D('',#122,#123,#124); -#122 = CARTESIAN_POINT('',(-35.41090981799,-0.2,-8.689779599357)); -#123 = DIRECTION('',(0.,-1.,0.)); -#124 = DIRECTION('',(-1.,0.,0.)); -#125 = ORIENTED_EDGE('',*,*,#126,.T.); -#126 = EDGE_CURVE('',#118,#127,#129,.T.); -#127 = VERTEX_POINT('',#128); -#128 = CARTESIAN_POINT('',(-36.85603142851,-0.2,-1.573188716044)); -#129 = LINE('',#130,#131); -#130 = CARTESIAN_POINT('',(-36.19319006079,-0.2,-0.910347348321)); -#131 = VECTOR('',#132,1.); -#132 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#133 = ORIENTED_EDGE('',*,*,#134,.F.); -#134 = EDGE_CURVE('',#135,#127,#137,.T.); -#135 = VERTEX_POINT('',#136); -#136 = CARTESIAN_POINT('',(-32.57517518159,-0.2,0.2)); -#137 = CIRCLE('',#138,6.054044962965); -#138 = AXIS2_PLACEMENT_3D('',#139,#140,#141); -#139 = CARTESIAN_POINT('',(-32.57517518159,-0.2,-5.854044962965)); -#140 = DIRECTION('',(0.,-1.,0.)); -#141 = DIRECTION('',(-1.,0.,0.)); -#142 = ORIENTED_EDGE('',*,*,#143,.T.); -#143 = EDGE_CURVE('',#135,#144,#146,.T.); -#144 = VERTEX_POINT('',#145); -#145 = CARTESIAN_POINT('',(35.082842712475,-0.2,0.2)); -#146 = LINE('',#147,#148); -#147 = CARTESIAN_POINT('',(-7.942265537672,-0.2,0.2)); -#148 = VECTOR('',#149,1.); -#149 = DIRECTION('',(1.,0.,0.)); -#150 = ORIENTED_EDGE('',*,*,#151,.F.); -#151 = EDGE_CURVE('',#152,#144,#154,.T.); -#152 = VERTEX_POINT('',#153); -#153 = CARTESIAN_POINT('',(42.298608189024,-0.2,-7.015765476549)); -#154 = LINE('',#155,#156); -#155 = CARTESIAN_POINT('',(36.596246576251,-0.2,-1.313403863776)); -#156 = VECTOR('',#157,1.); -#157 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#158 = ORIENTED_EDGE('',*,*,#159,.F.); -#159 = EDGE_CURVE('',#160,#152,#162,.T.); -#160 = VERTEX_POINT('',#161); -#161 = CARTESIAN_POINT('',(26.938753236523,-0.2,-55.20570756731)); -#162 = LINE('',#163,#164); -#163 = CARTESIAN_POINT('',(32.699020781567,-0.2,-37.13346923684)); -#164 = VECTOR('',#165,1.); -#165 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#166 = ORIENTED_EDGE('',*,*,#167,.F.); -#167 = EDGE_CURVE('',#168,#160,#170,.T.); -#168 = VERTEX_POINT('',#169); -#169 = CARTESIAN_POINT('',(32.703857168398,-0.2,-60.78483712899)); -#170 = LINE('',#171,#172); -#171 = CARTESIAN_POINT('',(16.008242280412,-0.2,-44.62779994931)); -#172 = VECTOR('',#173,1.); -#173 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#174 = ORIENTED_EDGE('',*,*,#175,.F.); -#175 = EDGE_CURVE('',#176,#168,#178,.T.); -#176 = VERTEX_POINT('',#177); -#177 = CARTESIAN_POINT('',(26.715163243538,-0.2,-66.97315781796)); -#178 = LINE('',#179,#180); -#179 = CARTESIAN_POINT('',(30.25240665457,-0.2,-63.31800414721)); -#180 = VECTOR('',#181,1.); -#181 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#182 = ORIENTED_EDGE('',*,*,#183,.F.); -#183 = EDGE_CURVE('',#184,#176,#186,.T.); -#184 = VERTEX_POINT('',#185); -#185 = CARTESIAN_POINT('',(20.532019001374,-0.2,-60.98947335481)); -#186 = LINE('',#187,#188); -#187 = CARTESIAN_POINT('',(9.922784884512,-0.2,-50.72247862452)); -#188 = VECTOR('',#189,1.); -#189 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#190 = ORIENTED_EDGE('',*,*,#191,.F.); -#191 = EDGE_CURVE('',#192,#184,#194,.T.); -#192 = VERTEX_POINT('',#193); -#193 = CARTESIAN_POINT('',(-20.53201900137,-0.2,-60.98947335481)); -#194 = LINE('',#195,#196); -#195 = CARTESIAN_POINT('',(5.354765181569,-0.2,-60.98947335481)); -#196 = VECTOR('',#197,1.); -#197 = DIRECTION('',(1.,0.,0.)); -#198 = ORIENTED_EDGE('',*,*,#199,.T.); -#199 = EDGE_CURVE('',#192,#200,#202,.T.); -#200 = VERTEX_POINT('',#201); -#201 = CARTESIAN_POINT('',(-25.53052705686,-0.2,-65.82673637491)); -#202 = LINE('',#203,#204); -#203 = CARTESIAN_POINT('',(-9.454421870603,-0.2,-50.26922436104)); -#204 = VECTOR('',#205,1.); -#205 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#206 = ORIENTED_EDGE('',*,*,#207,.F.); -#207 = EDGE_CURVE('',#83,#200,#208,.T.); -#208 = CIRCLE('',#209,1.648528137424); -#209 = AXIS2_PLACEMENT_3D('',#210,#211,#212); -#210 = CARTESIAN_POINT('',(-26.67694849991,-0.2,-64.64210018823)); -#211 = DIRECTION('',(0.,-1.,0.)); -#212 = DIRECTION('',(-1.,0.,0.)); -#213 = FACE_BOUND('',#214,.F.); -#214 = EDGE_LOOP('',(#215)); -#215 = ORIENTED_EDGE('',*,*,#216,.F.); -#216 = EDGE_CURVE('',#217,#217,#219,.T.); -#217 = VERTEX_POINT('',#218); -#218 = CARTESIAN_POINT('',(-11.6927539352,-0.2,-48.00951684793)); -#219 = CIRCLE('',#220,4.735522705283); -#220 = AXIS2_PLACEMENT_3D('',#221,#222,#223); -#221 = CARTESIAN_POINT('',(-16.42827664048,-0.2,-48.00951684793)); -#222 = DIRECTION('',(-0.,1.,0.)); -#223 = DIRECTION('',(1.,0.,0.)); -#224 = PLANE('',#225); -#225 = AXIS2_PLACEMENT_3D('',#226,#227,#228); -#226 = CARTESIAN_POINT('',(0.403056515455,-0.2,-33.34517655273)); -#227 = DIRECTION('',(0.,1.,0.)); -#228 = DIRECTION('',(1.,0.,0.)); -#229 = ADVANCED_FACE('',(#230),#255,.F.); -#230 = FACE_BOUND('',#231,.F.); -#231 = EDGE_LOOP('',(#232,#240,#241,#249)); -#232 = ORIENTED_EDGE('',*,*,#233,.T.); -#233 = EDGE_CURVE('',#234,#160,#236,.T.); -#234 = VERTEX_POINT('',#235); -#235 = CARTESIAN_POINT('',(26.938753236523,3.2,-55.20570756731)); -#236 = LINE('',#237,#238); -#237 = CARTESIAN_POINT('',(26.938753236523,3.,-55.20570756731)); -#238 = VECTOR('',#239,1.); -#239 = DIRECTION('',(0.,-1.,0.)); -#240 = ORIENTED_EDGE('',*,*,#159,.T.); -#241 = ORIENTED_EDGE('',*,*,#242,.F.); -#242 = EDGE_CURVE('',#243,#152,#245,.T.); -#243 = VERTEX_POINT('',#244); -#244 = CARTESIAN_POINT('',(42.298608189024,3.2,-7.015765476549)); -#245 = LINE('',#246,#247); -#246 = CARTESIAN_POINT('',(42.298608189024,3.,-7.015765476549)); -#247 = VECTOR('',#248,1.); -#248 = DIRECTION('',(0.,-1.,0.)); -#249 = ORIENTED_EDGE('',*,*,#250,.F.); -#250 = EDGE_CURVE('',#234,#243,#251,.T.); -#251 = LINE('',#252,#253); -#252 = CARTESIAN_POINT('',(32.699020781567,3.2,-37.13346923684)); -#253 = VECTOR('',#254,1.); -#254 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#255 = PLANE('',#256); -#256 = AXIS2_PLACEMENT_3D('',#257,#258,#259); -#257 = CARTESIAN_POINT('',(34.581352051556,3.,-31.22785130119)); -#258 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#259 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#260 = ADVANCED_FACE('',(#261,#311,#322,#447,#481),#492,.T.); -#261 = FACE_BOUND('',#262,.T.); -#262 = EDGE_LOOP('',(#263,#273,#281,#289,#297,#305)); -#263 = ORIENTED_EDGE('',*,*,#264,.F.); -#264 = EDGE_CURVE('',#265,#267,#269,.T.); -#265 = VERTEX_POINT('',#266); -#266 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#267 = VERTEX_POINT('',#268); -#268 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#269 = LINE('',#270,#271); -#270 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#271 = VECTOR('',#272,1.); -#272 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#273 = ORIENTED_EDGE('',*,*,#274,.F.); -#274 = EDGE_CURVE('',#275,#265,#277,.T.); -#275 = VERTEX_POINT('',#276); -#276 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#277 = LINE('',#278,#279); -#278 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#279 = VECTOR('',#280,1.); -#280 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#281 = ORIENTED_EDGE('',*,*,#282,.F.); -#282 = EDGE_CURVE('',#283,#275,#285,.T.); -#283 = VERTEX_POINT('',#284); -#284 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#285 = LINE('',#286,#287); -#286 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#287 = VECTOR('',#288,1.); -#288 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#289 = ORIENTED_EDGE('',*,*,#290,.F.); -#290 = EDGE_CURVE('',#291,#283,#293,.T.); -#291 = VERTEX_POINT('',#292); -#292 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#293 = LINE('',#294,#295); -#294 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#295 = VECTOR('',#296,1.); -#296 = DIRECTION('',(1.,0.,0.)); -#297 = ORIENTED_EDGE('',*,*,#298,.F.); -#298 = EDGE_CURVE('',#299,#291,#301,.T.); -#299 = VERTEX_POINT('',#300); -#300 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#301 = LINE('',#302,#303); -#302 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#303 = VECTOR('',#304,1.); -#304 = DIRECTION('',(0.,0.,1.)); -#305 = ORIENTED_EDGE('',*,*,#306,.F.); -#306 = EDGE_CURVE('',#267,#299,#307,.T.); -#307 = LINE('',#308,#309); -#308 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#309 = VECTOR('',#310,1.); -#310 = DIRECTION('',(-1.,0.,0.)); -#311 = FACE_BOUND('',#312,.T.); -#312 = EDGE_LOOP('',(#313)); -#313 = ORIENTED_EDGE('',*,*,#314,.F.); -#314 = EDGE_CURVE('',#315,#315,#317,.T.); -#315 = VERTEX_POINT('',#316); -#316 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#317 = CIRCLE('',#318,4.735522705283); -#318 = AXIS2_PLACEMENT_3D('',#319,#320,#321); -#319 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#320 = DIRECTION('',(-0.,1.,0.)); -#321 = DIRECTION('',(1.,0.,0.)); -#322 = FACE_BOUND('',#323,.T.); -#323 = EDGE_LOOP('',(#324,#334,#343,#351,#360,#368,#374,#375,#383,#391, - #399,#407,#415,#424,#432,#441)); -#324 = ORIENTED_EDGE('',*,*,#325,.T.); -#325 = EDGE_CURVE('',#326,#328,#330,.T.); -#326 = VERTEX_POINT('',#327); -#327 = CARTESIAN_POINT('',(-26.93875323652,3.2,-55.20570756731)); -#328 = VERTEX_POINT('',#329); -#329 = CARTESIAN_POINT('',(-41.17904151244,3.2,-10.52828909594)); -#330 = LINE('',#331,#332); -#331 = CARTESIAN_POINT('',(-32.39120436163,3.2,-38.09921113329)); -#332 = VECTOR('',#333,1.); -#333 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#334 = ORIENTED_EDGE('',*,*,#335,.F.); -#335 = EDGE_CURVE('',#336,#328,#338,.T.); -#336 = VERTEX_POINT('',#337); -#337 = CARTESIAN_POINT('',(-39.69176606491,3.2,-4.408923352436)); -#338 = CIRCLE('',#339,6.054044962965); -#339 = AXIS2_PLACEMENT_3D('',#340,#341,#342); -#340 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#341 = DIRECTION('',(0.,-1.,0.)); -#342 = DIRECTION('',(-1.,0.,0.)); -#343 = ORIENTED_EDGE('',*,*,#344,.T.); -#344 = EDGE_CURVE('',#336,#345,#347,.T.); -#345 = VERTEX_POINT('',#346); -#346 = CARTESIAN_POINT('',(-36.85603142851,3.2,-1.573188716044)); -#347 = LINE('',#348,#349); -#348 = CARTESIAN_POINT('',(-36.19319006079,3.2,-0.910347348321)); -#349 = VECTOR('',#350,1.); -#350 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#351 = ORIENTED_EDGE('',*,*,#352,.F.); -#352 = EDGE_CURVE('',#353,#345,#355,.T.); -#353 = VERTEX_POINT('',#354); -#354 = CARTESIAN_POINT('',(-32.57517518159,3.2,0.2)); -#355 = CIRCLE('',#356,6.054044962965); -#356 = AXIS2_PLACEMENT_3D('',#357,#358,#359); -#357 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#358 = DIRECTION('',(0.,-1.,0.)); -#359 = DIRECTION('',(-1.,0.,0.)); -#360 = ORIENTED_EDGE('',*,*,#361,.T.); -#361 = EDGE_CURVE('',#353,#362,#364,.T.); -#362 = VERTEX_POINT('',#363); -#363 = CARTESIAN_POINT('',(35.082842712475,3.2,0.2)); -#364 = LINE('',#365,#366); -#365 = CARTESIAN_POINT('',(-7.942265537672,3.2,0.2)); -#366 = VECTOR('',#367,1.); -#367 = DIRECTION('',(1.,0.,0.)); -#368 = ORIENTED_EDGE('',*,*,#369,.F.); -#369 = EDGE_CURVE('',#243,#362,#370,.T.); -#370 = LINE('',#371,#372); -#371 = CARTESIAN_POINT('',(36.596246576251,3.2,-1.313403863776)); -#372 = VECTOR('',#373,1.); -#373 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#374 = ORIENTED_EDGE('',*,*,#250,.F.); -#375 = ORIENTED_EDGE('',*,*,#376,.F.); -#376 = EDGE_CURVE('',#377,#234,#379,.T.); -#377 = VERTEX_POINT('',#378); -#378 = CARTESIAN_POINT('',(32.703857168398,3.2,-60.78483712899)); -#379 = LINE('',#380,#381); -#380 = CARTESIAN_POINT('',(16.008242280412,3.2,-44.62779994931)); -#381 = VECTOR('',#382,1.); -#382 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#383 = ORIENTED_EDGE('',*,*,#384,.F.); -#384 = EDGE_CURVE('',#385,#377,#387,.T.); -#385 = VERTEX_POINT('',#386); -#386 = CARTESIAN_POINT('',(26.715163243538,3.2,-66.97315781796)); -#387 = LINE('',#388,#389); -#388 = CARTESIAN_POINT('',(30.25240665457,3.2,-63.31800414721)); -#389 = VECTOR('',#390,1.); -#390 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#391 = ORIENTED_EDGE('',*,*,#392,.F.); -#392 = EDGE_CURVE('',#393,#385,#395,.T.); -#393 = VERTEX_POINT('',#394); -#394 = CARTESIAN_POINT('',(20.532019001374,3.2,-60.98947335481)); -#395 = LINE('',#396,#397); -#396 = CARTESIAN_POINT('',(9.922784884512,3.2,-50.72247862452)); -#397 = VECTOR('',#398,1.); -#398 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#399 = ORIENTED_EDGE('',*,*,#400,.F.); -#400 = EDGE_CURVE('',#401,#393,#403,.T.); -#401 = VERTEX_POINT('',#402); -#402 = CARTESIAN_POINT('',(-20.53201900137,3.2,-60.98947335481)); -#403 = LINE('',#404,#405); -#404 = CARTESIAN_POINT('',(5.354765181569,3.2,-60.98947335481)); -#405 = VECTOR('',#406,1.); -#406 = DIRECTION('',(1.,0.,0.)); -#407 = ORIENTED_EDGE('',*,*,#408,.T.); -#408 = EDGE_CURVE('',#401,#409,#411,.T.); -#409 = VERTEX_POINT('',#410); -#410 = CARTESIAN_POINT('',(-25.53052705686,3.2,-65.82673637491)); -#411 = LINE('',#412,#413); -#412 = CARTESIAN_POINT('',(-9.454421870603,3.2,-50.26922436104)); -#413 = VECTOR('',#414,1.); -#414 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#415 = ORIENTED_EDGE('',*,*,#416,.F.); -#416 = EDGE_CURVE('',#417,#409,#419,.T.); -#417 = VERTEX_POINT('',#418); -#418 = CARTESIAN_POINT('',(-27.86158468659,3.2,-65.78852163128)); -#419 = CIRCLE('',#420,1.648528137424); -#420 = AXIS2_PLACEMENT_3D('',#421,#422,#423); -#421 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#422 = DIRECTION('',(0.,-1.,0.)); -#423 = DIRECTION('',(-1.,0.,0.)); -#424 = ORIENTED_EDGE('',*,*,#425,.T.); -#425 = EDGE_CURVE('',#417,#426,#428,.T.); -#426 = VERTEX_POINT('',#427); -#427 = CARTESIAN_POINT('',(-29.08766684168,3.2,-64.52156932717)); -#428 = LINE('',#429,#430); -#429 = CARTESIAN_POINT('',(-29.44004200272,3.2,-64.15744811364)); -#430 = VECTOR('',#431,1.); -#431 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#432 = ORIENTED_EDGE('',*,*,#433,.F.); -#433 = EDGE_CURVE('',#434,#426,#436,.T.); -#434 = VERTEX_POINT('',#435); -#435 = CARTESIAN_POINT('',(-28.96712497021,3.2,-57.16864680227)); -#436 = CIRCLE('',#437,5.2); -#437 = AXIS2_PLACEMENT_3D('',#438,#439,#440); -#438 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#439 = DIRECTION('',(0.,-1.,0.)); -#440 = DIRECTION('',(-1.,0.,0.)); -#441 = ORIENTED_EDGE('',*,*,#442,.T.); -#442 = EDGE_CURVE('',#434,#326,#443,.T.); -#443 = LINE('',#444,#445); -#444 = CARTESIAN_POINT('',(-14.90185526362,3.2,-43.55710346492)); -#445 = VECTOR('',#446,1.); -#446 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#447 = FACE_BOUND('',#448,.T.); -#448 = EDGE_LOOP('',(#449,#459,#467,#475)); -#449 = ORIENTED_EDGE('',*,*,#450,.F.); -#450 = EDGE_CURVE('',#451,#453,#455,.T.); -#451 = VERTEX_POINT('',#452); -#452 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#453 = VERTEX_POINT('',#454); -#454 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#455 = LINE('',#456,#457); -#456 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#457 = VECTOR('',#458,1.); -#458 = DIRECTION('',(-8.501532861635E-02,0.,-0.996379643459)); -#459 = ORIENTED_EDGE('',*,*,#460,.F.); -#460 = EDGE_CURVE('',#461,#451,#463,.T.); -#461 = VERTEX_POINT('',#462); -#462 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#463 = LINE('',#464,#465); -#464 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#465 = VECTOR('',#466,1.); -#466 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#467 = ORIENTED_EDGE('',*,*,#468,.F.); -#468 = EDGE_CURVE('',#469,#461,#471,.T.); -#469 = VERTEX_POINT('',#470); -#470 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#471 = LINE('',#472,#473); -#472 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#473 = VECTOR('',#474,1.); -#474 = DIRECTION('',(-8.501532861635E-02,0.,0.996379643459)); -#475 = ORIENTED_EDGE('',*,*,#476,.F.); -#476 = EDGE_CURVE('',#453,#469,#477,.T.); -#477 = LINE('',#478,#479); -#478 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#479 = VECTOR('',#480,1.); -#480 = DIRECTION('',(-1.,0.,0.)); -#481 = FACE_BOUND('',#482,.T.); -#482 = EDGE_LOOP('',(#483)); -#483 = ORIENTED_EDGE('',*,*,#484,.F.); -#484 = EDGE_CURVE('',#485,#485,#487,.T.); -#485 = VERTEX_POINT('',#486); -#486 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#487 = CIRCLE('',#488,4.735522705283); -#488 = AXIS2_PLACEMENT_3D('',#489,#490,#491); -#489 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#490 = DIRECTION('',(-0.,1.,0.)); -#491 = DIRECTION('',(1.,0.,0.)); -#492 = PLANE('',#493); -#493 = AXIS2_PLACEMENT_3D('',#494,#495,#496); -#494 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#495 = DIRECTION('',(0.,1.,0.)); -#496 = DIRECTION('',(1.,0.,0.)); -#497 = ADVANCED_FACE('',(#498),#509,.F.); -#498 = FACE_BOUND('',#499,.F.); -#499 = EDGE_LOOP('',(#500,#506,#507,#508)); -#500 = ORIENTED_EDGE('',*,*,#501,.F.); -#501 = EDGE_CURVE('',#168,#377,#502,.T.); -#502 = LINE('',#503,#504); -#503 = CARTESIAN_POINT('',(32.703857168398,3.,-60.78483712899)); -#504 = VECTOR('',#505,1.); -#505 = DIRECTION('',(0.,1.,0.)); -#506 = ORIENTED_EDGE('',*,*,#167,.T.); -#507 = ORIENTED_EDGE('',*,*,#233,.F.); -#508 = ORIENTED_EDGE('',*,*,#376,.F.); -#509 = PLANE('',#510); -#510 = AXIS2_PLACEMENT_3D('',#511,#512,#513); -#511 = CARTESIAN_POINT('',(29.704873980143,3.,-57.88259703786)); -#512 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#513 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#514 = ADVANCED_FACE('',(#515),#526,.F.); -#515 = FACE_BOUND('',#516,.F.); -#516 = EDGE_LOOP('',(#517,#523,#524,#525)); -#517 = ORIENTED_EDGE('',*,*,#518,.F.); -#518 = EDGE_CURVE('',#176,#385,#519,.T.); -#519 = LINE('',#520,#521); -#520 = CARTESIAN_POINT('',(26.715163243538,3.,-66.97315781796)); -#521 = VECTOR('',#522,1.); -#522 = DIRECTION('',(0.,1.,0.)); -#523 = ORIENTED_EDGE('',*,*,#175,.T.); -#524 = ORIENTED_EDGE('',*,*,#501,.T.); -#525 = ORIENTED_EDGE('',*,*,#384,.F.); -#526 = PLANE('',#527); -#527 = AXIS2_PLACEMENT_3D('',#528,#529,#530); -#528 = CARTESIAN_POINT('',(29.709510205968,3.,-63.87899747347)); -#529 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#530 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#531 = ADVANCED_FACE('',(#532),#543,.F.); -#532 = FACE_BOUND('',#533,.F.); -#533 = EDGE_LOOP('',(#534,#540,#541,#542)); -#534 = ORIENTED_EDGE('',*,*,#535,.T.); -#535 = EDGE_CURVE('',#393,#184,#536,.T.); -#536 = LINE('',#537,#538); -#537 = CARTESIAN_POINT('',(20.532019001374,3.,-60.98947335481)); -#538 = VECTOR('',#539,1.); -#539 = DIRECTION('',(0.,-1.,0.)); -#540 = ORIENTED_EDGE('',*,*,#183,.T.); -#541 = ORIENTED_EDGE('',*,*,#518,.T.); -#542 = ORIENTED_EDGE('',*,*,#392,.F.); -#543 = PLANE('',#544); -#544 = AXIS2_PLACEMENT_3D('',#545,#546,#547); -#545 = CARTESIAN_POINT('',(23.522653113203,3.,-63.8836336993)); -#546 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#547 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#548 = ADVANCED_FACE('',(#549),#560,.F.); -#549 = FACE_BOUND('',#550,.F.); -#550 = EDGE_LOOP('',(#551,#557,#558,#559)); -#551 = ORIENTED_EDGE('',*,*,#552,.F.); -#552 = EDGE_CURVE('',#192,#401,#553,.T.); -#553 = LINE('',#554,#555); -#554 = CARTESIAN_POINT('',(-20.53201900137,3.,-60.98947335481)); -#555 = VECTOR('',#556,1.); -#556 = DIRECTION('',(0.,1.,0.)); -#557 = ORIENTED_EDGE('',*,*,#191,.T.); -#558 = ORIENTED_EDGE('',*,*,#535,.F.); -#559 = ORIENTED_EDGE('',*,*,#400,.F.); -#560 = PLANE('',#561); -#561 = AXIS2_PLACEMENT_3D('',#562,#563,#564); -#562 = CARTESIAN_POINT('',(10.306473847682,3.,-60.98947335481)); -#563 = DIRECTION('',(0.,0.,1.)); -#564 = DIRECTION('',(0.,-1.,0.)); -#565 = ADVANCED_FACE('',(#566),#577,.T.); -#566 = FACE_BOUND('',#567,.T.); -#567 = EDGE_LOOP('',(#568,#574,#575,#576)); -#568 = ORIENTED_EDGE('',*,*,#569,.F.); -#569 = EDGE_CURVE('',#409,#200,#570,.T.); -#570 = LINE('',#571,#572); -#571 = CARTESIAN_POINT('',(-25.53052705686,3.,-65.82673637491)); -#572 = VECTOR('',#573,1.); -#573 = DIRECTION('',(0.,-1.,0.)); -#574 = ORIENTED_EDGE('',*,*,#408,.F.); -#575 = ORIENTED_EDGE('',*,*,#552,.F.); -#576 = ORIENTED_EDGE('',*,*,#199,.T.); -#577 = PLANE('',#578); -#578 = AXIS2_PLACEMENT_3D('',#579,#580,#581); -#579 = CARTESIAN_POINT('',(-23.00219525444,3.,-63.37996509944)); -#580 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#581 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#582 = ADVANCED_FACE('',(#583),#594,.T.); -#583 = FACE_BOUND('',#584,.T.); -#584 = EDGE_LOOP('',(#585,#591,#592,#593)); -#585 = ORIENTED_EDGE('',*,*,#586,.F.); -#586 = EDGE_CURVE('',#417,#83,#587,.T.); -#587 = LINE('',#588,#589); -#588 = CARTESIAN_POINT('',(-27.86158468659,3.,-65.78852163128)); -#589 = VECTOR('',#590,1.); -#590 = DIRECTION('',(0.,-1.,0.)); -#591 = ORIENTED_EDGE('',*,*,#416,.T.); -#592 = ORIENTED_EDGE('',*,*,#569,.T.); -#593 = ORIENTED_EDGE('',*,*,#207,.F.); -#594 = CYLINDRICAL_SURFACE('',#595,1.648528137424); -#595 = AXIS2_PLACEMENT_3D('',#596,#597,#598); -#596 = CARTESIAN_POINT('',(-26.67694849991,3.,-64.64210018823)); -#597 = DIRECTION('',(0.,-1.,0.)); -#598 = DIRECTION('',(-1.,0.,0.)); -#599 = ADVANCED_FACE('',(#600),#611,.T.); -#600 = FACE_BOUND('',#601,.T.); -#601 = EDGE_LOOP('',(#602,#608,#609,#610)); -#602 = ORIENTED_EDGE('',*,*,#603,.F.); -#603 = EDGE_CURVE('',#426,#85,#604,.T.); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-29.08766684168,3.,-64.52156932717)); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(0.,-1.,0.)); -#608 = ORIENTED_EDGE('',*,*,#425,.F.); -#609 = ORIENTED_EDGE('',*,*,#586,.T.); -#610 = ORIENTED_EDGE('',*,*,#82,.T.); -#611 = PLANE('',#612); -#612 = AXIS2_PLACEMENT_3D('',#613,#614,#615); -#613 = CARTESIAN_POINT('',(-28.47462576413,3.,-65.15504547923)); -#614 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#615 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#616 = ADVANCED_FACE('',(#617),#628,.T.); -#617 = FACE_BOUND('',#618,.T.); -#618 = EDGE_LOOP('',(#619,#625,#626,#627)); -#619 = ORIENTED_EDGE('',*,*,#620,.F.); -#620 = EDGE_CURVE('',#434,#93,#621,.T.); -#621 = LINE('',#622,#623); -#622 = CARTESIAN_POINT('',(-28.96712497021,3.,-57.16864680227)); -#623 = VECTOR('',#624,1.); -#624 = DIRECTION('',(0.,-1.,0.)); -#625 = ORIENTED_EDGE('',*,*,#433,.T.); -#626 = ORIENTED_EDGE('',*,*,#603,.T.); -#627 = ORIENTED_EDGE('',*,*,#92,.F.); -#628 = CYLINDRICAL_SURFACE('',#629,5.2); -#629 = AXIS2_PLACEMENT_3D('',#630,#631,#632); -#630 = CARTESIAN_POINT('',(-25.35093464349,3.,-60.90537900045)); -#631 = DIRECTION('',(0.,-1.,0.)); -#632 = DIRECTION('',(-1.,0.,0.)); -#633 = ADVANCED_FACE('',(#634),#645,.T.); -#634 = FACE_BOUND('',#635,.T.); -#635 = EDGE_LOOP('',(#636,#642,#643,#644)); -#636 = ORIENTED_EDGE('',*,*,#637,.F.); -#637 = EDGE_CURVE('',#326,#102,#638,.T.); -#638 = LINE('',#639,#640); -#639 = CARTESIAN_POINT('',(-26.93875323652,3.,-55.20570756731)); -#640 = VECTOR('',#641,1.); -#641 = DIRECTION('',(0.,-1.,0.)); -#642 = ORIENTED_EDGE('',*,*,#442,.F.); -#643 = ORIENTED_EDGE('',*,*,#620,.T.); -#644 = ORIENTED_EDGE('',*,*,#101,.T.); -#645 = PLANE('',#646); -#646 = AXIS2_PLACEMENT_3D('',#647,#648,#649); -#647 = CARTESIAN_POINT('',(-27.90836811563,3.,-56.14404399617)); -#648 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#649 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#650 = ADVANCED_FACE('',(#651),#662,.T.); -#651 = FACE_BOUND('',#652,.T.); -#652 = EDGE_LOOP('',(#653,#659,#660,#661)); -#653 = ORIENTED_EDGE('',*,*,#654,.F.); -#654 = EDGE_CURVE('',#328,#110,#655,.T.); -#655 = LINE('',#656,#657); -#656 = CARTESIAN_POINT('',(-41.17904151244,3.,-10.52828909594)); -#657 = VECTOR('',#658,1.); -#658 = DIRECTION('',(0.,-1.,0.)); -#659 = ORIENTED_EDGE('',*,*,#325,.F.); -#660 = ORIENTED_EDGE('',*,*,#637,.T.); -#661 = ORIENTED_EDGE('',*,*,#109,.T.); -#662 = PLANE('',#663); -#663 = AXIS2_PLACEMENT_3D('',#664,#665,#666); -#664 = CARTESIAN_POINT('',(-34.04006158346,3.,-32.92609366041)); -#665 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#666 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#667 = ADVANCED_FACE('',(#668),#679,.T.); -#668 = FACE_BOUND('',#669,.T.); -#669 = EDGE_LOOP('',(#670,#676,#677,#678)); -#670 = ORIENTED_EDGE('',*,*,#671,.F.); -#671 = EDGE_CURVE('',#336,#118,#672,.T.); -#672 = LINE('',#673,#674); -#673 = CARTESIAN_POINT('',(-39.69176606491,3.,-4.408923352436)); -#674 = VECTOR('',#675,1.); -#675 = DIRECTION('',(0.,-1.,0.)); -#676 = ORIENTED_EDGE('',*,*,#335,.T.); -#677 = ORIENTED_EDGE('',*,*,#654,.T.); -#678 = ORIENTED_EDGE('',*,*,#117,.F.); -#679 = CYLINDRICAL_SURFACE('',#680,6.054044962965); -#680 = AXIS2_PLACEMENT_3D('',#681,#682,#683); -#681 = CARTESIAN_POINT('',(-35.41090981799,3.,-8.689779599357)); -#682 = DIRECTION('',(0.,-1.,0.)); -#683 = DIRECTION('',(-1.,0.,0.)); -#684 = ADVANCED_FACE('',(#685),#696,.T.); -#685 = FACE_BOUND('',#686,.T.); -#686 = EDGE_LOOP('',(#687,#693,#694,#695)); -#687 = ORIENTED_EDGE('',*,*,#688,.F.); -#688 = EDGE_CURVE('',#345,#127,#689,.T.); -#689 = LINE('',#690,#691); -#690 = CARTESIAN_POINT('',(-36.85603142851,3.,-1.573188716044)); -#691 = VECTOR('',#692,1.); -#692 = DIRECTION('',(0.,-1.,0.)); -#693 = ORIENTED_EDGE('',*,*,#344,.F.); -#694 = ORIENTED_EDGE('',*,*,#671,.T.); -#695 = ORIENTED_EDGE('',*,*,#126,.T.); -#696 = PLANE('',#697); -#697 = AXIS2_PLACEMENT_3D('',#698,#699,#700); -#698 = CARTESIAN_POINT('',(-38.27389874671,3.,-2.99105603424)); -#699 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#700 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#701 = ADVANCED_FACE('',(#702),#713,.T.); -#702 = FACE_BOUND('',#703,.T.); -#703 = EDGE_LOOP('',(#704,#710,#711,#712)); -#704 = ORIENTED_EDGE('',*,*,#705,.F.); -#705 = EDGE_CURVE('',#353,#135,#706,.T.); -#706 = LINE('',#707,#708); -#707 = CARTESIAN_POINT('',(-32.57517518159,3.,0.2)); -#708 = VECTOR('',#709,1.); -#709 = DIRECTION('',(0.,-1.,0.)); -#710 = ORIENTED_EDGE('',*,*,#352,.T.); -#711 = ORIENTED_EDGE('',*,*,#688,.T.); -#712 = ORIENTED_EDGE('',*,*,#134,.F.); -#713 = CYLINDRICAL_SURFACE('',#714,6.054044962965); -#714 = AXIS2_PLACEMENT_3D('',#715,#716,#717); -#715 = CARTESIAN_POINT('',(-32.57517518159,3.,-5.854044962965)); -#716 = DIRECTION('',(0.,-1.,0.)); -#717 = DIRECTION('',(-1.,0.,0.)); -#718 = ADVANCED_FACE('',(#719),#730,.T.); -#719 = FACE_BOUND('',#720,.T.); -#720 = EDGE_LOOP('',(#721,#727,#728,#729)); -#721 = ORIENTED_EDGE('',*,*,#722,.F.); -#722 = EDGE_CURVE('',#362,#144,#723,.T.); -#723 = LINE('',#724,#725); -#724 = CARTESIAN_POINT('',(35.082842712475,3.,0.2)); -#725 = VECTOR('',#726,1.); -#726 = DIRECTION('',(0.,-1.,0.)); -#727 = ORIENTED_EDGE('',*,*,#361,.F.); -#728 = ORIENTED_EDGE('',*,*,#705,.T.); -#729 = ORIENTED_EDGE('',*,*,#143,.T.); -#730 = PLANE('',#731); -#731 = AXIS2_PLACEMENT_3D('',#732,#733,#734); -#732 = CARTESIAN_POINT('',(-16.28758759079,3.,0.2)); -#733 = DIRECTION('',(0.,0.,1.)); -#734 = DIRECTION('',(0.,-1.,0.)); -#735 = ADVANCED_FACE('',(#736),#742,.F.); -#736 = FACE_BOUND('',#737,.F.); -#737 = EDGE_LOOP('',(#738,#739,#740,#741)); -#738 = ORIENTED_EDGE('',*,*,#151,.T.); -#739 = ORIENTED_EDGE('',*,*,#722,.F.); -#740 = ORIENTED_EDGE('',*,*,#369,.F.); -#741 = ORIENTED_EDGE('',*,*,#242,.T.); -#742 = PLANE('',#743); -#743 = AXIS2_PLACEMENT_3D('',#744,#745,#746); -#744 = CARTESIAN_POINT('',(38.67695526217,3.,-3.394112549695)); -#745 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#746 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#747 = ADVANCED_FACE('',(#748),#765,.T.); -#748 = FACE_BOUND('',#749,.T.); -#749 = EDGE_LOOP('',(#750,#758,#764)); -#750 = ORIENTED_EDGE('',*,*,#751,.T.); -#751 = EDGE_CURVE('',#451,#752,#754,.T.); -#752 = VERTEX_POINT('',#753); -#753 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#754 = LINE('',#755,#756); -#755 = CARTESIAN_POINT('',(5.649679875255,3.602918464526,-13.21082950266 - )); -#756 = VECTOR('',#757,1.); -#757 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#758 = ORIENTED_EDGE('',*,*,#759,.T.); -#759 = EDGE_CURVE('',#752,#461,#760,.T.); -#760 = LINE('',#761,#762); -#761 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#762 = VECTOR('',#763,1.); -#763 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#764 = ORIENTED_EDGE('',*,*,#460,.T.); -#765 = PLANE('',#766); -#766 = AXIS2_PLACEMENT_3D('',#767,#768,#769); -#767 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-13.01628215822 - )); -#768 = DIRECTION('',(2.881637632171E-16,0.342020143326,0.939692620786)); -#769 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326) - ); -#770 = ADVANCED_FACE('',(#771),#789,.T.); -#771 = FACE_BOUND('',#772,.T.); -#772 = EDGE_LOOP('',(#773,#781,#782,#783)); -#773 = ORIENTED_EDGE('',*,*,#774,.T.); -#774 = EDGE_CURVE('',#775,#752,#777,.T.); -#775 = VERTEX_POINT('',#776); -#776 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#777 = LINE('',#778,#779); -#778 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#779 = VECTOR('',#780,1.); -#780 = DIRECTION('',(5.275122655166E-17,0.227455280238,0.97378852709)); -#781 = ORIENTED_EDGE('',*,*,#751,.F.); -#782 = ORIENTED_EDGE('',*,*,#450,.T.); -#783 = ORIENTED_EDGE('',*,*,#784,.T.); -#784 = EDGE_CURVE('',#453,#775,#785,.T.); -#785 = LINE('',#786,#787); -#786 = CARTESIAN_POINT('',(1.103762571829,7.940067898719,-47.92064259636 - )); -#787 = VECTOR('',#788,1.); -#788 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#789 = PLANE('',#790); -#790 = AXIS2_PLACEMENT_3D('',#791,#792,#793); -#791 = CARTESIAN_POINT('',(5.823691883056,3.068404028665,-13.45978839622 - )); -#792 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02)); -#793 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487824E-02) - ); -#794 = ADVANCED_FACE('',(#795),#805,.T.); -#795 = FACE_BOUND('',#796,.T.); -#796 = EDGE_LOOP('',(#797,#803,#804)); -#797 = ORIENTED_EDGE('',*,*,#798,.T.); -#798 = EDGE_CURVE('',#469,#775,#799,.T.); -#799 = LINE('',#800,#801); -#800 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#801 = VECTOR('',#802,1.); -#802 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#803 = ORIENTED_EDGE('',*,*,#784,.F.); -#804 = ORIENTED_EDGE('',*,*,#476,.T.); -#805 = PLANE('',#806); -#806 = AXIS2_PLACEMENT_3D('',#807,#808,#809); -#807 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-49.69378323641 - )); -#808 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#809 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#810 = ADVANCED_FACE('',(#811),#817,.T.); -#811 = FACE_BOUND('',#812,.T.); -#812 = EDGE_LOOP('',(#813,#814,#815,#816)); -#813 = ORIENTED_EDGE('',*,*,#468,.T.); -#814 = ORIENTED_EDGE('',*,*,#759,.F.); -#815 = ORIENTED_EDGE('',*,*,#774,.F.); -#816 = ORIENTED_EDGE('',*,*,#798,.F.); -#817 = PLANE('',#818); -#818 = AXIS2_PLACEMENT_3D('',#819,#820,#821); -#819 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#820 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#821 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487824E-02)); -#822 = ADVANCED_FACE('',(#823),#834,.F.); -#823 = FACE_BOUND('',#824,.F.); -#824 = EDGE_LOOP('',(#825,#831,#832,#833)); -#825 = ORIENTED_EDGE('',*,*,#826,.F.); -#826 = EDGE_CURVE('',#217,#485,#827,.T.); -#827 = LINE('',#828,#829); -#828 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#829 = VECTOR('',#830,1.); -#830 = DIRECTION('',(0.,1.,0.)); -#831 = ORIENTED_EDGE('',*,*,#216,.T.); -#832 = ORIENTED_EDGE('',*,*,#826,.T.); -#833 = ORIENTED_EDGE('',*,*,#484,.F.); -#834 = CYLINDRICAL_SURFACE('',#835,4.735522705283); -#835 = AXIS2_PLACEMENT_3D('',#836,#837,#838); -#836 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#837 = DIRECTION('',(0.,1.,0.)); -#838 = DIRECTION('',(1.,0.,0.)); -#839 = ADVANCED_FACE('',(#840),#851,.F.); -#840 = FACE_BOUND('',#841,.F.); -#841 = EDGE_LOOP('',(#842,#848,#849,#850)); -#842 = ORIENTED_EDGE('',*,*,#843,.F.); -#843 = EDGE_CURVE('',#72,#315,#844,.T.); -#844 = LINE('',#845,#846); -#845 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#846 = VECTOR('',#847,1.); -#847 = DIRECTION('',(0.,1.,0.)); -#848 = ORIENTED_EDGE('',*,*,#71,.T.); -#849 = ORIENTED_EDGE('',*,*,#843,.T.); -#850 = ORIENTED_EDGE('',*,*,#314,.F.); -#851 = CYLINDRICAL_SURFACE('',#852,4.735522705283); -#852 = AXIS2_PLACEMENT_3D('',#853,#854,#855); -#853 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#854 = DIRECTION('',(0.,1.,0.)); -#855 = DIRECTION('',(1.,0.,0.)); -#856 = ADVANCED_FACE('',(#857),#873,.F.); -#857 = FACE_BOUND('',#858,.F.); -#858 = EDGE_LOOP('',(#859,#865,#866,#872)); -#859 = ORIENTED_EDGE('',*,*,#860,.F.); -#860 = EDGE_CURVE('',#24,#265,#861,.T.); -#861 = LINE('',#862,#863); -#862 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#863 = VECTOR('',#864,1.); -#864 = DIRECTION('',(0.,1.,0.)); -#865 = ORIENTED_EDGE('',*,*,#63,.T.); -#866 = ORIENTED_EDGE('',*,*,#867,.T.); -#867 = EDGE_CURVE('',#56,#267,#868,.T.); -#868 = LINE('',#869,#870); -#869 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#870 = VECTOR('',#871,1.); -#871 = DIRECTION('',(0.,1.,0.)); -#872 = ORIENTED_EDGE('',*,*,#264,.F.); -#873 = PLANE('',#874); -#874 = AXIS2_PLACEMENT_3D('',#875,#876,#877); -#875 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#876 = DIRECTION('',(-2.191520817069E-03,0.,-0.999997598615)); -#877 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#878 = ADVANCED_FACE('',(#879),#890,.F.); -#879 = FACE_BOUND('',#880,.F.); -#880 = EDGE_LOOP('',(#881,#887,#888,#889)); -#881 = ORIENTED_EDGE('',*,*,#882,.T.); -#882 = EDGE_CURVE('',#48,#299,#883,.T.); -#883 = LINE('',#884,#885); -#884 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#885 = VECTOR('',#886,1.); -#886 = DIRECTION('',(0.,1.,0.)); -#887 = ORIENTED_EDGE('',*,*,#306,.F.); -#888 = ORIENTED_EDGE('',*,*,#867,.F.); -#889 = ORIENTED_EDGE('',*,*,#55,.T.); -#890 = PLANE('',#891); -#891 = AXIS2_PLACEMENT_3D('',#892,#893,#894); -#892 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#893 = DIRECTION('',(0.,0.,-1.)); -#894 = DIRECTION('',(0.,1.,0.)); -#895 = ADVANCED_FACE('',(#896),#907,.F.); -#896 = FACE_BOUND('',#897,.F.); -#897 = EDGE_LOOP('',(#898,#904,#905,#906)); -#898 = ORIENTED_EDGE('',*,*,#899,.T.); -#899 = EDGE_CURVE('',#40,#291,#900,.T.); -#900 = LINE('',#901,#902); -#901 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#902 = VECTOR('',#903,1.); -#903 = DIRECTION('',(0.,1.,0.)); -#904 = ORIENTED_EDGE('',*,*,#298,.F.); -#905 = ORIENTED_EDGE('',*,*,#882,.F.); -#906 = ORIENTED_EDGE('',*,*,#47,.T.); -#907 = PLANE('',#908); -#908 = AXIS2_PLACEMENT_3D('',#909,#910,#911); -#909 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#910 = DIRECTION('',(-1.,0.,0.)); -#911 = DIRECTION('',(0.,1.,0.)); -#912 = ADVANCED_FACE('',(#913),#924,.F.); -#913 = FACE_BOUND('',#914,.F.); -#914 = EDGE_LOOP('',(#915,#921,#922,#923)); -#915 = ORIENTED_EDGE('',*,*,#916,.T.); -#916 = EDGE_CURVE('',#32,#283,#917,.T.); -#917 = LINE('',#918,#919); -#918 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#919 = VECTOR('',#920,1.); -#920 = DIRECTION('',(0.,1.,0.)); -#921 = ORIENTED_EDGE('',*,*,#290,.F.); -#922 = ORIENTED_EDGE('',*,*,#899,.F.); -#923 = ORIENTED_EDGE('',*,*,#39,.T.); -#924 = PLANE('',#925); -#925 = AXIS2_PLACEMENT_3D('',#926,#927,#928); -#926 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#927 = DIRECTION('',(0.,0.,1.)); -#928 = DIRECTION('',(0.,-1.,0.)); -#929 = ADVANCED_FACE('',(#930),#941,.F.); -#930 = FACE_BOUND('',#931,.F.); -#931 = EDGE_LOOP('',(#932,#938,#939,#940)); -#932 = ORIENTED_EDGE('',*,*,#933,.T.); -#933 = EDGE_CURVE('',#22,#275,#934,.T.); -#934 = LINE('',#935,#936); -#935 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#936 = VECTOR('',#937,1.); -#937 = DIRECTION('',(0.,1.,0.)); -#938 = ORIENTED_EDGE('',*,*,#282,.F.); -#939 = ORIENTED_EDGE('',*,*,#916,.F.); -#940 = ORIENTED_EDGE('',*,*,#31,.T.); -#941 = PLANE('',#942); -#942 = AXIS2_PLACEMENT_3D('',#943,#944,#945); -#943 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#944 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#945 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#946 = ADVANCED_FACE('',(#947),#953,.F.); -#947 = FACE_BOUND('',#948,.F.); -#948 = EDGE_LOOP('',(#949,#950,#951,#952)); -#949 = ORIENTED_EDGE('',*,*,#21,.T.); -#950 = ORIENTED_EDGE('',*,*,#860,.T.); -#951 = ORIENTED_EDGE('',*,*,#274,.F.); -#952 = ORIENTED_EDGE('',*,*,#933,.F.); -#953 = PLANE('',#954); -#954 = AXIS2_PLACEMENT_3D('',#955,#956,#957); -#955 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#956 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#957 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#958 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#962)) GLOBAL_UNIT_ASSIGNED_CONTEXT -((#959,#960,#961)) REPRESENTATION_CONTEXT('Context #1', - '3D Context with UNIT and UNCERTAINTY') ); -#959 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#960 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#961 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#962 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-05),#959, - 'distance_accuracy_value','confusion accuracy'); -#963 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female.step b/docs/CAD/design/mate-connectors/BearConnector_Female.step deleted file mode 100644 index 18e31c4b47..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Female.step +++ /dev/null @@ -1,1173 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T10:54:26',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 1', - 'Open CASCADE STEP translator 7.8 1','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#1118); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#57,#222,#246,#270,#287,#299,#330,#354,#378, - #402,#426,#451,#475,#500,#524,#548,#573,#597,#622,#646,#670,#687, - #817,#848,#872,#896,#920,#944,#961,#986,#1017,#1033,#1050,#1061, - #1086,#1100,#1109)); -#17 = ADVANCED_FACE('',(#18),#52,.F.); -#18 = FACE_BOUND('',#19,.F.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(0.,0.,1.)); -#30 = ORIENTED_EDGE('',*,*,#31,.T.); -#31 = EDGE_CURVE('',#22,#32,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796) - ); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(0.,1.,0.)); -#38 = ORIENTED_EDGE('',*,*,#39,.T.); -#39 = EDGE_CURVE('',#32,#40,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,4.2)); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796) - ); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(0.,0.,1.)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#24,#40,#48,.T.); -#48 = LINE('',#49,#50); -#49 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#50 = VECTOR('',#51,1.); -#51 = DIRECTION('',(0.,1.,0.)); -#52 = PLANE('',#53); -#53 = AXIS2_PLACEMENT_3D('',#54,#55,#56); -#54 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#55 = DIRECTION('',(1.,0.,0.)); -#56 = DIRECTION('',(0.,0.,1.)); -#57 = ADVANCED_FACE('',(#58,#83),#217,.F.); -#58 = FACE_BOUND('',#59,.F.); -#59 = EDGE_LOOP('',(#60,#68,#69,#77)); -#60 = ORIENTED_EDGE('',*,*,#61,.F.); -#61 = EDGE_CURVE('',#22,#62,#64,.T.); -#62 = VERTEX_POINT('',#63); -#63 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#64 = LINE('',#65,#66); -#65 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#66 = VECTOR('',#67,1.); -#67 = DIRECTION('',(1.,0.,0.)); -#68 = ORIENTED_EDGE('',*,*,#21,.T.); -#69 = ORIENTED_EDGE('',*,*,#70,.T.); -#70 = EDGE_CURVE('',#24,#71,#73,.T.); -#71 = VERTEX_POINT('',#72); -#72 = CARTESIAN_POINT('',(46.298608189024,0.,4.2)); -#73 = LINE('',#74,#75); -#74 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#75 = VECTOR('',#76,1.); -#76 = DIRECTION('',(1.,0.,0.)); -#77 = ORIENTED_EDGE('',*,*,#78,.F.); -#78 = EDGE_CURVE('',#62,#71,#79,.T.); -#79 = LINE('',#80,#81); -#80 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#81 = VECTOR('',#82,1.); -#82 = DIRECTION('',(0.,0.,1.)); -#83 = FACE_BOUND('',#84,.F.); -#84 = EDGE_LOOP('',(#85,#95,#103,#111,#119,#128,#136,#145,#153,#161,#170 - ,#178,#187,#195,#203,#211)); -#85 = ORIENTED_EDGE('',*,*,#86,.T.); -#86 = EDGE_CURVE('',#87,#89,#91,.T.); -#87 = VERTEX_POINT('',#88); -#88 = CARTESIAN_POINT('',(32.703857168398,0.,-60.78483712899)); -#89 = VERTEX_POINT('',#90); -#90 = CARTESIAN_POINT('',(26.938753236523,0.,-55.20570756731)); -#91 = LINE('',#92,#93); -#92 = CARTESIAN_POINT('',(13.567306766147,0.,-42.26560567724)); -#93 = VECTOR('',#94,1.); -#94 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#95 = ORIENTED_EDGE('',*,*,#96,.T.); -#96 = EDGE_CURVE('',#89,#97,#99,.T.); -#97 = VERTEX_POINT('',#98); -#98 = CARTESIAN_POINT('',(42.298608189024,0.,-7.015765476549)); -#99 = LINE('',#100,#101); -#100 = CARTESIAN_POINT('',(25.140315874087,-4.440892098501E-16, - -60.84811712245)); -#101 = VECTOR('',#102,1.); -#102 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#103 = ORIENTED_EDGE('',*,*,#104,.T.); -#104 = EDGE_CURVE('',#97,#105,#107,.T.); -#105 = VERTEX_POINT('',#106); -#106 = CARTESIAN_POINT('',(35.082842712475,0.,0.2)); -#107 = LINE('',#108,#109); -#108 = CARTESIAN_POINT('',(34.536239068456,0.,0.746603644019)); -#109 = VECTOR('',#110,1.); -#110 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#111 = ORIENTED_EDGE('',*,*,#112,.F.); -#112 = EDGE_CURVE('',#113,#105,#115,.T.); -#113 = VERTEX_POINT('',#114); -#114 = CARTESIAN_POINT('',(-32.57517518159,0.,0.2)); -#115 = LINE('',#116,#117); -#116 = CARTESIAN_POINT('',(-30.87627118587,0.,0.2)); -#117 = VECTOR('',#118,1.); -#118 = DIRECTION('',(1.,0.,0.)); -#119 = ORIENTED_EDGE('',*,*,#120,.T.); -#120 = EDGE_CURVE('',#113,#121,#123,.T.); -#121 = VERTEX_POINT('',#122); -#122 = CARTESIAN_POINT('',(-36.85603142851,0.,-1.573188716044)); -#123 = CIRCLE('',#124,6.054044962965); -#124 = AXIS2_PLACEMENT_3D('',#125,#126,#127); -#125 = CARTESIAN_POINT('',(-32.57517518159,0.,-5.854044962965)); -#126 = DIRECTION('',(0.,-1.,0.)); -#127 = DIRECTION('',(-1.,0.,0.)); -#128 = ORIENTED_EDGE('',*,*,#129,.F.); -#129 = EDGE_CURVE('',#130,#121,#132,.T.); -#130 = VERTEX_POINT('',#131); -#131 = CARTESIAN_POINT('',(-39.69176606491,0.,-4.408923352436)); -#132 = LINE('',#133,#134); -#133 = CARTESIAN_POINT('',(-57.0671882012,0.,-21.78434548873)); -#134 = VECTOR('',#135,1.); -#135 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#136 = ORIENTED_EDGE('',*,*,#137,.T.); -#137 = EDGE_CURVE('',#130,#138,#140,.T.); -#138 = VERTEX_POINT('',#139); -#139 = CARTESIAN_POINT('',(-41.17904151244,0.,-10.52828909594)); -#140 = CIRCLE('',#141,6.054044962965); -#141 = AXIS2_PLACEMENT_3D('',#142,#143,#144); -#142 = CARTESIAN_POINT('',(-35.41090981799,0.,-8.689779599357)); -#143 = DIRECTION('',(0.,-1.,0.)); -#144 = DIRECTION('',(-1.,0.,0.)); -#145 = ORIENTED_EDGE('',*,*,#146,.F.); -#146 = EDGE_CURVE('',#147,#138,#149,.T.); -#147 = VERTEX_POINT('',#148); -#148 = CARTESIAN_POINT('',(-26.93875323652,0.,-55.20570756731)); -#149 = LINE('',#150,#151); -#150 = CARTESIAN_POINT('',(-29.06259699304,-4.440892098501E-16, - -48.54236940733)); -#151 = VECTOR('',#152,1.); -#152 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#153 = ORIENTED_EDGE('',*,*,#154,.F.); -#154 = EDGE_CURVE('',#155,#147,#157,.T.); -#155 = VERTEX_POINT('',#156); -#156 = CARTESIAN_POINT('',(-28.96712497021,0.,-57.16864680227)); -#157 = LINE('',#158,#159); -#158 = CARTESIAN_POINT('',(-36.14667143517,0.,-64.11659091489)); -#159 = VECTOR('',#160,1.); -#160 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#161 = ORIENTED_EDGE('',*,*,#162,.T.); -#162 = EDGE_CURVE('',#155,#163,#165,.T.); -#163 = VERTEX_POINT('',#164); -#164 = CARTESIAN_POINT('',(-29.08766684168,0.,-64.52156932717)); -#165 = CIRCLE('',#166,5.2); -#166 = AXIS2_PLACEMENT_3D('',#167,#168,#169); -#167 = CARTESIAN_POINT('',(-25.35093464349,0.,-60.90537900045)); -#168 = DIRECTION('',(0.,-1.,0.)); -#169 = DIRECTION('',(-1.,0.,0.)); -#170 = ORIENTED_EDGE('',*,*,#171,.F.); -#171 = EDGE_CURVE('',#172,#163,#174,.T.); -#172 = VERTEX_POINT('',#173); -#173 = CARTESIAN_POINT('',(-27.86158468659,0.,-65.78852163128)); -#174 = LINE('',#175,#176); -#175 = CARTESIAN_POINT('',(-31.12923147938,0.,-62.41195129628)); -#176 = VECTOR('',#177,1.); -#177 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#178 = ORIENTED_EDGE('',*,*,#179,.T.); -#179 = EDGE_CURVE('',#172,#180,#182,.T.); -#180 = VERTEX_POINT('',#181); -#181 = CARTESIAN_POINT('',(-25.53052705686,0.,-65.82673637491)); -#182 = CIRCLE('',#183,1.648528137424); -#183 = AXIS2_PLACEMENT_3D('',#184,#185,#186); -#184 = CARTESIAN_POINT('',(-26.67694849991,0.,-64.64210018823)); -#185 = DIRECTION('',(0.,-1.,0.)); -#186 = DIRECTION('',(-1.,0.,0.)); -#187 = ORIENTED_EDGE('',*,*,#188,.F.); -#188 = EDGE_CURVE('',#189,#180,#191,.T.); -#189 = VERTEX_POINT('',#190); -#190 = CARTESIAN_POINT('',(-20.53201900137,0.,-60.98947335481)); -#191 = LINE('',#192,#193); -#192 = CARTESIAN_POINT('',(-30.69923804215,0.,-70.82871181101)); -#193 = VECTOR('',#194,1.); -#194 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#195 = ORIENTED_EDGE('',*,*,#196,.T.); -#196 = EDGE_CURVE('',#189,#197,#199,.T.); -#197 = VERTEX_POINT('',#198); -#198 = CARTESIAN_POINT('',(20.532019001374,0.,-60.98947335481)); -#199 = LINE('',#200,#201); -#200 = CARTESIAN_POINT('',(-17.57924046663,0.,-60.98947335481)); -#201 = VECTOR('',#202,1.); -#202 = DIRECTION('',(1.,0.,0.)); -#203 = ORIENTED_EDGE('',*,*,#204,.T.); -#204 = EDGE_CURVE('',#197,#205,#207,.T.); -#205 = VERTEX_POINT('',#206); -#206 = CARTESIAN_POINT('',(26.715163243538,0.,-66.97315781796)); -#207 = LINE('',#208,#209); -#208 = CARTESIAN_POINT('',(7.481849370247,-4.440892098501E-16, - -48.36028435244)); -#209 = VECTOR('',#210,1.); -#210 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#211 = ORIENTED_EDGE('',*,*,#212,.T.); -#212 = EDGE_CURVE('',#205,#87,#213,.T.); -#213 = LINE('',#214,#215); -#214 = CARTESIAN_POINT('',(9.75933652063,0.,-84.4941890519)); -#215 = VECTOR('',#216,1.); -#216 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#217 = PLANE('',#218); -#218 = AXIS2_PLACEMENT_3D('',#219,#220,#221); -#219 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#220 = DIRECTION('',(0.,1.,0.)); -#221 = DIRECTION('',(0.,0.,1.)); -#222 = ADVANCED_FACE('',(#223),#241,.T.); -#223 = FACE_BOUND('',#224,.T.); -#224 = EDGE_LOOP('',(#225,#226,#227,#235)); -#225 = ORIENTED_EDGE('',*,*,#47,.F.); -#226 = ORIENTED_EDGE('',*,*,#70,.T.); -#227 = ORIENTED_EDGE('',*,*,#228,.T.); -#228 = EDGE_CURVE('',#71,#229,#231,.T.); -#229 = VERTEX_POINT('',#230); -#230 = CARTESIAN_POINT('',(46.298608189024,20.8572529153,4.2)); -#231 = LINE('',#232,#233); -#232 = CARTESIAN_POINT('',(46.298608189024,0.,4.2)); -#233 = VECTOR('',#234,1.); -#234 = DIRECTION('',(0.,1.,0.)); -#235 = ORIENTED_EDGE('',*,*,#236,.F.); -#236 = EDGE_CURVE('',#40,#229,#237,.T.); -#237 = LINE('',#238,#239); -#238 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,4.2)); -#239 = VECTOR('',#240,1.); -#240 = DIRECTION('',(1.,0.,0.)); -#241 = PLANE('',#242); -#242 = AXIS2_PLACEMENT_3D('',#243,#244,#245); -#243 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#244 = DIRECTION('',(0.,0.,1.)); -#245 = DIRECTION('',(1.,0.,0.)); -#246 = ADVANCED_FACE('',(#247),#265,.T.); -#247 = FACE_BOUND('',#248,.T.); -#248 = EDGE_LOOP('',(#249,#257,#258,#259)); -#249 = ORIENTED_EDGE('',*,*,#250,.F.); -#250 = EDGE_CURVE('',#32,#251,#253,.T.); -#251 = VERTEX_POINT('',#252); -#252 = CARTESIAN_POINT('',(46.298608189024,20.8572529153,-70.97315781796 - )); -#253 = LINE('',#254,#255); -#254 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796 - )); -#255 = VECTOR('',#256,1.); -#256 = DIRECTION('',(1.,0.,0.)); -#257 = ORIENTED_EDGE('',*,*,#39,.T.); -#258 = ORIENTED_EDGE('',*,*,#236,.T.); -#259 = ORIENTED_EDGE('',*,*,#260,.F.); -#260 = EDGE_CURVE('',#251,#229,#261,.T.); -#261 = LINE('',#262,#263); -#262 = CARTESIAN_POINT('',(46.298608189024,20.8572529153,-70.97315781796 - )); -#263 = VECTOR('',#264,1.); -#264 = DIRECTION('',(0.,0.,1.)); -#265 = PLANE('',#266); -#266 = AXIS2_PLACEMENT_3D('',#267,#268,#269); -#267 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796 - )); -#268 = DIRECTION('',(0.,1.,0.)); -#269 = DIRECTION('',(0.,0.,1.)); -#270 = ADVANCED_FACE('',(#271),#282,.F.); -#271 = FACE_BOUND('',#272,.F.); -#272 = EDGE_LOOP('',(#273,#274,#275,#281)); -#273 = ORIENTED_EDGE('',*,*,#31,.F.); -#274 = ORIENTED_EDGE('',*,*,#61,.T.); -#275 = ORIENTED_EDGE('',*,*,#276,.T.); -#276 = EDGE_CURVE('',#62,#251,#277,.T.); -#277 = LINE('',#278,#279); -#278 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#279 = VECTOR('',#280,1.); -#280 = DIRECTION('',(0.,1.,0.)); -#281 = ORIENTED_EDGE('',*,*,#250,.F.); -#282 = PLANE('',#283); -#283 = AXIS2_PLACEMENT_3D('',#284,#285,#286); -#284 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#285 = DIRECTION('',(0.,0.,1.)); -#286 = DIRECTION('',(1.,0.,0.)); -#287 = ADVANCED_FACE('',(#288),#294,.T.); -#288 = FACE_BOUND('',#289,.T.); -#289 = EDGE_LOOP('',(#290,#291,#292,#293)); -#290 = ORIENTED_EDGE('',*,*,#78,.F.); -#291 = ORIENTED_EDGE('',*,*,#276,.T.); -#292 = ORIENTED_EDGE('',*,*,#260,.T.); -#293 = ORIENTED_EDGE('',*,*,#228,.F.); -#294 = PLANE('',#295); -#295 = AXIS2_PLACEMENT_3D('',#296,#297,#298); -#296 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#297 = DIRECTION('',(1.,0.,0.)); -#298 = DIRECTION('',(0.,0.,1.)); -#299 = ADVANCED_FACE('',(#300),#325,.T.); -#300 = FACE_BOUND('',#301,.T.); -#301 = EDGE_LOOP('',(#302,#310,#311,#319)); -#302 = ORIENTED_EDGE('',*,*,#303,.F.); -#303 = EDGE_CURVE('',#87,#304,#306,.T.); -#304 = VERTEX_POINT('',#305); -#305 = CARTESIAN_POINT('',(32.703857168398,3.2,-60.78483712899)); -#306 = LINE('',#307,#308); -#307 = CARTESIAN_POINT('',(32.703857168398,3.,-60.78483712899)); -#308 = VECTOR('',#309,1.); -#309 = DIRECTION('',(0.,1.,0.)); -#310 = ORIENTED_EDGE('',*,*,#86,.T.); -#311 = ORIENTED_EDGE('',*,*,#312,.F.); -#312 = EDGE_CURVE('',#313,#89,#315,.T.); -#313 = VERTEX_POINT('',#314); -#314 = CARTESIAN_POINT('',(26.938753236523,3.2,-55.20570756731)); -#315 = LINE('',#316,#317); -#316 = CARTESIAN_POINT('',(26.938753236523,3.,-55.20570756731)); -#317 = VECTOR('',#318,1.); -#318 = DIRECTION('',(0.,-1.,0.)); -#319 = ORIENTED_EDGE('',*,*,#320,.F.); -#320 = EDGE_CURVE('',#304,#313,#321,.T.); -#321 = LINE('',#322,#323); -#322 = CARTESIAN_POINT('',(16.008242280412,3.2,-44.62779994931)); -#323 = VECTOR('',#324,1.); -#324 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#325 = PLANE('',#326); -#326 = AXIS2_PLACEMENT_3D('',#327,#328,#329); -#327 = CARTESIAN_POINT('',(29.704873980143,3.,-57.88259703786)); -#328 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#329 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#330 = ADVANCED_FACE('',(#331),#349,.T.); -#331 = FACE_BOUND('',#332,.T.); -#332 = EDGE_LOOP('',(#333,#341,#342,#343)); -#333 = ORIENTED_EDGE('',*,*,#334,.F.); -#334 = EDGE_CURVE('',#205,#335,#337,.T.); -#335 = VERTEX_POINT('',#336); -#336 = CARTESIAN_POINT('',(26.715163243538,3.2,-66.97315781796)); -#337 = LINE('',#338,#339); -#338 = CARTESIAN_POINT('',(26.715163243538,3.,-66.97315781796)); -#339 = VECTOR('',#340,1.); -#340 = DIRECTION('',(0.,1.,0.)); -#341 = ORIENTED_EDGE('',*,*,#212,.T.); -#342 = ORIENTED_EDGE('',*,*,#303,.T.); -#343 = ORIENTED_EDGE('',*,*,#344,.F.); -#344 = EDGE_CURVE('',#335,#304,#345,.T.); -#345 = LINE('',#346,#347); -#346 = CARTESIAN_POINT('',(30.25240665457,3.2,-63.31800414721)); -#347 = VECTOR('',#348,1.); -#348 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#349 = PLANE('',#350); -#350 = AXIS2_PLACEMENT_3D('',#351,#352,#353); -#351 = CARTESIAN_POINT('',(29.709510205968,3.,-63.87899747347)); -#352 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#353 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#354 = ADVANCED_FACE('',(#355),#373,.T.); -#355 = FACE_BOUND('',#356,.T.); -#356 = EDGE_LOOP('',(#357,#365,#371,#372)); -#357 = ORIENTED_EDGE('',*,*,#358,.F.); -#358 = EDGE_CURVE('',#359,#335,#361,.T.); -#359 = VERTEX_POINT('',#360); -#360 = CARTESIAN_POINT('',(20.532019001374,3.2,-60.98947335481)); -#361 = LINE('',#362,#363); -#362 = CARTESIAN_POINT('',(9.922784884512,3.2,-50.72247862452)); -#363 = VECTOR('',#364,1.); -#364 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#365 = ORIENTED_EDGE('',*,*,#366,.T.); -#366 = EDGE_CURVE('',#359,#197,#367,.T.); -#367 = LINE('',#368,#369); -#368 = CARTESIAN_POINT('',(20.532019001374,3.,-60.98947335481)); -#369 = VECTOR('',#370,1.); -#370 = DIRECTION('',(0.,-1.,0.)); -#371 = ORIENTED_EDGE('',*,*,#204,.T.); -#372 = ORIENTED_EDGE('',*,*,#334,.T.); -#373 = PLANE('',#374); -#374 = AXIS2_PLACEMENT_3D('',#375,#376,#377); -#375 = CARTESIAN_POINT('',(23.522653113203,3.,-63.8836336993)); -#376 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#377 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#378 = ADVANCED_FACE('',(#379),#397,.T.); -#379 = FACE_BOUND('',#380,.T.); -#380 = EDGE_LOOP('',(#381,#389,#390,#391)); -#381 = ORIENTED_EDGE('',*,*,#382,.F.); -#382 = EDGE_CURVE('',#189,#383,#385,.T.); -#383 = VERTEX_POINT('',#384); -#384 = CARTESIAN_POINT('',(-20.53201900137,3.2,-60.98947335481)); -#385 = LINE('',#386,#387); -#386 = CARTESIAN_POINT('',(-20.53201900137,3.,-60.98947335481)); -#387 = VECTOR('',#388,1.); -#388 = DIRECTION('',(0.,1.,0.)); -#389 = ORIENTED_EDGE('',*,*,#196,.T.); -#390 = ORIENTED_EDGE('',*,*,#366,.F.); -#391 = ORIENTED_EDGE('',*,*,#392,.F.); -#392 = EDGE_CURVE('',#383,#359,#393,.T.); -#393 = LINE('',#394,#395); -#394 = CARTESIAN_POINT('',(5.354765181569,3.2,-60.98947335481)); -#395 = VECTOR('',#396,1.); -#396 = DIRECTION('',(1.,0.,0.)); -#397 = PLANE('',#398); -#398 = AXIS2_PLACEMENT_3D('',#399,#400,#401); -#399 = CARTESIAN_POINT('',(10.306473847682,3.,-60.98947335481)); -#400 = DIRECTION('',(0.,0.,1.)); -#401 = DIRECTION('',(0.,-1.,0.)); -#402 = ADVANCED_FACE('',(#403),#421,.F.); -#403 = FACE_BOUND('',#404,.F.); -#404 = EDGE_LOOP('',(#405,#413,#419,#420)); -#405 = ORIENTED_EDGE('',*,*,#406,.F.); -#406 = EDGE_CURVE('',#407,#180,#409,.T.); -#407 = VERTEX_POINT('',#408); -#408 = CARTESIAN_POINT('',(-25.53052705686,3.2,-65.82673637491)); -#409 = LINE('',#410,#411); -#410 = CARTESIAN_POINT('',(-25.53052705686,3.,-65.82673637491)); -#411 = VECTOR('',#412,1.); -#412 = DIRECTION('',(0.,-1.,0.)); -#413 = ORIENTED_EDGE('',*,*,#414,.F.); -#414 = EDGE_CURVE('',#383,#407,#415,.T.); -#415 = LINE('',#416,#417); -#416 = CARTESIAN_POINT('',(-9.454421870603,3.2,-50.26922436104)); -#417 = VECTOR('',#418,1.); -#418 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#419 = ORIENTED_EDGE('',*,*,#382,.F.); -#420 = ORIENTED_EDGE('',*,*,#188,.T.); -#421 = PLANE('',#422); -#422 = AXIS2_PLACEMENT_3D('',#423,#424,#425); -#423 = CARTESIAN_POINT('',(-23.00219525444,3.,-63.37996509944)); -#424 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#425 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#426 = ADVANCED_FACE('',(#427),#446,.F.); -#427 = FACE_BOUND('',#428,.F.); -#428 = EDGE_LOOP('',(#429,#437,#444,#445)); -#429 = ORIENTED_EDGE('',*,*,#430,.F.); -#430 = EDGE_CURVE('',#431,#172,#433,.T.); -#431 = VERTEX_POINT('',#432); -#432 = CARTESIAN_POINT('',(-27.86158468659,3.2,-65.78852163128)); -#433 = LINE('',#434,#435); -#434 = CARTESIAN_POINT('',(-27.86158468659,3.,-65.78852163128)); -#435 = VECTOR('',#436,1.); -#436 = DIRECTION('',(0.,-1.,0.)); -#437 = ORIENTED_EDGE('',*,*,#438,.T.); -#438 = EDGE_CURVE('',#431,#407,#439,.T.); -#439 = CIRCLE('',#440,1.648528137424); -#440 = AXIS2_PLACEMENT_3D('',#441,#442,#443); -#441 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#442 = DIRECTION('',(0.,-1.,0.)); -#443 = DIRECTION('',(-1.,0.,0.)); -#444 = ORIENTED_EDGE('',*,*,#406,.T.); -#445 = ORIENTED_EDGE('',*,*,#179,.F.); -#446 = CYLINDRICAL_SURFACE('',#447,1.648528137424); -#447 = AXIS2_PLACEMENT_3D('',#448,#449,#450); -#448 = CARTESIAN_POINT('',(-26.67694849991,3.,-64.64210018823)); -#449 = DIRECTION('',(0.,-1.,0.)); -#450 = DIRECTION('',(-1.,0.,0.)); -#451 = ADVANCED_FACE('',(#452),#470,.F.); -#452 = FACE_BOUND('',#453,.F.); -#453 = EDGE_LOOP('',(#454,#462,#468,#469)); -#454 = ORIENTED_EDGE('',*,*,#455,.F.); -#455 = EDGE_CURVE('',#456,#163,#458,.T.); -#456 = VERTEX_POINT('',#457); -#457 = CARTESIAN_POINT('',(-29.08766684168,3.2,-64.52156932717)); -#458 = LINE('',#459,#460); -#459 = CARTESIAN_POINT('',(-29.08766684168,3.,-64.52156932717)); -#460 = VECTOR('',#461,1.); -#461 = DIRECTION('',(0.,-1.,0.)); -#462 = ORIENTED_EDGE('',*,*,#463,.F.); -#463 = EDGE_CURVE('',#431,#456,#464,.T.); -#464 = LINE('',#465,#466); -#465 = CARTESIAN_POINT('',(-29.44004200272,3.2,-64.15744811364)); -#466 = VECTOR('',#467,1.); -#467 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#468 = ORIENTED_EDGE('',*,*,#430,.T.); -#469 = ORIENTED_EDGE('',*,*,#171,.T.); -#470 = PLANE('',#471); -#471 = AXIS2_PLACEMENT_3D('',#472,#473,#474); -#472 = CARTESIAN_POINT('',(-28.47462576413,3.,-65.15504547923)); -#473 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#474 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#475 = ADVANCED_FACE('',(#476),#495,.F.); -#476 = FACE_BOUND('',#477,.F.); -#477 = EDGE_LOOP('',(#478,#486,#493,#494)); -#478 = ORIENTED_EDGE('',*,*,#479,.F.); -#479 = EDGE_CURVE('',#480,#155,#482,.T.); -#480 = VERTEX_POINT('',#481); -#481 = CARTESIAN_POINT('',(-28.96712497021,3.2,-57.16864680227)); -#482 = LINE('',#483,#484); -#483 = CARTESIAN_POINT('',(-28.96712497021,3.,-57.16864680227)); -#484 = VECTOR('',#485,1.); -#485 = DIRECTION('',(0.,-1.,0.)); -#486 = ORIENTED_EDGE('',*,*,#487,.T.); -#487 = EDGE_CURVE('',#480,#456,#488,.T.); -#488 = CIRCLE('',#489,5.2); -#489 = AXIS2_PLACEMENT_3D('',#490,#491,#492); -#490 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#491 = DIRECTION('',(0.,-1.,0.)); -#492 = DIRECTION('',(-1.,0.,0.)); -#493 = ORIENTED_EDGE('',*,*,#455,.T.); -#494 = ORIENTED_EDGE('',*,*,#162,.F.); -#495 = CYLINDRICAL_SURFACE('',#496,5.2); -#496 = AXIS2_PLACEMENT_3D('',#497,#498,#499); -#497 = CARTESIAN_POINT('',(-25.35093464349,3.,-60.90537900045)); -#498 = DIRECTION('',(0.,-1.,0.)); -#499 = DIRECTION('',(-1.,0.,0.)); -#500 = ADVANCED_FACE('',(#501),#519,.F.); -#501 = FACE_BOUND('',#502,.F.); -#502 = EDGE_LOOP('',(#503,#511,#517,#518)); -#503 = ORIENTED_EDGE('',*,*,#504,.F.); -#504 = EDGE_CURVE('',#505,#147,#507,.T.); -#505 = VERTEX_POINT('',#506); -#506 = CARTESIAN_POINT('',(-26.93875323652,3.2,-55.20570756731)); -#507 = LINE('',#508,#509); -#508 = CARTESIAN_POINT('',(-26.93875323652,3.,-55.20570756731)); -#509 = VECTOR('',#510,1.); -#510 = DIRECTION('',(0.,-1.,0.)); -#511 = ORIENTED_EDGE('',*,*,#512,.F.); -#512 = EDGE_CURVE('',#480,#505,#513,.T.); -#513 = LINE('',#514,#515); -#514 = CARTESIAN_POINT('',(-14.90185526362,3.2,-43.55710346492)); -#515 = VECTOR('',#516,1.); -#516 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#517 = ORIENTED_EDGE('',*,*,#479,.T.); -#518 = ORIENTED_EDGE('',*,*,#154,.T.); -#519 = PLANE('',#520); -#520 = AXIS2_PLACEMENT_3D('',#521,#522,#523); -#521 = CARTESIAN_POINT('',(-27.90836811563,3.,-56.14404399617)); -#522 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#523 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#524 = ADVANCED_FACE('',(#525),#543,.F.); -#525 = FACE_BOUND('',#526,.F.); -#526 = EDGE_LOOP('',(#527,#535,#541,#542)); -#527 = ORIENTED_EDGE('',*,*,#528,.F.); -#528 = EDGE_CURVE('',#529,#138,#531,.T.); -#529 = VERTEX_POINT('',#530); -#530 = CARTESIAN_POINT('',(-41.17904151244,3.2,-10.52828909594)); -#531 = LINE('',#532,#533); -#532 = CARTESIAN_POINT('',(-41.17904151244,3.,-10.52828909594)); -#533 = VECTOR('',#534,1.); -#534 = DIRECTION('',(0.,-1.,0.)); -#535 = ORIENTED_EDGE('',*,*,#536,.F.); -#536 = EDGE_CURVE('',#505,#529,#537,.T.); -#537 = LINE('',#538,#539); -#538 = CARTESIAN_POINT('',(-32.39120436163,3.2,-38.09921113329)); -#539 = VECTOR('',#540,1.); -#540 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#541 = ORIENTED_EDGE('',*,*,#504,.T.); -#542 = ORIENTED_EDGE('',*,*,#146,.T.); -#543 = PLANE('',#544); -#544 = AXIS2_PLACEMENT_3D('',#545,#546,#547); -#545 = CARTESIAN_POINT('',(-34.04006158346,3.,-32.92609366041)); -#546 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#547 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#548 = ADVANCED_FACE('',(#549),#568,.F.); -#549 = FACE_BOUND('',#550,.F.); -#550 = EDGE_LOOP('',(#551,#559,#566,#567)); -#551 = ORIENTED_EDGE('',*,*,#552,.F.); -#552 = EDGE_CURVE('',#553,#130,#555,.T.); -#553 = VERTEX_POINT('',#554); -#554 = CARTESIAN_POINT('',(-39.69176606491,3.2,-4.408923352436)); -#555 = LINE('',#556,#557); -#556 = CARTESIAN_POINT('',(-39.69176606491,3.,-4.408923352436)); -#557 = VECTOR('',#558,1.); -#558 = DIRECTION('',(0.,-1.,0.)); -#559 = ORIENTED_EDGE('',*,*,#560,.T.); -#560 = EDGE_CURVE('',#553,#529,#561,.T.); -#561 = CIRCLE('',#562,6.054044962965); -#562 = AXIS2_PLACEMENT_3D('',#563,#564,#565); -#563 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#564 = DIRECTION('',(0.,-1.,0.)); -#565 = DIRECTION('',(-1.,0.,0.)); -#566 = ORIENTED_EDGE('',*,*,#528,.T.); -#567 = ORIENTED_EDGE('',*,*,#137,.F.); -#568 = CYLINDRICAL_SURFACE('',#569,6.054044962965); -#569 = AXIS2_PLACEMENT_3D('',#570,#571,#572); -#570 = CARTESIAN_POINT('',(-35.41090981799,3.,-8.689779599357)); -#571 = DIRECTION('',(0.,-1.,0.)); -#572 = DIRECTION('',(-1.,0.,0.)); -#573 = ADVANCED_FACE('',(#574),#592,.F.); -#574 = FACE_BOUND('',#575,.F.); -#575 = EDGE_LOOP('',(#576,#584,#590,#591)); -#576 = ORIENTED_EDGE('',*,*,#577,.F.); -#577 = EDGE_CURVE('',#578,#121,#580,.T.); -#578 = VERTEX_POINT('',#579); -#579 = CARTESIAN_POINT('',(-36.85603142851,3.2,-1.573188716044)); -#580 = LINE('',#581,#582); -#581 = CARTESIAN_POINT('',(-36.85603142851,3.,-1.573188716044)); -#582 = VECTOR('',#583,1.); -#583 = DIRECTION('',(0.,-1.,0.)); -#584 = ORIENTED_EDGE('',*,*,#585,.F.); -#585 = EDGE_CURVE('',#553,#578,#586,.T.); -#586 = LINE('',#587,#588); -#587 = CARTESIAN_POINT('',(-36.19319006079,3.2,-0.910347348321)); -#588 = VECTOR('',#589,1.); -#589 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#590 = ORIENTED_EDGE('',*,*,#552,.T.); -#591 = ORIENTED_EDGE('',*,*,#129,.T.); -#592 = PLANE('',#593); -#593 = AXIS2_PLACEMENT_3D('',#594,#595,#596); -#594 = CARTESIAN_POINT('',(-38.27389874671,3.,-2.99105603424)); -#595 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#596 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#597 = ADVANCED_FACE('',(#598),#617,.F.); -#598 = FACE_BOUND('',#599,.F.); -#599 = EDGE_LOOP('',(#600,#608,#615,#616)); -#600 = ORIENTED_EDGE('',*,*,#601,.F.); -#601 = EDGE_CURVE('',#602,#113,#604,.T.); -#602 = VERTEX_POINT('',#603); -#603 = CARTESIAN_POINT('',(-32.57517518159,3.2,0.2)); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-32.57517518159,3.,0.2)); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(0.,-1.,0.)); -#608 = ORIENTED_EDGE('',*,*,#609,.T.); -#609 = EDGE_CURVE('',#602,#578,#610,.T.); -#610 = CIRCLE('',#611,6.054044962965); -#611 = AXIS2_PLACEMENT_3D('',#612,#613,#614); -#612 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#613 = DIRECTION('',(0.,-1.,0.)); -#614 = DIRECTION('',(-1.,0.,0.)); -#615 = ORIENTED_EDGE('',*,*,#577,.T.); -#616 = ORIENTED_EDGE('',*,*,#120,.F.); -#617 = CYLINDRICAL_SURFACE('',#618,6.054044962965); -#618 = AXIS2_PLACEMENT_3D('',#619,#620,#621); -#619 = CARTESIAN_POINT('',(-32.57517518159,3.,-5.854044962965)); -#620 = DIRECTION('',(0.,-1.,0.)); -#621 = DIRECTION('',(-1.,0.,0.)); -#622 = ADVANCED_FACE('',(#623),#641,.F.); -#623 = FACE_BOUND('',#624,.F.); -#624 = EDGE_LOOP('',(#625,#633,#639,#640)); -#625 = ORIENTED_EDGE('',*,*,#626,.F.); -#626 = EDGE_CURVE('',#627,#105,#629,.T.); -#627 = VERTEX_POINT('',#628); -#628 = CARTESIAN_POINT('',(35.082842712475,3.2,0.2)); -#629 = LINE('',#630,#631); -#630 = CARTESIAN_POINT('',(35.082842712475,3.,0.2)); -#631 = VECTOR('',#632,1.); -#632 = DIRECTION('',(0.,-1.,0.)); -#633 = ORIENTED_EDGE('',*,*,#634,.F.); -#634 = EDGE_CURVE('',#602,#627,#635,.T.); -#635 = LINE('',#636,#637); -#636 = CARTESIAN_POINT('',(-7.942265537672,3.2,0.2)); -#637 = VECTOR('',#638,1.); -#638 = DIRECTION('',(1.,0.,0.)); -#639 = ORIENTED_EDGE('',*,*,#601,.T.); -#640 = ORIENTED_EDGE('',*,*,#112,.T.); -#641 = PLANE('',#642); -#642 = AXIS2_PLACEMENT_3D('',#643,#644,#645); -#643 = CARTESIAN_POINT('',(-16.28758759079,3.,0.2)); -#644 = DIRECTION('',(0.,0.,1.)); -#645 = DIRECTION('',(0.,-1.,0.)); -#646 = ADVANCED_FACE('',(#647),#665,.T.); -#647 = FACE_BOUND('',#648,.T.); -#648 = EDGE_LOOP('',(#649,#657,#658,#659)); -#649 = ORIENTED_EDGE('',*,*,#650,.T.); -#650 = EDGE_CURVE('',#651,#97,#653,.T.); -#651 = VERTEX_POINT('',#652); -#652 = CARTESIAN_POINT('',(42.298608189024,3.2,-7.015765476549)); -#653 = LINE('',#654,#655); -#654 = CARTESIAN_POINT('',(42.298608189024,3.,-7.015765476549)); -#655 = VECTOR('',#656,1.); -#656 = DIRECTION('',(0.,-1.,0.)); -#657 = ORIENTED_EDGE('',*,*,#104,.T.); -#658 = ORIENTED_EDGE('',*,*,#626,.F.); -#659 = ORIENTED_EDGE('',*,*,#660,.F.); -#660 = EDGE_CURVE('',#651,#627,#661,.T.); -#661 = LINE('',#662,#663); -#662 = CARTESIAN_POINT('',(36.596246576251,3.2,-1.313403863776)); -#663 = VECTOR('',#664,1.); -#664 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#665 = PLANE('',#666); -#666 = AXIS2_PLACEMENT_3D('',#667,#668,#669); -#667 = CARTESIAN_POINT('',(38.67695526217,3.,-3.394112549695)); -#668 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#669 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#670 = ADVANCED_FACE('',(#671),#682,.T.); -#671 = FACE_BOUND('',#672,.T.); -#672 = EDGE_LOOP('',(#673,#679,#680,#681)); -#673 = ORIENTED_EDGE('',*,*,#674,.F.); -#674 = EDGE_CURVE('',#313,#651,#675,.T.); -#675 = LINE('',#676,#677); -#676 = CARTESIAN_POINT('',(32.699020781567,3.2,-37.13346923684)); -#677 = VECTOR('',#678,1.); -#678 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#679 = ORIENTED_EDGE('',*,*,#312,.T.); -#680 = ORIENTED_EDGE('',*,*,#96,.T.); -#681 = ORIENTED_EDGE('',*,*,#650,.F.); -#682 = PLANE('',#683); -#683 = AXIS2_PLACEMENT_3D('',#684,#685,#686); -#684 = CARTESIAN_POINT('',(34.581352051556,3.,-31.22785130119)); -#685 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#686 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#687 = ADVANCED_FACE('',(#688,#738,#749,#767,#801),#812,.F.); -#688 = FACE_BOUND('',#689,.F.); -#689 = EDGE_LOOP('',(#690,#700,#708,#716,#724,#732)); -#690 = ORIENTED_EDGE('',*,*,#691,.F.); -#691 = EDGE_CURVE('',#692,#694,#696,.T.); -#692 = VERTEX_POINT('',#693); -#693 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#694 = VERTEX_POINT('',#695); -#695 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#696 = LINE('',#697,#698); -#697 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#698 = VECTOR('',#699,1.); -#699 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#700 = ORIENTED_EDGE('',*,*,#701,.F.); -#701 = EDGE_CURVE('',#702,#692,#704,.T.); -#702 = VERTEX_POINT('',#703); -#703 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#704 = LINE('',#705,#706); -#705 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#706 = VECTOR('',#707,1.); -#707 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#708 = ORIENTED_EDGE('',*,*,#709,.F.); -#709 = EDGE_CURVE('',#710,#702,#712,.T.); -#710 = VERTEX_POINT('',#711); -#711 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#712 = LINE('',#713,#714); -#713 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#714 = VECTOR('',#715,1.); -#715 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#716 = ORIENTED_EDGE('',*,*,#717,.F.); -#717 = EDGE_CURVE('',#718,#710,#720,.T.); -#718 = VERTEX_POINT('',#719); -#719 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#720 = LINE('',#721,#722); -#721 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#722 = VECTOR('',#723,1.); -#723 = DIRECTION('',(1.,0.,0.)); -#724 = ORIENTED_EDGE('',*,*,#725,.F.); -#725 = EDGE_CURVE('',#726,#718,#728,.T.); -#726 = VERTEX_POINT('',#727); -#727 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#728 = LINE('',#729,#730); -#729 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#730 = VECTOR('',#731,1.); -#731 = DIRECTION('',(0.,0.,1.)); -#732 = ORIENTED_EDGE('',*,*,#733,.F.); -#733 = EDGE_CURVE('',#694,#726,#734,.T.); -#734 = LINE('',#735,#736); -#735 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#736 = VECTOR('',#737,1.); -#737 = DIRECTION('',(-1.,0.,0.)); -#738 = FACE_BOUND('',#739,.F.); -#739 = EDGE_LOOP('',(#740)); -#740 = ORIENTED_EDGE('',*,*,#741,.F.); -#741 = EDGE_CURVE('',#742,#742,#744,.T.); -#742 = VERTEX_POINT('',#743); -#743 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#744 = CIRCLE('',#745,4.735522705283); -#745 = AXIS2_PLACEMENT_3D('',#746,#747,#748); -#746 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#747 = DIRECTION('',(-0.,1.,0.)); -#748 = DIRECTION('',(1.,0.,0.)); -#749 = FACE_BOUND('',#750,.F.); -#750 = EDGE_LOOP('',(#751,#752,#753,#754,#755,#756,#757,#758,#759,#760, - #761,#762,#763,#764,#765,#766)); -#751 = ORIENTED_EDGE('',*,*,#536,.T.); -#752 = ORIENTED_EDGE('',*,*,#560,.F.); -#753 = ORIENTED_EDGE('',*,*,#585,.T.); -#754 = ORIENTED_EDGE('',*,*,#609,.F.); -#755 = ORIENTED_EDGE('',*,*,#634,.T.); -#756 = ORIENTED_EDGE('',*,*,#660,.F.); -#757 = ORIENTED_EDGE('',*,*,#674,.F.); -#758 = ORIENTED_EDGE('',*,*,#320,.F.); -#759 = ORIENTED_EDGE('',*,*,#344,.F.); -#760 = ORIENTED_EDGE('',*,*,#358,.F.); -#761 = ORIENTED_EDGE('',*,*,#392,.F.); -#762 = ORIENTED_EDGE('',*,*,#414,.T.); -#763 = ORIENTED_EDGE('',*,*,#438,.F.); -#764 = ORIENTED_EDGE('',*,*,#463,.T.); -#765 = ORIENTED_EDGE('',*,*,#487,.F.); -#766 = ORIENTED_EDGE('',*,*,#512,.T.); -#767 = FACE_BOUND('',#768,.F.); -#768 = EDGE_LOOP('',(#769,#779,#787,#795)); -#769 = ORIENTED_EDGE('',*,*,#770,.F.); -#770 = EDGE_CURVE('',#771,#773,#775,.T.); -#771 = VERTEX_POINT('',#772); -#772 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#773 = VERTEX_POINT('',#774); -#774 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#775 = LINE('',#776,#777); -#776 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#777 = VECTOR('',#778,1.); -#778 = DIRECTION('',(-8.501532861635E-02,0.,-0.996379643459)); -#779 = ORIENTED_EDGE('',*,*,#780,.F.); -#780 = EDGE_CURVE('',#781,#771,#783,.T.); -#781 = VERTEX_POINT('',#782); -#782 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#783 = LINE('',#784,#785); -#784 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#785 = VECTOR('',#786,1.); -#786 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#787 = ORIENTED_EDGE('',*,*,#788,.F.); -#788 = EDGE_CURVE('',#789,#781,#791,.T.); -#789 = VERTEX_POINT('',#790); -#790 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#791 = LINE('',#792,#793); -#792 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#793 = VECTOR('',#794,1.); -#794 = DIRECTION('',(-8.501532861635E-02,0.,0.996379643459)); -#795 = ORIENTED_EDGE('',*,*,#796,.F.); -#796 = EDGE_CURVE('',#773,#789,#797,.T.); -#797 = LINE('',#798,#799); -#798 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#799 = VECTOR('',#800,1.); -#800 = DIRECTION('',(-1.,0.,0.)); -#801 = FACE_BOUND('',#802,.F.); -#802 = EDGE_LOOP('',(#803)); -#803 = ORIENTED_EDGE('',*,*,#804,.F.); -#804 = EDGE_CURVE('',#805,#805,#807,.T.); -#805 = VERTEX_POINT('',#806); -#806 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#807 = CIRCLE('',#808,4.735522705283); -#808 = AXIS2_PLACEMENT_3D('',#809,#810,#811); -#809 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#810 = DIRECTION('',(-0.,1.,0.)); -#811 = DIRECTION('',(1.,0.,0.)); -#812 = PLANE('',#813); -#813 = AXIS2_PLACEMENT_3D('',#814,#815,#816); -#814 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#815 = DIRECTION('',(0.,1.,0.)); -#816 = DIRECTION('',(1.,0.,0.)); -#817 = ADVANCED_FACE('',(#818),#843,.T.); -#818 = FACE_BOUND('',#819,.T.); -#819 = EDGE_LOOP('',(#820,#828,#836,#842)); -#820 = ORIENTED_EDGE('',*,*,#821,.F.); -#821 = EDGE_CURVE('',#822,#692,#824,.T.); -#822 = VERTEX_POINT('',#823); -#823 = CARTESIAN_POINT('',(16.626582997737,0.,-8.940188245231)); -#824 = LINE('',#825,#826); -#825 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#826 = VECTOR('',#827,1.); -#827 = DIRECTION('',(0.,1.,0.)); -#828 = ORIENTED_EDGE('',*,*,#829,.T.); -#829 = EDGE_CURVE('',#822,#830,#832,.T.); -#830 = VERTEX_POINT('',#831); -#831 = CARTESIAN_POINT('',(-5.329070518201E-15,0.,-8.903751135252)); -#832 = LINE('',#833,#834); -#833 = CARTESIAN_POINT('',(-18.54556462154,1.7763568394E-15, - -8.863107566442)); -#834 = VECTOR('',#835,1.); -#835 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#836 = ORIENTED_EDGE('',*,*,#837,.T.); -#837 = EDGE_CURVE('',#830,#694,#838,.T.); -#838 = LINE('',#839,#840); -#839 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#840 = VECTOR('',#841,1.); -#841 = DIRECTION('',(0.,1.,0.)); -#842 = ORIENTED_EDGE('',*,*,#691,.F.); -#843 = PLANE('',#844); -#844 = AXIS2_PLACEMENT_3D('',#845,#846,#847); -#845 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#846 = DIRECTION('',(-2.191520817069E-03,0.,-0.999997598615)); -#847 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#848 = ADVANCED_FACE('',(#849),#867,.T.); -#849 = FACE_BOUND('',#850,.T.); -#850 = EDGE_LOOP('',(#851,#859,#865,#866)); -#851 = ORIENTED_EDGE('',*,*,#852,.F.); -#852 = EDGE_CURVE('',#853,#702,#855,.T.); -#853 = VERTEX_POINT('',#854); -#854 = CARTESIAN_POINT('',(19.029295926024,0.,-17.63009960955)); -#855 = LINE('',#856,#857); -#856 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#857 = VECTOR('',#858,1.); -#858 = DIRECTION('',(0.,1.,0.)); -#859 = ORIENTED_EDGE('',*,*,#860,.T.); -#860 = EDGE_CURVE('',#853,#822,#861,.T.); -#861 = LINE('',#862,#863); -#862 = CARTESIAN_POINT('',(23.053273013696,0.,-32.18365022821)); -#863 = VECTOR('',#864,1.); -#864 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#865 = ORIENTED_EDGE('',*,*,#821,.T.); -#866 = ORIENTED_EDGE('',*,*,#701,.F.); -#867 = PLANE('',#868); -#868 = AXIS2_PLACEMENT_3D('',#869,#870,#871); -#869 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#870 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#871 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#872 = ADVANCED_FACE('',(#873),#891,.T.); -#873 = FACE_BOUND('',#874,.T.); -#874 = EDGE_LOOP('',(#875,#883,#884,#885)); -#875 = ORIENTED_EDGE('',*,*,#876,.T.); -#876 = EDGE_CURVE('',#877,#853,#879,.T.); -#877 = VERTEX_POINT('',#878); -#878 = CARTESIAN_POINT('',(22.059435554995,0.,-3.734519760785)); -#879 = LINE('',#880,#881); -#880 = CARTESIAN_POINT('',(12.741012548745,1.7763568394E-15, - -46.46683800444)); -#881 = VECTOR('',#882,1.); -#882 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#883 = ORIENTED_EDGE('',*,*,#852,.T.); -#884 = ORIENTED_EDGE('',*,*,#709,.F.); -#885 = ORIENTED_EDGE('',*,*,#886,.F.); -#886 = EDGE_CURVE('',#877,#710,#887,.T.); -#887 = LINE('',#888,#889); -#888 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#889 = VECTOR('',#890,1.); -#890 = DIRECTION('',(0.,1.,0.)); -#891 = PLANE('',#892); -#892 = AXIS2_PLACEMENT_3D('',#893,#894,#895); -#893 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#894 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#895 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#896 = ADVANCED_FACE('',(#897),#915,.T.); -#897 = FACE_BOUND('',#898,.T.); -#898 = EDGE_LOOP('',(#899,#907,#908,#909)); -#899 = ORIENTED_EDGE('',*,*,#900,.T.); -#900 = EDGE_CURVE('',#901,#877,#903,.T.); -#901 = VERTEX_POINT('',#902); -#902 = CARTESIAN_POINT('',(-21.72552223146,0.,-3.734519760785)); -#903 = LINE('',#904,#905); -#904 = CARTESIAN_POINT('',(-22.63692080725,0.,-3.734519760785)); -#905 = VECTOR('',#906,1.); -#906 = DIRECTION('',(1.,0.,0.)); -#907 = ORIENTED_EDGE('',*,*,#886,.T.); -#908 = ORIENTED_EDGE('',*,*,#717,.F.); -#909 = ORIENTED_EDGE('',*,*,#910,.F.); -#910 = EDGE_CURVE('',#901,#718,#911,.T.); -#911 = LINE('',#912,#913); -#912 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#913 = VECTOR('',#914,1.); -#914 = DIRECTION('',(0.,1.,0.)); -#915 = PLANE('',#916); -#916 = AXIS2_PLACEMENT_3D('',#917,#918,#919); -#917 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#918 = DIRECTION('',(0.,0.,1.)); -#919 = DIRECTION('',(0.,-1.,0.)); -#920 = ADVANCED_FACE('',(#921),#939,.T.); -#921 = FACE_BOUND('',#922,.T.); -#922 = EDGE_LOOP('',(#923,#931,#932,#933)); -#923 = ORIENTED_EDGE('',*,*,#924,.T.); -#924 = EDGE_CURVE('',#925,#901,#927,.T.); -#925 = VERTEX_POINT('',#926); -#926 = CARTESIAN_POINT('',(-21.72552223146,0.,-8.903751135252)); -#927 = LINE('',#928,#929); -#928 = CARTESIAN_POINT('',(-21.72552223146,0.,-38.64614663299)); -#929 = VECTOR('',#930,1.); -#930 = DIRECTION('',(0.,0.,1.)); -#931 = ORIENTED_EDGE('',*,*,#910,.T.); -#932 = ORIENTED_EDGE('',*,*,#725,.F.); -#933 = ORIENTED_EDGE('',*,*,#934,.F.); -#934 = EDGE_CURVE('',#925,#726,#935,.T.); -#935 = LINE('',#936,#937); -#936 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#937 = VECTOR('',#938,1.); -#938 = DIRECTION('',(0.,1.,0.)); -#939 = PLANE('',#940); -#940 = AXIS2_PLACEMENT_3D('',#941,#942,#943); -#941 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#942 = DIRECTION('',(-1.,0.,0.)); -#943 = DIRECTION('',(0.,1.,0.)); -#944 = ADVANCED_FACE('',(#945),#956,.T.); -#945 = FACE_BOUND('',#946,.T.); -#946 = EDGE_LOOP('',(#947,#953,#954,#955)); -#947 = ORIENTED_EDGE('',*,*,#948,.T.); -#948 = EDGE_CURVE('',#830,#925,#949,.T.); -#949 = LINE('',#950,#951); -#950 = CARTESIAN_POINT('',(-28.21385794834,0.,-8.903751135252)); -#951 = VECTOR('',#952,1.); -#952 = DIRECTION('',(-1.,0.,0.)); -#953 = ORIENTED_EDGE('',*,*,#934,.T.); -#954 = ORIENTED_EDGE('',*,*,#733,.F.); -#955 = ORIENTED_EDGE('',*,*,#837,.F.); -#956 = PLANE('',#957); -#957 = AXIS2_PLACEMENT_3D('',#958,#959,#960); -#958 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#959 = DIRECTION('',(0.,0.,-1.)); -#960 = DIRECTION('',(0.,1.,0.)); -#961 = ADVANCED_FACE('',(#962),#981,.T.); -#962 = FACE_BOUND('',#963,.T.); -#963 = EDGE_LOOP('',(#964,#973,#979,#980)); -#964 = ORIENTED_EDGE('',*,*,#965,.T.); -#965 = EDGE_CURVE('',#966,#966,#968,.T.); -#966 = VERTEX_POINT('',#967); -#967 = CARTESIAN_POINT('',(21.163799345768,0.,-48.00951684793)); -#968 = CIRCLE('',#969,4.735522705283); -#969 = AXIS2_PLACEMENT_3D('',#970,#971,#972); -#970 = CARTESIAN_POINT('',(16.428276640485,0.,-48.00951684793)); -#971 = DIRECTION('',(-0.,1.,0.)); -#972 = DIRECTION('',(1.,0.,0.)); -#973 = ORIENTED_EDGE('',*,*,#974,.T.); -#974 = EDGE_CURVE('',#966,#742,#975,.T.); -#975 = LINE('',#976,#977); -#976 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#977 = VECTOR('',#978,1.); -#978 = DIRECTION('',(0.,1.,0.)); -#979 = ORIENTED_EDGE('',*,*,#741,.F.); -#980 = ORIENTED_EDGE('',*,*,#974,.F.); -#981 = CYLINDRICAL_SURFACE('',#982,4.735522705283); -#982 = AXIS2_PLACEMENT_3D('',#983,#984,#985); -#983 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#984 = DIRECTION('',(0.,1.,0.)); -#985 = DIRECTION('',(1.,0.,0.)); -#986 = ADVANCED_FACE('',(#987),#1012,.F.); -#987 = FACE_BOUND('',#988,.F.); -#988 = EDGE_LOOP('',(#989,#999,#1005,#1006)); -#989 = ORIENTED_EDGE('',*,*,#990,.T.); -#990 = EDGE_CURVE('',#991,#993,#995,.T.); -#991 = VERTEX_POINT('',#992); -#992 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#993 = VERTEX_POINT('',#994); -#994 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#995 = LINE('',#996,#997); -#996 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#997 = VECTOR('',#998,1.); -#998 = DIRECTION('',(5.275122655166E-17,0.227455280238,0.97378852709)); -#999 = ORIENTED_EDGE('',*,*,#1000,.F.); -#1000 = EDGE_CURVE('',#771,#993,#1001,.T.); -#1001 = LINE('',#1002,#1003); -#1002 = CARTESIAN_POINT('',(5.649679875255,3.602918464526, - -13.21082950266)); -#1003 = VECTOR('',#1004,1.); -#1004 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#1005 = ORIENTED_EDGE('',*,*,#770,.T.); -#1006 = ORIENTED_EDGE('',*,*,#1007,.T.); -#1007 = EDGE_CURVE('',#773,#991,#1008,.T.); -#1008 = LINE('',#1009,#1010); -#1009 = CARTESIAN_POINT('',(1.103762571829,7.940067898719, - -47.92064259636)); -#1010 = VECTOR('',#1011,1.); -#1011 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#1012 = PLANE('',#1013); -#1013 = AXIS2_PLACEMENT_3D('',#1014,#1015,#1016); -#1014 = CARTESIAN_POINT('',(5.823691883056,3.068404028665, - -13.45978839622)); -#1015 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1016 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487824E-02) - ); -#1017 = ADVANCED_FACE('',(#1018),#1028,.F.); -#1018 = FACE_BOUND('',#1019,.F.); -#1019 = EDGE_LOOP('',(#1020,#1021,#1027)); -#1020 = ORIENTED_EDGE('',*,*,#1000,.T.); -#1021 = ORIENTED_EDGE('',*,*,#1022,.T.); -#1022 = EDGE_CURVE('',#993,#781,#1023,.T.); -#1023 = LINE('',#1024,#1025); -#1024 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#1025 = VECTOR('',#1026,1.); -#1026 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#1027 = ORIENTED_EDGE('',*,*,#780,.T.); -#1028 = PLANE('',#1029); -#1029 = AXIS2_PLACEMENT_3D('',#1030,#1031,#1032); -#1030 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -13.01628215822)); -#1031 = DIRECTION('',(2.881637632171E-16,0.342020143326,0.939692620786) - ); -#1032 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326 - )); -#1033 = ADVANCED_FACE('',(#1034),#1045,.F.); -#1034 = FACE_BOUND('',#1035,.F.); -#1035 = EDGE_LOOP('',(#1036,#1037,#1038,#1039)); -#1036 = ORIENTED_EDGE('',*,*,#788,.T.); -#1037 = ORIENTED_EDGE('',*,*,#1022,.F.); -#1038 = ORIENTED_EDGE('',*,*,#990,.F.); -#1039 = ORIENTED_EDGE('',*,*,#1040,.F.); -#1040 = EDGE_CURVE('',#789,#991,#1041,.T.); -#1041 = LINE('',#1042,#1043); -#1042 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#1043 = VECTOR('',#1044,1.); -#1044 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#1045 = PLANE('',#1046); -#1046 = AXIS2_PLACEMENT_3D('',#1047,#1048,#1049); -#1047 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#1048 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1049 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487824E-02) - ); -#1050 = ADVANCED_FACE('',(#1051),#1056,.F.); -#1051 = FACE_BOUND('',#1052,.F.); -#1052 = EDGE_LOOP('',(#1053,#1054,#1055)); -#1053 = ORIENTED_EDGE('',*,*,#1040,.T.); -#1054 = ORIENTED_EDGE('',*,*,#1007,.F.); -#1055 = ORIENTED_EDGE('',*,*,#796,.T.); -#1056 = PLANE('',#1057); -#1057 = AXIS2_PLACEMENT_3D('',#1058,#1059,#1060); -#1058 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -49.69378323641)); -#1059 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#1060 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#1061 = ADVANCED_FACE('',(#1062),#1081,.T.); -#1062 = FACE_BOUND('',#1063,.T.); -#1063 = EDGE_LOOP('',(#1064,#1073,#1079,#1080)); -#1064 = ORIENTED_EDGE('',*,*,#1065,.T.); -#1065 = EDGE_CURVE('',#1066,#1066,#1068,.T.); -#1066 = VERTEX_POINT('',#1067); -#1067 = CARTESIAN_POINT('',(-11.6927539352,0.,-48.00951684793)); -#1068 = CIRCLE('',#1069,4.735522705283); -#1069 = AXIS2_PLACEMENT_3D('',#1070,#1071,#1072); -#1070 = CARTESIAN_POINT('',(-16.42827664048,0.,-48.00951684793)); -#1071 = DIRECTION('',(-0.,1.,0.)); -#1072 = DIRECTION('',(1.,0.,0.)); -#1073 = ORIENTED_EDGE('',*,*,#1074,.T.); -#1074 = EDGE_CURVE('',#1066,#805,#1075,.T.); -#1075 = LINE('',#1076,#1077); -#1076 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#1077 = VECTOR('',#1078,1.); -#1078 = DIRECTION('',(0.,1.,0.)); -#1079 = ORIENTED_EDGE('',*,*,#804,.F.); -#1080 = ORIENTED_EDGE('',*,*,#1074,.F.); -#1081 = CYLINDRICAL_SURFACE('',#1082,4.735522705283); -#1082 = AXIS2_PLACEMENT_3D('',#1083,#1084,#1085); -#1083 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#1084 = DIRECTION('',(0.,1.,0.)); -#1085 = DIRECTION('',(1.,0.,0.)); -#1086 = ADVANCED_FACE('',(#1087),#1095,.F.); -#1087 = FACE_BOUND('',#1088,.F.); -#1088 = EDGE_LOOP('',(#1089,#1090,#1091,#1092,#1093,#1094)); -#1089 = ORIENTED_EDGE('',*,*,#860,.T.); -#1090 = ORIENTED_EDGE('',*,*,#829,.T.); -#1091 = ORIENTED_EDGE('',*,*,#948,.T.); -#1092 = ORIENTED_EDGE('',*,*,#924,.T.); -#1093 = ORIENTED_EDGE('',*,*,#900,.T.); -#1094 = ORIENTED_EDGE('',*,*,#876,.T.); -#1095 = PLANE('',#1096); -#1096 = AXIS2_PLACEMENT_3D('',#1097,#1098,#1099); -#1097 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1098 = DIRECTION('',(0.,1.,0.)); -#1099 = DIRECTION('',(0.,0.,1.)); -#1100 = ADVANCED_FACE('',(#1101),#1104,.F.); -#1101 = FACE_BOUND('',#1102,.F.); -#1102 = EDGE_LOOP('',(#1103)); -#1103 = ORIENTED_EDGE('',*,*,#965,.T.); -#1104 = PLANE('',#1105); -#1105 = AXIS2_PLACEMENT_3D('',#1106,#1107,#1108); -#1106 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1107 = DIRECTION('',(0.,1.,0.)); -#1108 = DIRECTION('',(0.,0.,1.)); -#1109 = ADVANCED_FACE('',(#1110),#1113,.F.); -#1110 = FACE_BOUND('',#1111,.F.); -#1111 = EDGE_LOOP('',(#1112)); -#1112 = ORIENTED_EDGE('',*,*,#1065,.T.); -#1113 = PLANE('',#1114); -#1114 = AXIS2_PLACEMENT_3D('',#1115,#1116,#1117); -#1115 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1116 = DIRECTION('',(0.,1.,0.)); -#1117 = DIRECTION('',(0.,0.,1.)); -#1118 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1122)) -GLOBAL_UNIT_ASSIGNED_CONTEXT((#1119,#1120,#1121)) REPRESENTATION_CONTEXT -('Context #1','3D Context with UNIT and UNCERTAINTY') ); -#1119 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#1120 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#1121 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#1122 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-05),#1119, - 'distance_accuracy_value','confusion accuracy'); -#1123 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.step b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.step deleted file mode 100644 index e6575701e4..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.step +++ /dev/null @@ -1,1048 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T11:06:23',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 1', - 'Open CASCADE STEP translator 7.8 1','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#976); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#157,#188,#212,#236,#261,#285,#310,#334,#358, - #383,#407,#432,#456,#480,#504,#528,#545,#675,#706,#730,#754,#778, - #802,#819,#850,#866,#882,#894,#919,#944,#958,#967)); -#17 = ADVANCED_FACE('',(#18),#152,.T.); -#18 = FACE_BOUND('',#19,.T.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62,#70,#79,#87,#96,#104,#112, - #121,#129,#138,#146)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(26.824640127118,20.8572529153,-55.23443461327) - ); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(42.184838000445,20.8572529153,-7.043416644207) - ); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(28.89442018934,20.8572529153,-48.74071565254) - ); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#30 = ORIENTED_EDGE('',*,*,#31,.F.); -#31 = EDGE_CURVE('',#32,#22,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(32.56245481215,20.8572529153,-60.7871552419)); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(12.092418778801,20.8572529153,-40.97745458223) - ); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#38 = ORIENTED_EDGE('',*,*,#39,.F.); -#39 = EDGE_CURVE('',#40,#32,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(26.712845130625,20.8572529153,-66.83175546171) - ); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(11.149878706433,20.8572529153,-82.91349687528) - ); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#48,#40,#50,.T.); -#48 = VERTEX_POINT('',#49); -#49 = CARTESIAN_POINT('',(20.57248334837,20.8572529153,-60.88947335481) - ); -#50 = LINE('',#51,#52); -#51 = CARTESIAN_POINT('',(9.111716439792,20.8572529153,-49.79841511636) - ); -#52 = VECTOR('',#53,1.); -#53 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#54 = ORIENTED_EDGE('',*,*,#55,.F.); -#55 = EDGE_CURVE('',#56,#48,#58,.T.); -#56 = VERTEX_POINT('',#57); -#57 = CARTESIAN_POINT('',(-20.57248334837,20.8572529153,-60.88947335481) - ); -#58 = LINE('',#59,#60); -#59 = CARTESIAN_POINT('',(-12.44623571629,20.8572529153,-60.88947335481) - ); -#60 = VECTOR('',#61,1.); -#61 = DIRECTION('',(1.,0.,0.)); -#62 = ORIENTED_EDGE('',*,*,#63,.T.); -#63 = EDGE_CURVE('',#56,#64,#66,.T.); -#64 = VERTEX_POINT('',#65); -#65 = CARTESIAN_POINT('',(-25.60006917852,20.8572529153,-65.75487614033) - ); -#66 = LINE('',#67,#68); -#67 = CARTESIAN_POINT('',(-32.03294606502,20.8572529153,-71.98023721416) - ); -#68 = VECTOR('',#69,1.); -#69 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#70 = ORIENTED_EDGE('',*,*,#71,.F.); -#71 = EDGE_CURVE('',#72,#64,#74,.T.); -#72 = VERTEX_POINT('',#73); -#73 = CARTESIAN_POINT('',(-27.78972445201,20.8572529153,-65.71897950961) - ); -#74 = CIRCLE('',#75,1.548528137424); -#75 = AXIS2_PLACEMENT_3D('',#76,#77,#78); -#76 = CARTESIAN_POINT('',(-26.67694849991,20.8572529153,-64.64210018823) - ); -#77 = DIRECTION('',(0.,-1.,0.)); -#78 = DIRECTION('',(1.,0.,0.)); -#79 = ORIENTED_EDGE('',*,*,#80,.T.); -#80 = EDGE_CURVE('',#72,#81,#83,.T.); -#81 = VERTEX_POINT('',#82); -#82 = CARTESIAN_POINT('',(-29.01580660709,20.8572529153,-64.4520272055) - ); -#83 = LINE('',#84,#85); -#84 = CARTESIAN_POINT('',(-31.36389178357,20.8572529153,-62.02567109858) - ); -#85 = VECTOR('',#86,1.); -#86 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#87 = ORIENTED_EDGE('',*,*,#88,.F.); -#88 = EDGE_CURVE('',#89,#81,#91,.T.); -#89 = VERTEX_POINT('',#90); -#90 = CARTESIAN_POINT('',(-28.89758284854,20.8572529153,-57.24050703685) - ); -#91 = CIRCLE('',#92,5.1); -#92 = AXIS2_PLACEMENT_3D('',#93,#94,#95); -#93 = CARTESIAN_POINT('',(-25.35093464349,20.8572529153,-60.90537900045) - ); -#94 = DIRECTION('',(0.,-1.,0.)); -#95 = DIRECTION('',(1.,0.,0.)); -#96 = ORIENTED_EDGE('',*,*,#97,.T.); -#97 = EDGE_CURVE('',#89,#98,#100,.T.); -#98 = VERTEX_POINT('',#99); -#99 = CARTESIAN_POINT('',(-26.82464012711,20.8572529153,-55.23443461327) - ); -#100 = LINE('',#101,#102); -#101 = CARTESIAN_POINT('',(-35.57003638008,20.8572529153,-63.69771634073 - )); -#102 = VECTOR('',#103,1.); -#103 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#104 = ORIENTED_EDGE('',*,*,#105,.T.); -#105 = EDGE_CURVE('',#98,#106,#108,.T.); -#106 = VERTEX_POINT('',#107); -#107 = CARTESIAN_POINT('',(-41.08376419406,20.8572529153,-10.49792081311 - )); -#108 = LINE('',#109,#110); -#109 = CARTESIAN_POINT('',(-32.53680963915,20.8572529153,-37.31309884227 - )); -#110 = VECTOR('',#111,1.); -#111 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#112 = ORIENTED_EDGE('',*,*,#113,.F.); -#113 = EDGE_CURVE('',#114,#106,#116,.T.); -#114 = VERTEX_POINT('',#115); -#115 = CARTESIAN_POINT('',(-39.62105538679,20.8572529153,-4.479634030555 - )); -#116 = CIRCLE('',#117,5.954044962965); -#117 = AXIS2_PLACEMENT_3D('',#118,#119,#120); -#118 = CARTESIAN_POINT('',(-35.41090981799,20.8572529153,-8.689779599357 - )); -#119 = DIRECTION('',(0.,-1.,0.)); -#120 = DIRECTION('',(1.,0.,0.)); -#121 = ORIENTED_EDGE('',*,*,#122,.T.); -#122 = EDGE_CURVE('',#114,#123,#125,.T.); -#123 = VERTEX_POINT('',#124); -#124 = CARTESIAN_POINT('',(-36.7853207504,20.8572529153,-1.643899394163) - ); -#125 = LINE('',#126,#127); -#126 = CARTESIAN_POINT('',(-56.28754386398,20.8572529153,-21.14612250775 - )); -#127 = VECTOR('',#128,1.); -#128 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#129 = ORIENTED_EDGE('',*,*,#130,.F.); -#130 = EDGE_CURVE('',#131,#123,#133,.T.); -#131 = VERTEX_POINT('',#132); -#132 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153, - 9.999999999998E-02)); -#133 = CIRCLE('',#134,5.954044962965); -#134 = AXIS2_PLACEMENT_3D('',#135,#136,#137); -#135 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153,-5.854044962965 - )); -#136 = DIRECTION('',(0.,-1.,0.)); -#137 = DIRECTION('',(1.,0.,0.)); -#138 = ORIENTED_EDGE('',*,*,#139,.T.); -#139 = EDGE_CURVE('',#131,#140,#142,.T.); -#140 = VERTEX_POINT('',#141); -#141 = CARTESIAN_POINT('',(35.041421356237,20.8572529153,0.1)); -#142 = LINE('',#143,#144); -#143 = CARTESIAN_POINT('',(-5.211766712356,20.8572529153,0.1)); -#144 = VECTOR('',#145,1.); -#145 = DIRECTION('',(1.,0.,0.)); -#146 = ORIENTED_EDGE('',*,*,#147,.F.); -#147 = EDGE_CURVE('',#24,#140,#148,.T.); -#148 = LINE('',#149,#150); -#149 = CARTESIAN_POINT('',(32.68311677643,20.8572529153,2.458304579807) - ); -#150 = VECTOR('',#151,1.); -#151 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#152 = PLANE('',#153); -#153 = AXIS2_PLACEMENT_3D('',#154,#155,#156); -#154 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796 - )); -#155 = DIRECTION('',(0.,1.,0.)); -#156 = DIRECTION('',(0.,0.,1.)); -#157 = ADVANCED_FACE('',(#158),#183,.F.); -#158 = FACE_BOUND('',#159,.F.); -#159 = EDGE_LOOP('',(#160,#170,#176,#177)); -#160 = ORIENTED_EDGE('',*,*,#161,.T.); -#161 = EDGE_CURVE('',#162,#164,#166,.T.); -#162 = VERTEX_POINT('',#163); -#163 = CARTESIAN_POINT('',(26.824640127118,3.2,-55.23443461327)); -#164 = VERTEX_POINT('',#165); -#165 = CARTESIAN_POINT('',(42.184838000445,3.2,-7.043416644207)); -#166 = LINE('',#167,#168); -#167 = CARTESIAN_POINT('',(36.45312509682,3.2,-25.02606776693)); -#168 = VECTOR('',#169,1.); -#169 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#170 = ORIENTED_EDGE('',*,*,#171,.T.); -#171 = EDGE_CURVE('',#164,#24,#172,.T.); -#172 = LINE('',#173,#174); -#173 = CARTESIAN_POINT('',(42.184838000445,-5.,-7.043416644207)); -#174 = VECTOR('',#175,1.); -#175 = DIRECTION('',(0.,1.,0.)); -#176 = ORIENTED_EDGE('',*,*,#21,.F.); -#177 = ORIENTED_EDGE('',*,*,#178,.F.); -#178 = EDGE_CURVE('',#162,#22,#179,.T.); -#179 = LINE('',#180,#181); -#180 = CARTESIAN_POINT('',(26.824640127118,-5.,-55.23443461327)); -#181 = VECTOR('',#182,1.); -#182 = DIRECTION('',(0.,1.,0.)); -#183 = PLANE('',#184); -#184 = AXIS2_PLACEMENT_3D('',#185,#186,#187); -#185 = CARTESIAN_POINT('',(42.184838000445,-5.,-7.043416644207)); -#186 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#187 = DIRECTION('',(-0.30368282823,0.,-0.952773183837)); -#188 = ADVANCED_FACE('',(#189),#207,.F.); -#189 = FACE_BOUND('',#190,.F.); -#190 = EDGE_LOOP('',(#191,#199,#205,#206)); -#191 = ORIENTED_EDGE('',*,*,#192,.T.); -#192 = EDGE_CURVE('',#164,#193,#195,.T.); -#193 = VERTEX_POINT('',#194); -#194 = CARTESIAN_POINT('',(35.041421356237,3.2,0.1)); -#195 = LINE('',#196,#197); -#196 = CARTESIAN_POINT('',(34.743124284224,3.2,0.398297072013)); -#197 = VECTOR('',#198,1.); -#198 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#199 = ORIENTED_EDGE('',*,*,#200,.T.); -#200 = EDGE_CURVE('',#193,#140,#201,.T.); -#201 = LINE('',#202,#203); -#202 = CARTESIAN_POINT('',(35.041421356237,-5.,0.1)); -#203 = VECTOR('',#204,1.); -#204 = DIRECTION('',(0.,1.,0.)); -#205 = ORIENTED_EDGE('',*,*,#147,.F.); -#206 = ORIENTED_EDGE('',*,*,#171,.F.); -#207 = PLANE('',#208); -#208 = AXIS2_PLACEMENT_3D('',#209,#210,#211); -#209 = CARTESIAN_POINT('',(35.041421356237,-5.,9.999999999998E-02)); -#210 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#211 = DIRECTION('',(0.707106781187,0.,-0.707106781187)); -#212 = ADVANCED_FACE('',(#213),#231,.T.); -#213 = FACE_BOUND('',#214,.T.); -#214 = EDGE_LOOP('',(#215,#223,#224,#225)); -#215 = ORIENTED_EDGE('',*,*,#216,.T.); -#216 = EDGE_CURVE('',#217,#193,#219,.T.); -#217 = VERTEX_POINT('',#218); -#218 = CARTESIAN_POINT('',(-32.57517518159,3.2,9.999999999998E-02)); -#219 = LINE('',#220,#221); -#220 = CARTESIAN_POINT('',(17.722238935846,3.2,0.1)); -#221 = VECTOR('',#222,1.); -#222 = DIRECTION('',(1.,0.,0.)); -#223 = ORIENTED_EDGE('',*,*,#200,.T.); -#224 = ORIENTED_EDGE('',*,*,#139,.F.); -#225 = ORIENTED_EDGE('',*,*,#226,.F.); -#226 = EDGE_CURVE('',#217,#131,#227,.T.); -#227 = LINE('',#228,#229); -#228 = CARTESIAN_POINT('',(-32.57517518159,-5.,9.999999999998E-02)); -#229 = VECTOR('',#230,1.); -#230 = DIRECTION('',(0.,1.,0.)); -#231 = PLANE('',#232); -#232 = AXIS2_PLACEMENT_3D('',#233,#234,#235); -#233 = CARTESIAN_POINT('',(35.041421356237,-5.,0.1)); -#234 = DIRECTION('',(0.,0.,1.)); -#235 = DIRECTION('',(-1.,0.,0.)); -#236 = ADVANCED_FACE('',(#237),#256,.T.); -#237 = FACE_BOUND('',#238,.F.); -#238 = EDGE_LOOP('',(#239,#248,#254,#255)); -#239 = ORIENTED_EDGE('',*,*,#240,.T.); -#240 = EDGE_CURVE('',#217,#241,#243,.T.); -#241 = VERTEX_POINT('',#242); -#242 = CARTESIAN_POINT('',(-36.7853207504,3.2,-1.643899394163)); -#243 = CIRCLE('',#244,5.954044962965); -#244 = AXIS2_PLACEMENT_3D('',#245,#246,#247); -#245 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#246 = DIRECTION('',(0.,-1.,0.)); -#247 = DIRECTION('',(1.,0.,0.)); -#248 = ORIENTED_EDGE('',*,*,#249,.T.); -#249 = EDGE_CURVE('',#241,#123,#250,.T.); -#250 = LINE('',#251,#252); -#251 = CARTESIAN_POINT('',(-36.7853207504,-5.,-1.643899394163)); -#252 = VECTOR('',#253,1.); -#253 = DIRECTION('',(0.,1.,0.)); -#254 = ORIENTED_EDGE('',*,*,#130,.F.); -#255 = ORIENTED_EDGE('',*,*,#226,.F.); -#256 = CYLINDRICAL_SURFACE('',#257,5.954044962965); -#257 = AXIS2_PLACEMENT_3D('',#258,#259,#260); -#258 = CARTESIAN_POINT('',(-32.57517518159,-5.,-5.854044962965)); -#259 = DIRECTION('',(0.,-1.,0.)); -#260 = DIRECTION('',(1.,0.,0.)); -#261 = ADVANCED_FACE('',(#262),#280,.T.); -#262 = FACE_BOUND('',#263,.T.); -#263 = EDGE_LOOP('',(#264,#272,#273,#274)); -#264 = ORIENTED_EDGE('',*,*,#265,.T.); -#265 = EDGE_CURVE('',#266,#241,#268,.T.); -#266 = VERTEX_POINT('',#267); -#267 = CARTESIAN_POINT('',(-39.62105538679,3.2,-4.479634030555)); -#268 = LINE('',#269,#270); -#269 = CARTESIAN_POINT('',(-35.41354572357,3.2,-0.272124367341)); -#270 = VECTOR('',#271,1.); -#271 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#272 = ORIENTED_EDGE('',*,*,#249,.T.); -#273 = ORIENTED_EDGE('',*,*,#122,.F.); -#274 = ORIENTED_EDGE('',*,*,#275,.F.); -#275 = EDGE_CURVE('',#266,#114,#276,.T.); -#276 = LINE('',#277,#278); -#277 = CARTESIAN_POINT('',(-39.62105538679,-5.,-4.479634030555)); -#278 = VECTOR('',#279,1.); -#279 = DIRECTION('',(0.,1.,0.)); -#280 = PLANE('',#281); -#281 = AXIS2_PLACEMENT_3D('',#282,#283,#284); -#282 = CARTESIAN_POINT('',(-36.7853207504,-5.,-1.643899394163)); -#283 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#284 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#285 = ADVANCED_FACE('',(#286),#305,.T.); -#286 = FACE_BOUND('',#287,.F.); -#287 = EDGE_LOOP('',(#288,#297,#303,#304)); -#288 = ORIENTED_EDGE('',*,*,#289,.T.); -#289 = EDGE_CURVE('',#266,#290,#292,.T.); -#290 = VERTEX_POINT('',#291); -#291 = CARTESIAN_POINT('',(-41.08376419406,3.2,-10.49792081311)); -#292 = CIRCLE('',#293,5.954044962965); -#293 = AXIS2_PLACEMENT_3D('',#294,#295,#296); -#294 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#295 = DIRECTION('',(0.,-1.,0.)); -#296 = DIRECTION('',(1.,0.,0.)); -#297 = ORIENTED_EDGE('',*,*,#298,.T.); -#298 = EDGE_CURVE('',#290,#106,#299,.T.); -#299 = LINE('',#300,#301); -#300 = CARTESIAN_POINT('',(-41.08376419406,-5.,-10.49792081311)); -#301 = VECTOR('',#302,1.); -#302 = DIRECTION('',(0.,1.,0.)); -#303 = ORIENTED_EDGE('',*,*,#113,.F.); -#304 = ORIENTED_EDGE('',*,*,#275,.F.); -#305 = CYLINDRICAL_SURFACE('',#306,5.954044962965); -#306 = AXIS2_PLACEMENT_3D('',#307,#308,#309); -#307 = CARTESIAN_POINT('',(-35.41090981799,-5.,-8.689779599357)); -#308 = DIRECTION('',(0.,-1.,0.)); -#309 = DIRECTION('',(1.,0.,0.)); -#310 = ADVANCED_FACE('',(#311),#329,.T.); -#311 = FACE_BOUND('',#312,.T.); -#312 = EDGE_LOOP('',(#313,#321,#322,#323)); -#313 = ORIENTED_EDGE('',*,*,#314,.T.); -#314 = EDGE_CURVE('',#315,#290,#317,.T.); -#315 = VERTEX_POINT('',#316); -#316 = CARTESIAN_POINT('',(-26.82464012711,3.2,-55.23443461327)); -#317 = LINE('',#318,#319); -#318 = CARTESIAN_POINT('',(-35.86541700774,3.2,-26.86994056823)); -#319 = VECTOR('',#320,1.); -#320 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#321 = ORIENTED_EDGE('',*,*,#298,.T.); -#322 = ORIENTED_EDGE('',*,*,#105,.F.); -#323 = ORIENTED_EDGE('',*,*,#324,.F.); -#324 = EDGE_CURVE('',#315,#98,#325,.T.); -#325 = LINE('',#326,#327); -#326 = CARTESIAN_POINT('',(-26.82464012711,-5.,-55.23443461327)); -#327 = VECTOR('',#328,1.); -#328 = DIRECTION('',(0.,1.,0.)); -#329 = PLANE('',#330); -#330 = AXIS2_PLACEMENT_3D('',#331,#332,#333); -#331 = CARTESIAN_POINT('',(-41.08376419406,-5.,-10.49792081311)); -#332 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#333 = DIRECTION('',(0.30368282823,0.,-0.952773183837)); -#334 = ADVANCED_FACE('',(#335),#353,.T.); -#335 = FACE_BOUND('',#336,.T.); -#336 = EDGE_LOOP('',(#337,#345,#346,#347)); -#337 = ORIENTED_EDGE('',*,*,#338,.T.); -#338 = EDGE_CURVE('',#339,#315,#341,.T.); -#339 = VERTEX_POINT('',#340); -#340 = CARTESIAN_POINT('',(-28.89758284854,3.2,-57.24050703685)); -#341 = LINE('',#342,#343); -#342 = CARTESIAN_POINT('',(-14.32522020853,3.2,-43.13822889076)); -#343 = VECTOR('',#344,1.); -#344 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#345 = ORIENTED_EDGE('',*,*,#324,.T.); -#346 = ORIENTED_EDGE('',*,*,#97,.F.); -#347 = ORIENTED_EDGE('',*,*,#348,.F.); -#348 = EDGE_CURVE('',#339,#89,#349,.T.); -#349 = LINE('',#350,#351); -#350 = CARTESIAN_POINT('',(-28.89758284854,-5.,-57.24050703685)); -#351 = VECTOR('',#352,1.); -#352 = DIRECTION('',(0.,1.,0.)); -#353 = PLANE('',#354); -#354 = AXIS2_PLACEMENT_3D('',#355,#356,#357); -#355 = CARTESIAN_POINT('',(-26.82464012711,-5.,-55.23443461327)); -#356 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#357 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#358 = ADVANCED_FACE('',(#359),#378,.T.); -#359 = FACE_BOUND('',#360,.F.); -#360 = EDGE_LOOP('',(#361,#370,#376,#377)); -#361 = ORIENTED_EDGE('',*,*,#362,.T.); -#362 = EDGE_CURVE('',#339,#363,#365,.T.); -#363 = VERTEX_POINT('',#364); -#364 = CARTESIAN_POINT('',(-29.01580660709,3.2,-64.4520272055)); -#365 = CIRCLE('',#366,5.1); -#366 = AXIS2_PLACEMENT_3D('',#367,#368,#369); -#367 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#368 = DIRECTION('',(0.,-1.,0.)); -#369 = DIRECTION('',(1.,0.,0.)); -#370 = ORIENTED_EDGE('',*,*,#371,.T.); -#371 = EDGE_CURVE('',#363,#81,#372,.T.); -#372 = LINE('',#373,#374); -#373 = CARTESIAN_POINT('',(-29.01580660709,-5.,-64.4520272055)); -#374 = VECTOR('',#375,1.); -#375 = DIRECTION('',(0.,1.,0.)); -#376 = ORIENTED_EDGE('',*,*,#88,.F.); -#377 = ORIENTED_EDGE('',*,*,#348,.F.); -#378 = CYLINDRICAL_SURFACE('',#379,5.1); -#379 = AXIS2_PLACEMENT_3D('',#380,#381,#382); -#380 = CARTESIAN_POINT('',(-25.35093464349,-5.,-60.90537900045)); -#381 = DIRECTION('',(0.,-1.,0.)); -#382 = DIRECTION('',(1.,0.,0.)); -#383 = ADVANCED_FACE('',(#384),#402,.T.); -#384 = FACE_BOUND('',#385,.T.); -#385 = EDGE_LOOP('',(#386,#394,#395,#396)); -#386 = ORIENTED_EDGE('',*,*,#387,.T.); -#387 = EDGE_CURVE('',#388,#363,#390,.T.); -#388 = VERTEX_POINT('',#389); -#389 = CARTESIAN_POINT('',(-27.78972445201,3.2,-65.71897950961)); -#390 = LINE('',#391,#392); -#391 = CARTESIAN_POINT('',(-29.67470230692,3.2,-63.77116791594)); -#392 = VECTOR('',#393,1.); -#393 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#394 = ORIENTED_EDGE('',*,*,#371,.T.); -#395 = ORIENTED_EDGE('',*,*,#80,.F.); -#396 = ORIENTED_EDGE('',*,*,#397,.F.); -#397 = EDGE_CURVE('',#388,#72,#398,.T.); -#398 = LINE('',#399,#400); -#399 = CARTESIAN_POINT('',(-27.78972445201,-5.,-65.71897950961)); -#400 = VECTOR('',#401,1.); -#401 = DIRECTION('',(0.,1.,0.)); -#402 = PLANE('',#403); -#403 = AXIS2_PLACEMENT_3D('',#404,#405,#406); -#404 = CARTESIAN_POINT('',(-29.01580660709,-5.,-64.4520272055)); -#405 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#406 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#407 = ADVANCED_FACE('',(#408),#427,.T.); -#408 = FACE_BOUND('',#409,.F.); -#409 = EDGE_LOOP('',(#410,#419,#425,#426)); -#410 = ORIENTED_EDGE('',*,*,#411,.T.); -#411 = EDGE_CURVE('',#388,#412,#414,.T.); -#412 = VERTEX_POINT('',#413); -#413 = CARTESIAN_POINT('',(-25.60006917852,3.2,-65.75487614033)); -#414 = CIRCLE('',#415,1.548528137424); -#415 = AXIS2_PLACEMENT_3D('',#416,#417,#418); -#416 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#417 = DIRECTION('',(0.,-1.,0.)); -#418 = DIRECTION('',(1.,0.,0.)); -#419 = ORIENTED_EDGE('',*,*,#420,.T.); -#420 = EDGE_CURVE('',#412,#64,#421,.T.); -#421 = LINE('',#422,#423); -#422 = CARTESIAN_POINT('',(-25.60006917852,-5.,-65.75487614033)); -#423 = VECTOR('',#424,1.); -#424 = DIRECTION('',(0.,1.,0.)); -#425 = ORIENTED_EDGE('',*,*,#71,.F.); -#426 = ORIENTED_EDGE('',*,*,#397,.F.); -#427 = CYLINDRICAL_SURFACE('',#428,1.548528137424); -#428 = AXIS2_PLACEMENT_3D('',#429,#430,#431); -#429 = CARTESIAN_POINT('',(-26.67694849991,-5.,-64.64210018823)); -#430 = DIRECTION('',(0.,-1.,0.)); -#431 = DIRECTION('',(1.,0.,0.)); -#432 = ADVANCED_FACE('',(#433),#451,.T.); -#433 = FACE_BOUND('',#434,.T.); -#434 = EDGE_LOOP('',(#435,#443,#444,#445)); -#435 = ORIENTED_EDGE('',*,*,#436,.T.); -#436 = EDGE_CURVE('',#437,#412,#439,.T.); -#437 = VERTEX_POINT('',#438); -#438 = CARTESIAN_POINT('',(-20.57248334837,3.2,-60.88947335481)); -#439 = LINE('',#440,#441); -#440 = CARTESIAN_POINT('',(-10.78812989347,3.2,-51.42074976419)); -#441 = VECTOR('',#442,1.); -#442 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#443 = ORIENTED_EDGE('',*,*,#420,.T.); -#444 = ORIENTED_EDGE('',*,*,#63,.F.); -#445 = ORIENTED_EDGE('',*,*,#446,.F.); -#446 = EDGE_CURVE('',#437,#56,#447,.T.); -#447 = LINE('',#448,#449); -#448 = CARTESIAN_POINT('',(-20.57248334837,-5.,-60.88947335481)); -#449 = VECTOR('',#450,1.); -#450 = DIRECTION('',(0.,1.,0.)); -#451 = PLANE('',#452); -#452 = AXIS2_PLACEMENT_3D('',#453,#454,#455); -#453 = CARTESIAN_POINT('',(-25.60006917852,-5.,-65.75487614033)); -#454 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#455 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#456 = ADVANCED_FACE('',(#457),#475,.F.); -#457 = FACE_BOUND('',#458,.F.); -#458 = EDGE_LOOP('',(#459,#467,#473,#474)); -#459 = ORIENTED_EDGE('',*,*,#460,.T.); -#460 = EDGE_CURVE('',#437,#461,#463,.T.); -#461 = VERTEX_POINT('',#462); -#462 = CARTESIAN_POINT('',(20.57248334837,3.2,-60.88947335481)); -#463 = LINE('',#464,#465); -#464 = CARTESIAN_POINT('',(10.487769931912,3.2,-60.88947335481)); -#465 = VECTOR('',#466,1.); -#466 = DIRECTION('',(1.,0.,0.)); -#467 = ORIENTED_EDGE('',*,*,#468,.T.); -#468 = EDGE_CURVE('',#461,#48,#469,.T.); -#469 = LINE('',#470,#471); -#470 = CARTESIAN_POINT('',(20.57248334837,-5.,-60.88947335481)); -#471 = VECTOR('',#472,1.); -#472 = DIRECTION('',(0.,1.,0.)); -#473 = ORIENTED_EDGE('',*,*,#55,.F.); -#474 = ORIENTED_EDGE('',*,*,#446,.F.); -#475 = PLANE('',#476); -#476 = AXIS2_PLACEMENT_3D('',#477,#478,#479); -#477 = CARTESIAN_POINT('',(20.57248334837,-5.,-60.88947335481)); -#478 = DIRECTION('',(0.,0.,1.)); -#479 = DIRECTION('',(-1.,0.,0.)); -#480 = ADVANCED_FACE('',(#481),#499,.F.); -#481 = FACE_BOUND('',#482,.F.); -#482 = EDGE_LOOP('',(#483,#491,#497,#498)); -#483 = ORIENTED_EDGE('',*,*,#484,.T.); -#484 = EDGE_CURVE('',#461,#485,#487,.T.); -#485 = VERTEX_POINT('',#486); -#486 = CARTESIAN_POINT('',(26.712845130625,3.2,-66.83175546171)); -#487 = LINE('',#488,#489); -#488 = CARTESIAN_POINT('',(11.552651954056,3.2,-52.16060938843)); -#489 = VECTOR('',#490,1.); -#490 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#491 = ORIENTED_EDGE('',*,*,#492,.T.); -#492 = EDGE_CURVE('',#485,#40,#493,.T.); -#493 = LINE('',#494,#495); -#494 = CARTESIAN_POINT('',(26.712845130625,-5.,-66.83175546171)); -#495 = VECTOR('',#496,1.); -#496 = DIRECTION('',(0.,1.,0.)); -#497 = ORIENTED_EDGE('',*,*,#47,.F.); -#498 = ORIENTED_EDGE('',*,*,#468,.F.); -#499 = PLANE('',#500); -#500 = AXIS2_PLACEMENT_3D('',#501,#502,#503); -#501 = CARTESIAN_POINT('',(26.712845130625,-5.,-66.83175546171)); -#502 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#503 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#504 = ADVANCED_FACE('',(#505),#523,.F.); -#505 = FACE_BOUND('',#506,.F.); -#506 = EDGE_LOOP('',(#507,#515,#521,#522)); -#507 = ORIENTED_EDGE('',*,*,#508,.T.); -#508 = EDGE_CURVE('',#485,#509,#511,.T.); -#509 = VERTEX_POINT('',#510); -#510 = CARTESIAN_POINT('',(32.56245481215,3.2,-60.7871552419)); -#511 = LINE('',#512,#513); -#512 = CARTESIAN_POINT('',(31.642948840372,3.2,-61.73731197059)); -#513 = VECTOR('',#514,1.); -#514 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#515 = ORIENTED_EDGE('',*,*,#516,.T.); -#516 = EDGE_CURVE('',#509,#32,#517,.T.); -#517 = LINE('',#518,#519); -#518 = CARTESIAN_POINT('',(32.56245481215,-5.,-60.7871552419)); -#519 = VECTOR('',#520,1.); -#520 = DIRECTION('',(0.,1.,0.)); -#521 = ORIENTED_EDGE('',*,*,#39,.F.); -#522 = ORIENTED_EDGE('',*,*,#492,.F.); -#523 = PLANE('',#524); -#524 = AXIS2_PLACEMENT_3D('',#525,#526,#527); -#525 = CARTESIAN_POINT('',(32.56245481215,-5.,-60.7871552419)); -#526 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#527 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#528 = ADVANCED_FACE('',(#529),#540,.F.); -#529 = FACE_BOUND('',#530,.F.); -#530 = EDGE_LOOP('',(#531,#537,#538,#539)); -#531 = ORIENTED_EDGE('',*,*,#532,.T.); -#532 = EDGE_CURVE('',#509,#162,#533,.T.); -#533 = LINE('',#534,#535); -#534 = CARTESIAN_POINT('',(14.533354293065,3.2,-43.3396488543)); -#535 = VECTOR('',#536,1.); -#536 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#537 = ORIENTED_EDGE('',*,*,#178,.T.); -#538 = ORIENTED_EDGE('',*,*,#31,.F.); -#539 = ORIENTED_EDGE('',*,*,#516,.F.); -#540 = PLANE('',#541); -#541 = AXIS2_PLACEMENT_3D('',#542,#543,#544); -#542 = CARTESIAN_POINT('',(26.824640127118,-5.,-55.23443461327)); -#543 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#544 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#545 = ADVANCED_FACE('',(#546,#564,#614,#648,#659),#670,.F.); -#546 = FACE_BOUND('',#547,.F.); -#547 = EDGE_LOOP('',(#548,#549,#550,#551,#552,#553,#554,#555,#556,#557, - #558,#559,#560,#561,#562,#563)); -#548 = ORIENTED_EDGE('',*,*,#161,.F.); -#549 = ORIENTED_EDGE('',*,*,#532,.F.); -#550 = ORIENTED_EDGE('',*,*,#508,.F.); -#551 = ORIENTED_EDGE('',*,*,#484,.F.); -#552 = ORIENTED_EDGE('',*,*,#460,.F.); -#553 = ORIENTED_EDGE('',*,*,#436,.T.); -#554 = ORIENTED_EDGE('',*,*,#411,.F.); -#555 = ORIENTED_EDGE('',*,*,#387,.T.); -#556 = ORIENTED_EDGE('',*,*,#362,.F.); -#557 = ORIENTED_EDGE('',*,*,#338,.T.); -#558 = ORIENTED_EDGE('',*,*,#314,.T.); -#559 = ORIENTED_EDGE('',*,*,#289,.F.); -#560 = ORIENTED_EDGE('',*,*,#265,.T.); -#561 = ORIENTED_EDGE('',*,*,#240,.F.); -#562 = ORIENTED_EDGE('',*,*,#216,.T.); -#563 = ORIENTED_EDGE('',*,*,#192,.F.); -#564 = FACE_BOUND('',#565,.F.); -#565 = EDGE_LOOP('',(#566,#576,#584,#592,#600,#608)); -#566 = ORIENTED_EDGE('',*,*,#567,.F.); -#567 = EDGE_CURVE('',#568,#570,#572,.T.); -#568 = VERTEX_POINT('',#569); -#569 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#570 = VERTEX_POINT('',#571); -#571 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#572 = LINE('',#573,#574); -#573 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#574 = VECTOR('',#575,1.); -#575 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#576 = ORIENTED_EDGE('',*,*,#577,.F.); -#577 = EDGE_CURVE('',#578,#568,#580,.T.); -#578 = VERTEX_POINT('',#579); -#579 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#580 = LINE('',#581,#582); -#581 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#582 = VECTOR('',#583,1.); -#583 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#584 = ORIENTED_EDGE('',*,*,#585,.F.); -#585 = EDGE_CURVE('',#586,#578,#588,.T.); -#586 = VERTEX_POINT('',#587); -#587 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#588 = LINE('',#589,#590); -#589 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#590 = VECTOR('',#591,1.); -#591 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#592 = ORIENTED_EDGE('',*,*,#593,.F.); -#593 = EDGE_CURVE('',#594,#586,#596,.T.); -#594 = VERTEX_POINT('',#595); -#595 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#596 = LINE('',#597,#598); -#597 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#598 = VECTOR('',#599,1.); -#599 = DIRECTION('',(1.,0.,0.)); -#600 = ORIENTED_EDGE('',*,*,#601,.F.); -#601 = EDGE_CURVE('',#602,#594,#604,.T.); -#602 = VERTEX_POINT('',#603); -#603 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(0.,0.,1.)); -#608 = ORIENTED_EDGE('',*,*,#609,.F.); -#609 = EDGE_CURVE('',#570,#602,#610,.T.); -#610 = LINE('',#611,#612); -#611 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#612 = VECTOR('',#613,1.); -#613 = DIRECTION('',(-1.,0.,0.)); -#614 = FACE_BOUND('',#615,.F.); -#615 = EDGE_LOOP('',(#616,#626,#634,#642)); -#616 = ORIENTED_EDGE('',*,*,#617,.F.); -#617 = EDGE_CURVE('',#618,#620,#622,.T.); -#618 = VERTEX_POINT('',#619); -#619 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#620 = VERTEX_POINT('',#621); -#621 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#622 = LINE('',#623,#624); -#623 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#624 = VECTOR('',#625,1.); -#625 = DIRECTION('',(-8.501532861638E-02,0.,-0.996379643459)); -#626 = ORIENTED_EDGE('',*,*,#627,.F.); -#627 = EDGE_CURVE('',#628,#618,#630,.T.); -#628 = VERTEX_POINT('',#629); -#629 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#630 = LINE('',#631,#632); -#631 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#632 = VECTOR('',#633,1.); -#633 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#634 = ORIENTED_EDGE('',*,*,#635,.F.); -#635 = EDGE_CURVE('',#636,#628,#638,.T.); -#636 = VERTEX_POINT('',#637); -#637 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#638 = LINE('',#639,#640); -#639 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#640 = VECTOR('',#641,1.); -#641 = DIRECTION('',(-8.501532861638E-02,0.,0.996379643459)); -#642 = ORIENTED_EDGE('',*,*,#643,.F.); -#643 = EDGE_CURVE('',#620,#636,#644,.T.); -#644 = LINE('',#645,#646); -#645 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#646 = VECTOR('',#647,1.); -#647 = DIRECTION('',(-1.,0.,0.)); -#648 = FACE_BOUND('',#649,.F.); -#649 = EDGE_LOOP('',(#650)); -#650 = ORIENTED_EDGE('',*,*,#651,.F.); -#651 = EDGE_CURVE('',#652,#652,#654,.T.); -#652 = VERTEX_POINT('',#653); -#653 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#654 = CIRCLE('',#655,4.735522705283); -#655 = AXIS2_PLACEMENT_3D('',#656,#657,#658); -#656 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#657 = DIRECTION('',(-0.,1.,0.)); -#658 = DIRECTION('',(1.,0.,0.)); -#659 = FACE_BOUND('',#660,.F.); -#660 = EDGE_LOOP('',(#661)); -#661 = ORIENTED_EDGE('',*,*,#662,.F.); -#662 = EDGE_CURVE('',#663,#663,#665,.T.); -#663 = VERTEX_POINT('',#664); -#664 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#665 = CIRCLE('',#666,4.735522705283); -#666 = AXIS2_PLACEMENT_3D('',#667,#668,#669); -#667 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#668 = DIRECTION('',(-0.,1.,0.)); -#669 = DIRECTION('',(1.,0.,0.)); -#670 = PLANE('',#671); -#671 = AXIS2_PLACEMENT_3D('',#672,#673,#674); -#672 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#673 = DIRECTION('',(0.,1.,0.)); -#674 = DIRECTION('',(1.,0.,0.)); -#675 = ADVANCED_FACE('',(#676),#701,.T.); -#676 = FACE_BOUND('',#677,.T.); -#677 = EDGE_LOOP('',(#678,#686,#694,#700)); -#678 = ORIENTED_EDGE('',*,*,#679,.F.); -#679 = EDGE_CURVE('',#680,#568,#682,.T.); -#680 = VERTEX_POINT('',#681); -#681 = CARTESIAN_POINT('',(16.626582997737,0.,-8.940188245231)); -#682 = LINE('',#683,#684); -#683 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#684 = VECTOR('',#685,1.); -#685 = DIRECTION('',(0.,1.,0.)); -#686 = ORIENTED_EDGE('',*,*,#687,.T.); -#687 = EDGE_CURVE('',#680,#688,#690,.T.); -#688 = VERTEX_POINT('',#689); -#689 = CARTESIAN_POINT('',(-5.329070518201E-15,0.,-8.903751135252)); -#690 = LINE('',#691,#692); -#691 = CARTESIAN_POINT('',(-18.54556462154,1.7763568394E-15, - -8.863107566442)); -#692 = VECTOR('',#693,1.); -#693 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#694 = ORIENTED_EDGE('',*,*,#695,.T.); -#695 = EDGE_CURVE('',#688,#570,#696,.T.); -#696 = LINE('',#697,#698); -#697 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#698 = VECTOR('',#699,1.); -#699 = DIRECTION('',(0.,1.,0.)); -#700 = ORIENTED_EDGE('',*,*,#567,.F.); -#701 = PLANE('',#702); -#702 = AXIS2_PLACEMENT_3D('',#703,#704,#705); -#703 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#704 = DIRECTION('',(-2.19152081707E-03,0.,-0.999997598615)); -#705 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#706 = ADVANCED_FACE('',(#707),#725,.T.); -#707 = FACE_BOUND('',#708,.T.); -#708 = EDGE_LOOP('',(#709,#717,#723,#724)); -#709 = ORIENTED_EDGE('',*,*,#710,.F.); -#710 = EDGE_CURVE('',#711,#578,#713,.T.); -#711 = VERTEX_POINT('',#712); -#712 = CARTESIAN_POINT('',(19.029295926024,0.,-17.63009960955)); -#713 = LINE('',#714,#715); -#714 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#715 = VECTOR('',#716,1.); -#716 = DIRECTION('',(0.,1.,0.)); -#717 = ORIENTED_EDGE('',*,*,#718,.T.); -#718 = EDGE_CURVE('',#711,#680,#719,.T.); -#719 = LINE('',#720,#721); -#720 = CARTESIAN_POINT('',(23.053273013696,0.,-32.18365022821)); -#721 = VECTOR('',#722,1.); -#722 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#723 = ORIENTED_EDGE('',*,*,#679,.T.); -#724 = ORIENTED_EDGE('',*,*,#577,.F.); -#725 = PLANE('',#726); -#726 = AXIS2_PLACEMENT_3D('',#727,#728,#729); -#727 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#728 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#729 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#730 = ADVANCED_FACE('',(#731),#749,.T.); -#731 = FACE_BOUND('',#732,.T.); -#732 = EDGE_LOOP('',(#733,#741,#747,#748)); -#733 = ORIENTED_EDGE('',*,*,#734,.T.); -#734 = EDGE_CURVE('',#688,#735,#737,.T.); -#735 = VERTEX_POINT('',#736); -#736 = CARTESIAN_POINT('',(-21.72552223146,0.,-8.903751135252)); -#737 = LINE('',#738,#739); -#738 = CARTESIAN_POINT('',(-28.21385794834,0.,-8.903751135252)); -#739 = VECTOR('',#740,1.); -#740 = DIRECTION('',(-1.,0.,0.)); -#741 = ORIENTED_EDGE('',*,*,#742,.T.); -#742 = EDGE_CURVE('',#735,#602,#743,.T.); -#743 = LINE('',#744,#745); -#744 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#745 = VECTOR('',#746,1.); -#746 = DIRECTION('',(0.,1.,0.)); -#747 = ORIENTED_EDGE('',*,*,#609,.F.); -#748 = ORIENTED_EDGE('',*,*,#695,.F.); -#749 = PLANE('',#750); -#750 = AXIS2_PLACEMENT_3D('',#751,#752,#753); -#751 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#752 = DIRECTION('',(0.,0.,-1.)); -#753 = DIRECTION('',(0.,1.,0.)); -#754 = ADVANCED_FACE('',(#755),#773,.T.); -#755 = FACE_BOUND('',#756,.T.); -#756 = EDGE_LOOP('',(#757,#765,#766,#767)); -#757 = ORIENTED_EDGE('',*,*,#758,.T.); -#758 = EDGE_CURVE('',#759,#711,#761,.T.); -#759 = VERTEX_POINT('',#760); -#760 = CARTESIAN_POINT('',(22.059435554995,0.,-3.734519760785)); -#761 = LINE('',#762,#763); -#762 = CARTESIAN_POINT('',(12.741012548745,1.7763568394E-15, - -46.46683800444)); -#763 = VECTOR('',#764,1.); -#764 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#765 = ORIENTED_EDGE('',*,*,#710,.T.); -#766 = ORIENTED_EDGE('',*,*,#585,.F.); -#767 = ORIENTED_EDGE('',*,*,#768,.F.); -#768 = EDGE_CURVE('',#759,#586,#769,.T.); -#769 = LINE('',#770,#771); -#770 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#771 = VECTOR('',#772,1.); -#772 = DIRECTION('',(0.,1.,0.)); -#773 = PLANE('',#774); -#774 = AXIS2_PLACEMENT_3D('',#775,#776,#777); -#775 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#776 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#777 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#778 = ADVANCED_FACE('',(#779),#797,.T.); -#779 = FACE_BOUND('',#780,.T.); -#780 = EDGE_LOOP('',(#781,#789,#795,#796)); -#781 = ORIENTED_EDGE('',*,*,#782,.T.); -#782 = EDGE_CURVE('',#735,#783,#785,.T.); -#783 = VERTEX_POINT('',#784); -#784 = CARTESIAN_POINT('',(-21.72552223146,0.,-3.734519760785)); -#785 = LINE('',#786,#787); -#786 = CARTESIAN_POINT('',(-21.72552223146,0.,-38.64614663299)); -#787 = VECTOR('',#788,1.); -#788 = DIRECTION('',(0.,0.,1.)); -#789 = ORIENTED_EDGE('',*,*,#790,.T.); -#790 = EDGE_CURVE('',#783,#594,#791,.T.); -#791 = LINE('',#792,#793); -#792 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#793 = VECTOR('',#794,1.); -#794 = DIRECTION('',(0.,1.,0.)); -#795 = ORIENTED_EDGE('',*,*,#601,.F.); -#796 = ORIENTED_EDGE('',*,*,#742,.F.); -#797 = PLANE('',#798); -#798 = AXIS2_PLACEMENT_3D('',#799,#800,#801); -#799 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#800 = DIRECTION('',(-1.,0.,0.)); -#801 = DIRECTION('',(0.,1.,0.)); -#802 = ADVANCED_FACE('',(#803),#814,.T.); -#803 = FACE_BOUND('',#804,.T.); -#804 = EDGE_LOOP('',(#805,#811,#812,#813)); -#805 = ORIENTED_EDGE('',*,*,#806,.T.); -#806 = EDGE_CURVE('',#783,#759,#807,.T.); -#807 = LINE('',#808,#809); -#808 = CARTESIAN_POINT('',(-22.63692080725,0.,-3.734519760785)); -#809 = VECTOR('',#810,1.); -#810 = DIRECTION('',(1.,0.,0.)); -#811 = ORIENTED_EDGE('',*,*,#768,.T.); -#812 = ORIENTED_EDGE('',*,*,#593,.F.); -#813 = ORIENTED_EDGE('',*,*,#790,.F.); -#814 = PLANE('',#815); -#815 = AXIS2_PLACEMENT_3D('',#816,#817,#818); -#816 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#817 = DIRECTION('',(0.,0.,1.)); -#818 = DIRECTION('',(0.,-1.,0.)); -#819 = ADVANCED_FACE('',(#820),#845,.F.); -#820 = FACE_BOUND('',#821,.F.); -#821 = EDGE_LOOP('',(#822,#832,#838,#839)); -#822 = ORIENTED_EDGE('',*,*,#823,.T.); -#823 = EDGE_CURVE('',#824,#826,#828,.T.); -#824 = VERTEX_POINT('',#825); -#825 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#826 = VERTEX_POINT('',#827); -#827 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#828 = LINE('',#829,#830); -#829 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#830 = VECTOR('',#831,1.); -#831 = DIRECTION('',(5.275122655165E-17,0.227455280238,0.97378852709)); -#832 = ORIENTED_EDGE('',*,*,#833,.F.); -#833 = EDGE_CURVE('',#618,#826,#834,.T.); -#834 = LINE('',#835,#836); -#835 = CARTESIAN_POINT('',(5.649679875255,3.602918464526,-13.21082950266 - )); -#836 = VECTOR('',#837,1.); -#837 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#838 = ORIENTED_EDGE('',*,*,#617,.T.); -#839 = ORIENTED_EDGE('',*,*,#840,.T.); -#840 = EDGE_CURVE('',#620,#824,#841,.T.); -#841 = LINE('',#842,#843); -#842 = CARTESIAN_POINT('',(1.103762571829,7.940067898719,-47.92064259636 - )); -#843 = VECTOR('',#844,1.); -#844 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#845 = PLANE('',#846); -#846 = AXIS2_PLACEMENT_3D('',#847,#848,#849); -#847 = CARTESIAN_POINT('',(5.823691883056,3.068404028665,-13.45978839622 - )); -#848 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02)); -#849 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487825E-02) - ); -#850 = ADVANCED_FACE('',(#851),#861,.F.); -#851 = FACE_BOUND('',#852,.F.); -#852 = EDGE_LOOP('',(#853,#854,#860)); -#853 = ORIENTED_EDGE('',*,*,#833,.T.); -#854 = ORIENTED_EDGE('',*,*,#855,.T.); -#855 = EDGE_CURVE('',#826,#628,#856,.T.); -#856 = LINE('',#857,#858); -#857 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#858 = VECTOR('',#859,1.); -#859 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#860 = ORIENTED_EDGE('',*,*,#627,.T.); -#861 = PLANE('',#862); -#862 = AXIS2_PLACEMENT_3D('',#863,#864,#865); -#863 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-13.01628215822 - )); -#864 = DIRECTION('',(2.88163763217E-16,0.342020143326,0.939692620786)); -#865 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326) - ); -#866 = ADVANCED_FACE('',(#867),#877,.F.); -#867 = FACE_BOUND('',#868,.F.); -#868 = EDGE_LOOP('',(#869,#875,#876)); -#869 = ORIENTED_EDGE('',*,*,#870,.T.); -#870 = EDGE_CURVE('',#636,#824,#871,.T.); -#871 = LINE('',#872,#873); -#872 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#873 = VECTOR('',#874,1.); -#874 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#875 = ORIENTED_EDGE('',*,*,#840,.F.); -#876 = ORIENTED_EDGE('',*,*,#643,.T.); -#877 = PLANE('',#878); -#878 = AXIS2_PLACEMENT_3D('',#879,#880,#881); -#879 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-49.69378323641 - )); -#880 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#881 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#882 = ADVANCED_FACE('',(#883),#889,.F.); -#883 = FACE_BOUND('',#884,.F.); -#884 = EDGE_LOOP('',(#885,#886,#887,#888)); -#885 = ORIENTED_EDGE('',*,*,#635,.T.); -#886 = ORIENTED_EDGE('',*,*,#855,.F.); -#887 = ORIENTED_EDGE('',*,*,#823,.F.); -#888 = ORIENTED_EDGE('',*,*,#870,.F.); -#889 = PLANE('',#890); -#890 = AXIS2_PLACEMENT_3D('',#891,#892,#893); -#891 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#892 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#893 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487825E-02)); -#894 = ADVANCED_FACE('',(#895),#914,.T.); -#895 = FACE_BOUND('',#896,.T.); -#896 = EDGE_LOOP('',(#897,#906,#912,#913)); -#897 = ORIENTED_EDGE('',*,*,#898,.T.); -#898 = EDGE_CURVE('',#899,#899,#901,.T.); -#899 = VERTEX_POINT('',#900); -#900 = CARTESIAN_POINT('',(-11.6927539352,0.,-48.00951684793)); -#901 = CIRCLE('',#902,4.735522705283); -#902 = AXIS2_PLACEMENT_3D('',#903,#904,#905); -#903 = CARTESIAN_POINT('',(-16.42827664048,0.,-48.00951684793)); -#904 = DIRECTION('',(-0.,1.,0.)); -#905 = DIRECTION('',(1.,0.,0.)); -#906 = ORIENTED_EDGE('',*,*,#907,.T.); -#907 = EDGE_CURVE('',#899,#652,#908,.T.); -#908 = LINE('',#909,#910); -#909 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#910 = VECTOR('',#911,1.); -#911 = DIRECTION('',(0.,1.,0.)); -#912 = ORIENTED_EDGE('',*,*,#651,.F.); -#913 = ORIENTED_EDGE('',*,*,#907,.F.); -#914 = CYLINDRICAL_SURFACE('',#915,4.735522705283); -#915 = AXIS2_PLACEMENT_3D('',#916,#917,#918); -#916 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#917 = DIRECTION('',(0.,1.,0.)); -#918 = DIRECTION('',(1.,0.,0.)); -#919 = ADVANCED_FACE('',(#920),#939,.T.); -#920 = FACE_BOUND('',#921,.T.); -#921 = EDGE_LOOP('',(#922,#931,#937,#938)); -#922 = ORIENTED_EDGE('',*,*,#923,.T.); -#923 = EDGE_CURVE('',#924,#924,#926,.T.); -#924 = VERTEX_POINT('',#925); -#925 = CARTESIAN_POINT('',(21.163799345768,0.,-48.00951684793)); -#926 = CIRCLE('',#927,4.735522705283); -#927 = AXIS2_PLACEMENT_3D('',#928,#929,#930); -#928 = CARTESIAN_POINT('',(16.428276640485,0.,-48.00951684793)); -#929 = DIRECTION('',(-0.,1.,0.)); -#930 = DIRECTION('',(1.,0.,0.)); -#931 = ORIENTED_EDGE('',*,*,#932,.T.); -#932 = EDGE_CURVE('',#924,#663,#933,.T.); -#933 = LINE('',#934,#935); -#934 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#935 = VECTOR('',#936,1.); -#936 = DIRECTION('',(0.,1.,0.)); -#937 = ORIENTED_EDGE('',*,*,#662,.F.); -#938 = ORIENTED_EDGE('',*,*,#932,.F.); -#939 = CYLINDRICAL_SURFACE('',#940,4.735522705283); -#940 = AXIS2_PLACEMENT_3D('',#941,#942,#943); -#941 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#942 = DIRECTION('',(0.,1.,0.)); -#943 = DIRECTION('',(1.,0.,0.)); -#944 = ADVANCED_FACE('',(#945),#953,.F.); -#945 = FACE_BOUND('',#946,.F.); -#946 = EDGE_LOOP('',(#947,#948,#949,#950,#951,#952)); -#947 = ORIENTED_EDGE('',*,*,#718,.T.); -#948 = ORIENTED_EDGE('',*,*,#687,.T.); -#949 = ORIENTED_EDGE('',*,*,#734,.T.); -#950 = ORIENTED_EDGE('',*,*,#782,.T.); -#951 = ORIENTED_EDGE('',*,*,#806,.T.); -#952 = ORIENTED_EDGE('',*,*,#758,.T.); -#953 = PLANE('',#954); -#954 = AXIS2_PLACEMENT_3D('',#955,#956,#957); -#955 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#956 = DIRECTION('',(0.,1.,0.)); -#957 = DIRECTION('',(0.,0.,1.)); -#958 = ADVANCED_FACE('',(#959),#962,.F.); -#959 = FACE_BOUND('',#960,.F.); -#960 = EDGE_LOOP('',(#961)); -#961 = ORIENTED_EDGE('',*,*,#898,.T.); -#962 = PLANE('',#963); -#963 = AXIS2_PLACEMENT_3D('',#964,#965,#966); -#964 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#965 = DIRECTION('',(0.,1.,0.)); -#966 = DIRECTION('',(0.,0.,1.)); -#967 = ADVANCED_FACE('',(#968),#971,.F.); -#968 = FACE_BOUND('',#969,.F.); -#969 = EDGE_LOOP('',(#970)); -#970 = ORIENTED_EDGE('',*,*,#923,.T.); -#971 = PLANE('',#972); -#972 = AXIS2_PLACEMENT_3D('',#973,#974,#975); -#973 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#974 = DIRECTION('',(0.,1.,0.)); -#975 = DIRECTION('',(0.,0.,1.)); -#976 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#980)) GLOBAL_UNIT_ASSIGNED_CONTEXT -((#977,#978,#979)) REPRESENTATION_CONTEXT('Context #1', - '3D Context with UNIT and UNCERTAINTY') ); -#977 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#978 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#979 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#980 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(5.E-06),#977, - 'distance_accuracy_value','confusion accuracy'); -#981 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.stl b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.stl deleted file mode 100644 index 940dab90f7..0000000000 Binary files a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.stl and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.step b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.step deleted file mode 100644 index 14e61e2877..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.step +++ /dev/null @@ -1,1604 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T11:06:23',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 2', - 'Open CASCADE STEP translator 7.8 2','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#1522); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#291,#322,#346,#370,#395,#419,#444,#468,#492, - #517,#541,#566,#590,#614,#638,#662,#679,#710,#734,#758,#782,#806, - #830,#854,#878,#903,#928,#952,#976,#1001,#1026,#1050,#1067,#1091, - #1221,#1252,#1276,#1300,#1324,#1348,#1365,#1390,#1421,#1437,#1454, - #1465,#1490,#1504,#1513)); -#17 = ADVANCED_FACE('',(#18,#152),#286,.F.); -#18 = FACE_BOUND('',#19,.F.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62,#70,#79,#87,#96,#104,#112, - #121,#129,#138,#146)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(28.536336768195,0.,-54.80352892379)); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(43.891390829132,0.,-6.628649129335)); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(30.462276491561,4.440892098501E-16, - -48.76109401628)); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#30 = ORIENTED_EDGE('',*,*,#31,.F.); -#31 = EDGE_CURVE('',#32,#22,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(34.683490155872,0.,-60.75238354821)); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(13.469833011847,0.,-40.22304997814)); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#38 = ORIENTED_EDGE('',*,*,#39,.F.); -#39 = EDGE_CURVE('',#40,#32,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(26.747616824317,0.,-68.95279080543)); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(12.749348137648,0.,-83.41767694094)); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#48,#40,#50,.T.); -#48 = VERTEX_POINT('',#49); -#49 = CARTESIAN_POINT('',(19.965518143439,0.,-62.38947335481)); -#50 = LINE('',#51,#52); -#51 = CARTESIAN_POINT('',(8.607536374131,0.,-51.39788454757)); -#52 = VECTOR('',#53,1.); -#53 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#54 = ORIENTED_EDGE('',*,*,#55,.F.); -#55 = EDGE_CURVE('',#56,#48,#58,.T.); -#56 = VERTEX_POINT('',#57); -#57 = CARTESIAN_POINT('',(-19.96551814343,0.,-62.38947335481)); -#58 = LINE('',#59,#60); -#59 = CARTESIAN_POINT('',(-12.74971831875,0.,-62.38947335481)); -#60 = VECTOR('',#61,1.); -#61 = DIRECTION('',(1.,0.,0.)); -#62 = ORIENTED_EDGE('',*,*,#63,.T.); -#63 = EDGE_CURVE('',#56,#64,#66,.T.); -#64 = VERTEX_POINT('',#65); -#65 = CARTESIAN_POINT('',(-24.55693735351,0.,-66.83277965903)); -#66 = LINE('',#67,#68); -#67 = CARTESIAN_POINT('',(-30.98981424001,0.,-73.05814073287)); -#68 = VECTOR('',#69,1.); -#69 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#70 = ORIENTED_EDGE('',*,*,#71,.F.); -#71 = EDGE_CURVE('',#72,#64,#74,.T.); -#72 = VERTEX_POINT('',#73); -#73 = CARTESIAN_POINT('',(-28.86762797071,0.,-66.76211133463)); -#74 = CIRCLE('',#75,3.048528137424); -#75 = AXIS2_PLACEMENT_3D('',#76,#77,#78); -#76 = CARTESIAN_POINT('',(-26.67694849991,0.,-64.64210018823)); -#77 = DIRECTION('',(0.,-1.,0.)); -#78 = DIRECTION('',(1.,0.,0.)); -#79 = ORIENTED_EDGE('',*,*,#80,.T.); -#80 = EDGE_CURVE('',#72,#81,#83,.T.); -#81 = VERTEX_POINT('',#82); -#82 = CARTESIAN_POINT('',(-30.0937101258,0.,-65.49515903052)); -#83 = LINE('',#84,#85); -#84 = CARTESIAN_POINT('',(-32.44179530228,0.,-63.0688029236)); -#85 = VECTOR('',#86,1.); -#86 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#87 = ORIENTED_EDGE('',*,*,#88,.F.); -#88 = EDGE_CURVE('',#89,#81,#91,.T.); -#89 = VERTEX_POINT('',#90); -#90 = CARTESIAN_POINT('',(-29.94071467356,0.,-56.16260351814)); -#91 = CIRCLE('',#92,6.6); -#92 = AXIS2_PLACEMENT_3D('',#93,#94,#95); -#93 = CARTESIAN_POINT('',(-25.35093464349,0.,-60.90537900045)); -#94 = DIRECTION('',(0.,-1.,0.)); -#95 = DIRECTION('',(1.,0.,0.)); -#96 = ORIENTED_EDGE('',*,*,#97,.T.); -#97 = EDGE_CURVE('',#89,#98,#100,.T.); -#98 = VERTEX_POINT('',#99); -#99 = CARTESIAN_POINT('',(-28.53633676819,0.,-54.80352892379)); -#100 = LINE('',#101,#102); -#101 = CARTESIAN_POINT('',(-36.94745061313,0.,-62.94331173664)); -#102 = VECTOR('',#103,1.); -#103 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#104 = ORIENTED_EDGE('',*,*,#105,.T.); -#105 = EDGE_CURVE('',#98,#106,#108,.T.); -#106 = VERTEX_POINT('',#107); -#107 = CARTESIAN_POINT('',(-42.51292396981,0.,-10.95344505546)); -#108 = LINE('',#109,#110); -#109 = CARTESIAN_POINT('',(-33.96596941491,4.440892098501E-16, - -37.76862308461)); -#110 = VECTOR('',#111,1.); -#111 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#112 = ORIENTED_EDGE('',*,*,#113,.F.); -#113 = EDGE_CURVE('',#114,#106,#116,.T.); -#114 = VERTEX_POINT('',#115); -#115 = CARTESIAN_POINT('',(-40.68171555857,0.,-3.418973858775)); -#116 = CIRCLE('',#117,7.454044962965); -#117 = AXIS2_PLACEMENT_3D('',#118,#119,#120); -#118 = CARTESIAN_POINT('',(-35.41090981799,0.,-8.689779599357)); -#119 = DIRECTION('',(0.,-1.,0.)); -#120 = DIRECTION('',(1.,0.,0.)); -#121 = ORIENTED_EDGE('',*,*,#122,.T.); -#122 = EDGE_CURVE('',#114,#123,#125,.T.); -#123 = VERTEX_POINT('',#124); -#124 = CARTESIAN_POINT('',(-37.84598092218,0.,-0.583239222383)); -#125 = LINE('',#126,#127); -#126 = CARTESIAN_POINT('',(-57.34820403576,0.,-20.08546233597)); -#127 = VECTOR('',#128,1.); -#128 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#129 = ORIENTED_EDGE('',*,*,#130,.F.); -#130 = EDGE_CURVE('',#131,#123,#133,.T.); -#131 = VERTEX_POINT('',#132); -#132 = CARTESIAN_POINT('',(-32.57517518159,0.,1.6)); -#133 = CIRCLE('',#134,7.454044962965); -#134 = AXIS2_PLACEMENT_3D('',#135,#136,#137); -#135 = CARTESIAN_POINT('',(-32.57517518159,0.,-5.854044962965)); -#136 = DIRECTION('',(0.,-1.,0.)); -#137 = DIRECTION('',(1.,0.,0.)); -#138 = ORIENTED_EDGE('',*,*,#139,.T.); -#139 = EDGE_CURVE('',#131,#140,#142,.T.); -#140 = VERTEX_POINT('',#141); -#141 = CARTESIAN_POINT('',(35.662741699797,0.,1.6)); -#142 = LINE('',#143,#144); -#143 = CARTESIAN_POINT('',(-4.901106540577,0.,1.6)); -#144 = VECTOR('',#145,1.); -#145 = DIRECTION('',(1.,0.,0.)); -#146 = ORIENTED_EDGE('',*,*,#147,.F.); -#147 = EDGE_CURVE('',#24,#140,#148,.T.); -#148 = LINE('',#149,#150); -#149 = CARTESIAN_POINT('',(33.5241070341,0.,3.738634665697)); -#150 = VECTOR('',#151,1.); -#151 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#152 = FACE_BOUND('',#153,.F.); -#153 = EDGE_LOOP('',(#154,#164,#172,#180,#188,#197,#205,#214,#222,#230, - #239,#247,#256,#264,#272,#280)); -#154 = ORIENTED_EDGE('',*,*,#155,.T.); -#155 = EDGE_CURVE('',#156,#158,#160,.T.); -#156 = VERTEX_POINT('',#157); -#157 = CARTESIAN_POINT('',(32.703857168398,0.,-60.78483712899)); -#158 = VERTEX_POINT('',#159); -#159 = CARTESIAN_POINT('',(26.938753236523,0.,-55.20570756731)); -#160 = LINE('',#161,#162); -#161 = CARTESIAN_POINT('',(13.567306766147,0.,-42.26560567724)); -#162 = VECTOR('',#163,1.); -#163 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#164 = ORIENTED_EDGE('',*,*,#165,.T.); -#165 = EDGE_CURVE('',#158,#166,#168,.T.); -#166 = VERTEX_POINT('',#167); -#167 = CARTESIAN_POINT('',(42.298608189024,0.,-7.015765476549)); -#168 = LINE('',#169,#170); -#169 = CARTESIAN_POINT('',(25.140315874087,-4.440892098501E-16, - -60.84811712245)); -#170 = VECTOR('',#171,1.); -#171 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#172 = ORIENTED_EDGE('',*,*,#173,.T.); -#173 = EDGE_CURVE('',#166,#174,#176,.T.); -#174 = VERTEX_POINT('',#175); -#175 = CARTESIAN_POINT('',(35.082842712475,0.,0.2)); -#176 = LINE('',#177,#178); -#177 = CARTESIAN_POINT('',(34.536239068456,0.,0.746603644019)); -#178 = VECTOR('',#179,1.); -#179 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#180 = ORIENTED_EDGE('',*,*,#181,.F.); -#181 = EDGE_CURVE('',#182,#174,#184,.T.); -#182 = VERTEX_POINT('',#183); -#183 = CARTESIAN_POINT('',(-32.57517518159,0.,0.2)); -#184 = LINE('',#185,#186); -#185 = CARTESIAN_POINT('',(-30.87627118587,0.,0.2)); -#186 = VECTOR('',#187,1.); -#187 = DIRECTION('',(1.,0.,0.)); -#188 = ORIENTED_EDGE('',*,*,#189,.T.); -#189 = EDGE_CURVE('',#182,#190,#192,.T.); -#190 = VERTEX_POINT('',#191); -#191 = CARTESIAN_POINT('',(-36.85603142851,0.,-1.573188716044)); -#192 = CIRCLE('',#193,6.054044962965); -#193 = AXIS2_PLACEMENT_3D('',#194,#195,#196); -#194 = CARTESIAN_POINT('',(-32.57517518159,0.,-5.854044962965)); -#195 = DIRECTION('',(0.,-1.,0.)); -#196 = DIRECTION('',(-1.,0.,0.)); -#197 = ORIENTED_EDGE('',*,*,#198,.F.); -#198 = EDGE_CURVE('',#199,#190,#201,.T.); -#199 = VERTEX_POINT('',#200); -#200 = CARTESIAN_POINT('',(-39.69176606491,0.,-4.408923352436)); -#201 = LINE('',#202,#203); -#202 = CARTESIAN_POINT('',(-57.0671882012,0.,-21.78434548873)); -#203 = VECTOR('',#204,1.); -#204 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#205 = ORIENTED_EDGE('',*,*,#206,.T.); -#206 = EDGE_CURVE('',#199,#207,#209,.T.); -#207 = VERTEX_POINT('',#208); -#208 = CARTESIAN_POINT('',(-41.17904151244,0.,-10.52828909594)); -#209 = CIRCLE('',#210,6.054044962965); -#210 = AXIS2_PLACEMENT_3D('',#211,#212,#213); -#211 = CARTESIAN_POINT('',(-35.41090981799,0.,-8.689779599357)); -#212 = DIRECTION('',(0.,-1.,0.)); -#213 = DIRECTION('',(-1.,0.,0.)); -#214 = ORIENTED_EDGE('',*,*,#215,.F.); -#215 = EDGE_CURVE('',#216,#207,#218,.T.); -#216 = VERTEX_POINT('',#217); -#217 = CARTESIAN_POINT('',(-26.93875323652,0.,-55.20570756731)); -#218 = LINE('',#219,#220); -#219 = CARTESIAN_POINT('',(-29.06259699304,-4.440892098501E-16, - -48.54236940733)); -#220 = VECTOR('',#221,1.); -#221 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#222 = ORIENTED_EDGE('',*,*,#223,.F.); -#223 = EDGE_CURVE('',#224,#216,#226,.T.); -#224 = VERTEX_POINT('',#225); -#225 = CARTESIAN_POINT('',(-28.96712497021,0.,-57.16864680227)); -#226 = LINE('',#227,#228); -#227 = CARTESIAN_POINT('',(-36.14667143517,0.,-64.11659091489)); -#228 = VECTOR('',#229,1.); -#229 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#230 = ORIENTED_EDGE('',*,*,#231,.T.); -#231 = EDGE_CURVE('',#224,#232,#234,.T.); -#232 = VERTEX_POINT('',#233); -#233 = CARTESIAN_POINT('',(-29.08766684168,0.,-64.52156932717)); -#234 = CIRCLE('',#235,5.2); -#235 = AXIS2_PLACEMENT_3D('',#236,#237,#238); -#236 = CARTESIAN_POINT('',(-25.35093464349,0.,-60.90537900045)); -#237 = DIRECTION('',(0.,-1.,0.)); -#238 = DIRECTION('',(-1.,0.,0.)); -#239 = ORIENTED_EDGE('',*,*,#240,.F.); -#240 = EDGE_CURVE('',#241,#232,#243,.T.); -#241 = VERTEX_POINT('',#242); -#242 = CARTESIAN_POINT('',(-27.86158468659,0.,-65.78852163128)); -#243 = LINE('',#244,#245); -#244 = CARTESIAN_POINT('',(-31.12923147938,0.,-62.41195129628)); -#245 = VECTOR('',#246,1.); -#246 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#247 = ORIENTED_EDGE('',*,*,#248,.T.); -#248 = EDGE_CURVE('',#241,#249,#251,.T.); -#249 = VERTEX_POINT('',#250); -#250 = CARTESIAN_POINT('',(-25.53052705686,0.,-65.82673637491)); -#251 = CIRCLE('',#252,1.648528137424); -#252 = AXIS2_PLACEMENT_3D('',#253,#254,#255); -#253 = CARTESIAN_POINT('',(-26.67694849991,0.,-64.64210018823)); -#254 = DIRECTION('',(0.,-1.,0.)); -#255 = DIRECTION('',(-1.,0.,0.)); -#256 = ORIENTED_EDGE('',*,*,#257,.F.); -#257 = EDGE_CURVE('',#258,#249,#260,.T.); -#258 = VERTEX_POINT('',#259); -#259 = CARTESIAN_POINT('',(-20.53201900137,0.,-60.98947335481)); -#260 = LINE('',#261,#262); -#261 = CARTESIAN_POINT('',(-30.69923804215,0.,-70.82871181101)); -#262 = VECTOR('',#263,1.); -#263 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#264 = ORIENTED_EDGE('',*,*,#265,.T.); -#265 = EDGE_CURVE('',#258,#266,#268,.T.); -#266 = VERTEX_POINT('',#267); -#267 = CARTESIAN_POINT('',(20.532019001374,0.,-60.98947335481)); -#268 = LINE('',#269,#270); -#269 = CARTESIAN_POINT('',(-17.57924046663,0.,-60.98947335481)); -#270 = VECTOR('',#271,1.); -#271 = DIRECTION('',(1.,0.,0.)); -#272 = ORIENTED_EDGE('',*,*,#273,.T.); -#273 = EDGE_CURVE('',#266,#274,#276,.T.); -#274 = VERTEX_POINT('',#275); -#275 = CARTESIAN_POINT('',(26.715163243538,0.,-66.97315781796)); -#276 = LINE('',#277,#278); -#277 = CARTESIAN_POINT('',(7.481849370247,-4.440892098501E-16, - -48.36028435244)); -#278 = VECTOR('',#279,1.); -#279 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#280 = ORIENTED_EDGE('',*,*,#281,.T.); -#281 = EDGE_CURVE('',#274,#156,#282,.T.); -#282 = LINE('',#283,#284); -#283 = CARTESIAN_POINT('',(9.75933652063,0.,-84.4941890519)); -#284 = VECTOR('',#285,1.); -#285 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#286 = PLANE('',#287); -#287 = AXIS2_PLACEMENT_3D('',#288,#289,#290); -#288 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#289 = DIRECTION('',(0.,1.,0.)); -#290 = DIRECTION('',(0.,0.,1.)); -#291 = ADVANCED_FACE('',(#292),#317,.F.); -#292 = FACE_BOUND('',#293,.F.); -#293 = EDGE_LOOP('',(#294,#295,#303,#311)); -#294 = ORIENTED_EDGE('',*,*,#21,.T.); -#295 = ORIENTED_EDGE('',*,*,#296,.T.); -#296 = EDGE_CURVE('',#24,#297,#299,.T.); -#297 = VERTEX_POINT('',#298); -#298 = CARTESIAN_POINT('',(43.891390829132,20.8572529153,-6.628649129335 - )); -#299 = LINE('',#300,#301); -#300 = CARTESIAN_POINT('',(43.891390829132,-5.,-6.628649129335)); -#301 = VECTOR('',#302,1.); -#302 = DIRECTION('',(0.,1.,0.)); -#303 = ORIENTED_EDGE('',*,*,#304,.F.); -#304 = EDGE_CURVE('',#305,#297,#307,.T.); -#305 = VERTEX_POINT('',#306); -#306 = CARTESIAN_POINT('',(28.536336768195,20.8572529153,-54.80352892379 - )); -#307 = LINE('',#308,#309); -#308 = CARTESIAN_POINT('',(30.462276491561,20.8572529153,-48.76109401628 - )); -#309 = VECTOR('',#310,1.); -#310 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#311 = ORIENTED_EDGE('',*,*,#312,.F.); -#312 = EDGE_CURVE('',#22,#305,#313,.T.); -#313 = LINE('',#314,#315); -#314 = CARTESIAN_POINT('',(28.536336768195,-5.,-54.80352892379)); -#315 = VECTOR('',#316,1.); -#316 = DIRECTION('',(0.,1.,0.)); -#317 = PLANE('',#318); -#318 = AXIS2_PLACEMENT_3D('',#319,#320,#321); -#319 = CARTESIAN_POINT('',(43.891390829132,-5.,-6.628649129335)); -#320 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#321 = DIRECTION('',(-0.30368282823,0.,-0.952773183837)); -#322 = ADVANCED_FACE('',(#323),#341,.F.); -#323 = FACE_BOUND('',#324,.F.); -#324 = EDGE_LOOP('',(#325,#326,#334,#340)); -#325 = ORIENTED_EDGE('',*,*,#147,.T.); -#326 = ORIENTED_EDGE('',*,*,#327,.T.); -#327 = EDGE_CURVE('',#140,#328,#330,.T.); -#328 = VERTEX_POINT('',#329); -#329 = CARTESIAN_POINT('',(35.662741699797,20.8572529153,1.6)); -#330 = LINE('',#331,#332); -#331 = CARTESIAN_POINT('',(35.662741699797,-5.,1.6)); -#332 = VECTOR('',#333,1.); -#333 = DIRECTION('',(0.,1.,0.)); -#334 = ORIENTED_EDGE('',*,*,#335,.F.); -#335 = EDGE_CURVE('',#297,#328,#336,.T.); -#336 = LINE('',#337,#338); -#337 = CARTESIAN_POINT('',(33.5241070341,20.8572529153,3.738634665697)); -#338 = VECTOR('',#339,1.); -#339 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#340 = ORIENTED_EDGE('',*,*,#296,.F.); -#341 = PLANE('',#342); -#342 = AXIS2_PLACEMENT_3D('',#343,#344,#345); -#343 = CARTESIAN_POINT('',(35.662741699797,-5.,1.6)); -#344 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#345 = DIRECTION('',(0.707106781187,0.,-0.707106781187)); -#346 = ADVANCED_FACE('',(#347),#365,.T.); -#347 = FACE_BOUND('',#348,.T.); -#348 = EDGE_LOOP('',(#349,#350,#351,#359)); -#349 = ORIENTED_EDGE('',*,*,#139,.T.); -#350 = ORIENTED_EDGE('',*,*,#327,.T.); -#351 = ORIENTED_EDGE('',*,*,#352,.F.); -#352 = EDGE_CURVE('',#353,#328,#355,.T.); -#353 = VERTEX_POINT('',#354); -#354 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153,1.6)); -#355 = LINE('',#356,#357); -#356 = CARTESIAN_POINT('',(-4.901106540577,20.8572529153,1.6)); -#357 = VECTOR('',#358,1.); -#358 = DIRECTION('',(1.,0.,0.)); -#359 = ORIENTED_EDGE('',*,*,#360,.F.); -#360 = EDGE_CURVE('',#131,#353,#361,.T.); -#361 = LINE('',#362,#363); -#362 = CARTESIAN_POINT('',(-32.57517518159,-5.,1.6)); -#363 = VECTOR('',#364,1.); -#364 = DIRECTION('',(0.,1.,0.)); -#365 = PLANE('',#366); -#366 = AXIS2_PLACEMENT_3D('',#367,#368,#369); -#367 = CARTESIAN_POINT('',(35.662741699797,-5.,1.6)); -#368 = DIRECTION('',(0.,0.,1.)); -#369 = DIRECTION('',(-1.,0.,0.)); -#370 = ADVANCED_FACE('',(#371),#390,.T.); -#371 = FACE_BOUND('',#372,.F.); -#372 = EDGE_LOOP('',(#373,#374,#382,#389)); -#373 = ORIENTED_EDGE('',*,*,#130,.T.); -#374 = ORIENTED_EDGE('',*,*,#375,.T.); -#375 = EDGE_CURVE('',#123,#376,#378,.T.); -#376 = VERTEX_POINT('',#377); -#377 = CARTESIAN_POINT('',(-37.84598092218,20.8572529153,-0.583239222383 - )); -#378 = LINE('',#379,#380); -#379 = CARTESIAN_POINT('',(-37.84598092218,-5.,-0.583239222383)); -#380 = VECTOR('',#381,1.); -#381 = DIRECTION('',(0.,1.,0.)); -#382 = ORIENTED_EDGE('',*,*,#383,.F.); -#383 = EDGE_CURVE('',#353,#376,#384,.T.); -#384 = CIRCLE('',#385,7.454044962965); -#385 = AXIS2_PLACEMENT_3D('',#386,#387,#388); -#386 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153,-5.854044962965 - )); -#387 = DIRECTION('',(0.,-1.,0.)); -#388 = DIRECTION('',(1.,0.,0.)); -#389 = ORIENTED_EDGE('',*,*,#360,.F.); -#390 = CYLINDRICAL_SURFACE('',#391,7.454044962965); -#391 = AXIS2_PLACEMENT_3D('',#392,#393,#394); -#392 = CARTESIAN_POINT('',(-32.57517518159,-5.,-5.854044962965)); -#393 = DIRECTION('',(0.,-1.,0.)); -#394 = DIRECTION('',(1.,0.,0.)); -#395 = ADVANCED_FACE('',(#396),#414,.T.); -#396 = FACE_BOUND('',#397,.T.); -#397 = EDGE_LOOP('',(#398,#399,#400,#408)); -#398 = ORIENTED_EDGE('',*,*,#122,.T.); -#399 = ORIENTED_EDGE('',*,*,#375,.T.); -#400 = ORIENTED_EDGE('',*,*,#401,.F.); -#401 = EDGE_CURVE('',#402,#376,#404,.T.); -#402 = VERTEX_POINT('',#403); -#403 = CARTESIAN_POINT('',(-40.68171555857,20.8572529153,-3.418973858775 - )); -#404 = LINE('',#405,#406); -#405 = CARTESIAN_POINT('',(-57.34820403576,20.8572529153,-20.08546233597 - )); -#406 = VECTOR('',#407,1.); -#407 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#408 = ORIENTED_EDGE('',*,*,#409,.F.); -#409 = EDGE_CURVE('',#114,#402,#410,.T.); -#410 = LINE('',#411,#412); -#411 = CARTESIAN_POINT('',(-40.68171555857,-5.,-3.418973858775)); -#412 = VECTOR('',#413,1.); -#413 = DIRECTION('',(0.,1.,0.)); -#414 = PLANE('',#415); -#415 = AXIS2_PLACEMENT_3D('',#416,#417,#418); -#416 = CARTESIAN_POINT('',(-37.84598092218,-5.,-0.583239222383)); -#417 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#418 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#419 = ADVANCED_FACE('',(#420),#439,.T.); -#420 = FACE_BOUND('',#421,.F.); -#421 = EDGE_LOOP('',(#422,#423,#431,#438)); -#422 = ORIENTED_EDGE('',*,*,#113,.T.); -#423 = ORIENTED_EDGE('',*,*,#424,.T.); -#424 = EDGE_CURVE('',#106,#425,#427,.T.); -#425 = VERTEX_POINT('',#426); -#426 = CARTESIAN_POINT('',(-42.51292396981,20.8572529153,-10.95344505546 - )); -#427 = LINE('',#428,#429); -#428 = CARTESIAN_POINT('',(-42.51292396981,-5.,-10.95344505546)); -#429 = VECTOR('',#430,1.); -#430 = DIRECTION('',(0.,1.,0.)); -#431 = ORIENTED_EDGE('',*,*,#432,.F.); -#432 = EDGE_CURVE('',#402,#425,#433,.T.); -#433 = CIRCLE('',#434,7.454044962965); -#434 = AXIS2_PLACEMENT_3D('',#435,#436,#437); -#435 = CARTESIAN_POINT('',(-35.41090981799,20.8572529153,-8.689779599357 - )); -#436 = DIRECTION('',(0.,-1.,0.)); -#437 = DIRECTION('',(1.,0.,0.)); -#438 = ORIENTED_EDGE('',*,*,#409,.F.); -#439 = CYLINDRICAL_SURFACE('',#440,7.454044962965); -#440 = AXIS2_PLACEMENT_3D('',#441,#442,#443); -#441 = CARTESIAN_POINT('',(-35.41090981799,-5.,-8.689779599357)); -#442 = DIRECTION('',(0.,-1.,0.)); -#443 = DIRECTION('',(1.,0.,0.)); -#444 = ADVANCED_FACE('',(#445),#463,.T.); -#445 = FACE_BOUND('',#446,.T.); -#446 = EDGE_LOOP('',(#447,#448,#449,#457)); -#447 = ORIENTED_EDGE('',*,*,#105,.T.); -#448 = ORIENTED_EDGE('',*,*,#424,.T.); -#449 = ORIENTED_EDGE('',*,*,#450,.F.); -#450 = EDGE_CURVE('',#451,#425,#453,.T.); -#451 = VERTEX_POINT('',#452); -#452 = CARTESIAN_POINT('',(-28.53633676819,20.8572529153,-54.80352892379 - )); -#453 = LINE('',#454,#455); -#454 = CARTESIAN_POINT('',(-33.96596941491,20.8572529153,-37.76862308461 - )); -#455 = VECTOR('',#456,1.); -#456 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#457 = ORIENTED_EDGE('',*,*,#458,.F.); -#458 = EDGE_CURVE('',#98,#451,#459,.T.); -#459 = LINE('',#460,#461); -#460 = CARTESIAN_POINT('',(-28.53633676819,-5.,-54.80352892379)); -#461 = VECTOR('',#462,1.); -#462 = DIRECTION('',(0.,1.,0.)); -#463 = PLANE('',#464); -#464 = AXIS2_PLACEMENT_3D('',#465,#466,#467); -#465 = CARTESIAN_POINT('',(-42.51292396981,-5.,-10.95344505546)); -#466 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#467 = DIRECTION('',(0.30368282823,0.,-0.952773183837)); -#468 = ADVANCED_FACE('',(#469),#487,.T.); -#469 = FACE_BOUND('',#470,.T.); -#470 = EDGE_LOOP('',(#471,#472,#473,#481)); -#471 = ORIENTED_EDGE('',*,*,#97,.T.); -#472 = ORIENTED_EDGE('',*,*,#458,.T.); -#473 = ORIENTED_EDGE('',*,*,#474,.F.); -#474 = EDGE_CURVE('',#475,#451,#477,.T.); -#475 = VERTEX_POINT('',#476); -#476 = CARTESIAN_POINT('',(-29.94071467356,20.8572529153,-56.16260351814 - )); -#477 = LINE('',#478,#479); -#478 = CARTESIAN_POINT('',(-36.94745061313,20.8572529153,-62.94331173664 - )); -#479 = VECTOR('',#480,1.); -#480 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#481 = ORIENTED_EDGE('',*,*,#482,.F.); -#482 = EDGE_CURVE('',#89,#475,#483,.T.); -#483 = LINE('',#484,#485); -#484 = CARTESIAN_POINT('',(-29.94071467356,-5.,-56.16260351814)); -#485 = VECTOR('',#486,1.); -#486 = DIRECTION('',(0.,1.,0.)); -#487 = PLANE('',#488); -#488 = AXIS2_PLACEMENT_3D('',#489,#490,#491); -#489 = CARTESIAN_POINT('',(-28.53633676819,-5.,-54.80352892379)); -#490 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#491 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#492 = ADVANCED_FACE('',(#493),#512,.T.); -#493 = FACE_BOUND('',#494,.F.); -#494 = EDGE_LOOP('',(#495,#496,#504,#511)); -#495 = ORIENTED_EDGE('',*,*,#88,.T.); -#496 = ORIENTED_EDGE('',*,*,#497,.T.); -#497 = EDGE_CURVE('',#81,#498,#500,.T.); -#498 = VERTEX_POINT('',#499); -#499 = CARTESIAN_POINT('',(-30.0937101258,20.8572529153,-65.49515903052) - ); -#500 = LINE('',#501,#502); -#501 = CARTESIAN_POINT('',(-30.0937101258,-5.,-65.49515903052)); -#502 = VECTOR('',#503,1.); -#503 = DIRECTION('',(0.,1.,0.)); -#504 = ORIENTED_EDGE('',*,*,#505,.F.); -#505 = EDGE_CURVE('',#475,#498,#506,.T.); -#506 = CIRCLE('',#507,6.6); -#507 = AXIS2_PLACEMENT_3D('',#508,#509,#510); -#508 = CARTESIAN_POINT('',(-25.35093464349,20.8572529153,-60.90537900045 - )); -#509 = DIRECTION('',(0.,-1.,0.)); -#510 = DIRECTION('',(1.,0.,0.)); -#511 = ORIENTED_EDGE('',*,*,#482,.F.); -#512 = CYLINDRICAL_SURFACE('',#513,6.6); -#513 = AXIS2_PLACEMENT_3D('',#514,#515,#516); -#514 = CARTESIAN_POINT('',(-25.35093464349,-5.,-60.90537900045)); -#515 = DIRECTION('',(0.,-1.,0.)); -#516 = DIRECTION('',(1.,0.,0.)); -#517 = ADVANCED_FACE('',(#518),#536,.T.); -#518 = FACE_BOUND('',#519,.T.); -#519 = EDGE_LOOP('',(#520,#521,#522,#530)); -#520 = ORIENTED_EDGE('',*,*,#80,.T.); -#521 = ORIENTED_EDGE('',*,*,#497,.T.); -#522 = ORIENTED_EDGE('',*,*,#523,.F.); -#523 = EDGE_CURVE('',#524,#498,#526,.T.); -#524 = VERTEX_POINT('',#525); -#525 = CARTESIAN_POINT('',(-28.86762797071,20.8572529153,-66.76211133463 - )); -#526 = LINE('',#527,#528); -#527 = CARTESIAN_POINT('',(-32.44179530228,20.8572529153,-63.0688029236) - ); -#528 = VECTOR('',#529,1.); -#529 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#530 = ORIENTED_EDGE('',*,*,#531,.F.); -#531 = EDGE_CURVE('',#72,#524,#532,.T.); -#532 = LINE('',#533,#534); -#533 = CARTESIAN_POINT('',(-28.86762797071,-5.,-66.76211133463)); -#534 = VECTOR('',#535,1.); -#535 = DIRECTION('',(0.,1.,0.)); -#536 = PLANE('',#537); -#537 = AXIS2_PLACEMENT_3D('',#538,#539,#540); -#538 = CARTESIAN_POINT('',(-30.0937101258,-5.,-65.49515903052)); -#539 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#540 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#541 = ADVANCED_FACE('',(#542),#561,.T.); -#542 = FACE_BOUND('',#543,.F.); -#543 = EDGE_LOOP('',(#544,#545,#553,#560)); -#544 = ORIENTED_EDGE('',*,*,#71,.T.); -#545 = ORIENTED_EDGE('',*,*,#546,.T.); -#546 = EDGE_CURVE('',#64,#547,#549,.T.); -#547 = VERTEX_POINT('',#548); -#548 = CARTESIAN_POINT('',(-24.55693735351,20.8572529153,-66.83277965903 - )); -#549 = LINE('',#550,#551); -#550 = CARTESIAN_POINT('',(-24.55693735351,-5.,-66.83277965903)); -#551 = VECTOR('',#552,1.); -#552 = DIRECTION('',(0.,1.,0.)); -#553 = ORIENTED_EDGE('',*,*,#554,.F.); -#554 = EDGE_CURVE('',#524,#547,#555,.T.); -#555 = CIRCLE('',#556,3.048528137424); -#556 = AXIS2_PLACEMENT_3D('',#557,#558,#559); -#557 = CARTESIAN_POINT('',(-26.67694849991,20.8572529153,-64.64210018823 - )); -#558 = DIRECTION('',(0.,-1.,0.)); -#559 = DIRECTION('',(1.,0.,0.)); -#560 = ORIENTED_EDGE('',*,*,#531,.F.); -#561 = CYLINDRICAL_SURFACE('',#562,3.048528137424); -#562 = AXIS2_PLACEMENT_3D('',#563,#564,#565); -#563 = CARTESIAN_POINT('',(-26.67694849991,-5.,-64.64210018823)); -#564 = DIRECTION('',(0.,-1.,0.)); -#565 = DIRECTION('',(1.,0.,0.)); -#566 = ADVANCED_FACE('',(#567),#585,.T.); -#567 = FACE_BOUND('',#568,.T.); -#568 = EDGE_LOOP('',(#569,#570,#571,#579)); -#569 = ORIENTED_EDGE('',*,*,#63,.T.); -#570 = ORIENTED_EDGE('',*,*,#546,.T.); -#571 = ORIENTED_EDGE('',*,*,#572,.F.); -#572 = EDGE_CURVE('',#573,#547,#575,.T.); -#573 = VERTEX_POINT('',#574); -#574 = CARTESIAN_POINT('',(-19.96551814343,20.8572529153,-62.38947335481 - )); -#575 = LINE('',#576,#577); -#576 = CARTESIAN_POINT('',(-30.98981424001,20.8572529153,-73.05814073287 - )); -#577 = VECTOR('',#578,1.); -#578 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#579 = ORIENTED_EDGE('',*,*,#580,.F.); -#580 = EDGE_CURVE('',#56,#573,#581,.T.); -#581 = LINE('',#582,#583); -#582 = CARTESIAN_POINT('',(-19.96551814343,-5.,-62.38947335481)); -#583 = VECTOR('',#584,1.); -#584 = DIRECTION('',(0.,1.,0.)); -#585 = PLANE('',#586); -#586 = AXIS2_PLACEMENT_3D('',#587,#588,#589); -#587 = CARTESIAN_POINT('',(-24.55693735351,-5.,-66.83277965903)); -#588 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#589 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#590 = ADVANCED_FACE('',(#591),#609,.F.); -#591 = FACE_BOUND('',#592,.F.); -#592 = EDGE_LOOP('',(#593,#594,#602,#608)); -#593 = ORIENTED_EDGE('',*,*,#55,.T.); -#594 = ORIENTED_EDGE('',*,*,#595,.T.); -#595 = EDGE_CURVE('',#48,#596,#598,.T.); -#596 = VERTEX_POINT('',#597); -#597 = CARTESIAN_POINT('',(19.965518143439,20.8572529153,-62.38947335481 - )); -#598 = LINE('',#599,#600); -#599 = CARTESIAN_POINT('',(19.965518143439,-5.,-62.38947335481)); -#600 = VECTOR('',#601,1.); -#601 = DIRECTION('',(0.,1.,0.)); -#602 = ORIENTED_EDGE('',*,*,#603,.F.); -#603 = EDGE_CURVE('',#573,#596,#604,.T.); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-12.74971831875,20.8572529153,-62.38947335481 - )); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(1.,0.,0.)); -#608 = ORIENTED_EDGE('',*,*,#580,.F.); -#609 = PLANE('',#610); -#610 = AXIS2_PLACEMENT_3D('',#611,#612,#613); -#611 = CARTESIAN_POINT('',(19.965518143439,-5.,-62.38947335481)); -#612 = DIRECTION('',(0.,0.,1.)); -#613 = DIRECTION('',(-1.,0.,0.)); -#614 = ADVANCED_FACE('',(#615),#633,.F.); -#615 = FACE_BOUND('',#616,.F.); -#616 = EDGE_LOOP('',(#617,#618,#626,#632)); -#617 = ORIENTED_EDGE('',*,*,#47,.T.); -#618 = ORIENTED_EDGE('',*,*,#619,.T.); -#619 = EDGE_CURVE('',#40,#620,#622,.T.); -#620 = VERTEX_POINT('',#621); -#621 = CARTESIAN_POINT('',(26.747616824317,20.8572529153,-68.95279080543 - )); -#622 = LINE('',#623,#624); -#623 = CARTESIAN_POINT('',(26.747616824317,-5.,-68.95279080543)); -#624 = VECTOR('',#625,1.); -#625 = DIRECTION('',(0.,1.,0.)); -#626 = ORIENTED_EDGE('',*,*,#627,.F.); -#627 = EDGE_CURVE('',#596,#620,#628,.T.); -#628 = LINE('',#629,#630); -#629 = CARTESIAN_POINT('',(8.607536374131,20.8572529153,-51.39788454757) - ); -#630 = VECTOR('',#631,1.); -#631 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#632 = ORIENTED_EDGE('',*,*,#595,.F.); -#633 = PLANE('',#634); -#634 = AXIS2_PLACEMENT_3D('',#635,#636,#637); -#635 = CARTESIAN_POINT('',(26.747616824317,-5.,-68.95279080543)); -#636 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#637 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#638 = ADVANCED_FACE('',(#639),#657,.F.); -#639 = FACE_BOUND('',#640,.F.); -#640 = EDGE_LOOP('',(#641,#642,#650,#656)); -#641 = ORIENTED_EDGE('',*,*,#39,.T.); -#642 = ORIENTED_EDGE('',*,*,#643,.T.); -#643 = EDGE_CURVE('',#32,#644,#646,.T.); -#644 = VERTEX_POINT('',#645); -#645 = CARTESIAN_POINT('',(34.683490155872,20.8572529153,-60.75238354821 - )); -#646 = LINE('',#647,#648); -#647 = CARTESIAN_POINT('',(34.683490155872,-5.,-60.75238354821)); -#648 = VECTOR('',#649,1.); -#649 = DIRECTION('',(0.,1.,0.)); -#650 = ORIENTED_EDGE('',*,*,#651,.F.); -#651 = EDGE_CURVE('',#620,#644,#652,.T.); -#652 = LINE('',#653,#654); -#653 = CARTESIAN_POINT('',(12.749348137648,20.8572529153,-83.41767694094 - )); -#654 = VECTOR('',#655,1.); -#655 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#656 = ORIENTED_EDGE('',*,*,#619,.F.); -#657 = PLANE('',#658); -#658 = AXIS2_PLACEMENT_3D('',#659,#660,#661); -#659 = CARTESIAN_POINT('',(34.683490155872,-5.,-60.75238354821)); -#660 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#661 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#662 = ADVANCED_FACE('',(#663),#674,.F.); -#663 = FACE_BOUND('',#664,.F.); -#664 = EDGE_LOOP('',(#665,#666,#667,#673)); -#665 = ORIENTED_EDGE('',*,*,#31,.T.); -#666 = ORIENTED_EDGE('',*,*,#312,.T.); -#667 = ORIENTED_EDGE('',*,*,#668,.F.); -#668 = EDGE_CURVE('',#644,#305,#669,.T.); -#669 = LINE('',#670,#671); -#670 = CARTESIAN_POINT('',(13.469833011847,20.8572529153,-40.22304997814 - )); -#671 = VECTOR('',#672,1.); -#672 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#673 = ORIENTED_EDGE('',*,*,#643,.F.); -#674 = PLANE('',#675); -#675 = AXIS2_PLACEMENT_3D('',#676,#677,#678); -#676 = CARTESIAN_POINT('',(28.536336768195,-5.,-54.80352892379)); -#677 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#678 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#679 = ADVANCED_FACE('',(#680),#705,.T.); -#680 = FACE_BOUND('',#681,.T.); -#681 = EDGE_LOOP('',(#682,#690,#691,#699)); -#682 = ORIENTED_EDGE('',*,*,#683,.F.); -#683 = EDGE_CURVE('',#156,#684,#686,.T.); -#684 = VERTEX_POINT('',#685); -#685 = CARTESIAN_POINT('',(32.703857168398,3.2,-60.78483712899)); -#686 = LINE('',#687,#688); -#687 = CARTESIAN_POINT('',(32.703857168398,3.,-60.78483712899)); -#688 = VECTOR('',#689,1.); -#689 = DIRECTION('',(0.,1.,0.)); -#690 = ORIENTED_EDGE('',*,*,#155,.T.); -#691 = ORIENTED_EDGE('',*,*,#692,.F.); -#692 = EDGE_CURVE('',#693,#158,#695,.T.); -#693 = VERTEX_POINT('',#694); -#694 = CARTESIAN_POINT('',(26.938753236523,3.2,-55.20570756731)); -#695 = LINE('',#696,#697); -#696 = CARTESIAN_POINT('',(26.938753236523,3.,-55.20570756731)); -#697 = VECTOR('',#698,1.); -#698 = DIRECTION('',(0.,-1.,0.)); -#699 = ORIENTED_EDGE('',*,*,#700,.F.); -#700 = EDGE_CURVE('',#684,#693,#701,.T.); -#701 = LINE('',#702,#703); -#702 = CARTESIAN_POINT('',(16.008242280412,3.2,-44.62779994931)); -#703 = VECTOR('',#704,1.); -#704 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#705 = PLANE('',#706); -#706 = AXIS2_PLACEMENT_3D('',#707,#708,#709); -#707 = CARTESIAN_POINT('',(29.704873980143,3.,-57.88259703786)); -#708 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#709 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#710 = ADVANCED_FACE('',(#711),#729,.T.); -#711 = FACE_BOUND('',#712,.T.); -#712 = EDGE_LOOP('',(#713,#721,#722,#723)); -#713 = ORIENTED_EDGE('',*,*,#714,.F.); -#714 = EDGE_CURVE('',#274,#715,#717,.T.); -#715 = VERTEX_POINT('',#716); -#716 = CARTESIAN_POINT('',(26.715163243538,3.2,-66.97315781796)); -#717 = LINE('',#718,#719); -#718 = CARTESIAN_POINT('',(26.715163243538,3.,-66.97315781796)); -#719 = VECTOR('',#720,1.); -#720 = DIRECTION('',(0.,1.,0.)); -#721 = ORIENTED_EDGE('',*,*,#281,.T.); -#722 = ORIENTED_EDGE('',*,*,#683,.T.); -#723 = ORIENTED_EDGE('',*,*,#724,.F.); -#724 = EDGE_CURVE('',#715,#684,#725,.T.); -#725 = LINE('',#726,#727); -#726 = CARTESIAN_POINT('',(30.25240665457,3.2,-63.31800414721)); -#727 = VECTOR('',#728,1.); -#728 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#729 = PLANE('',#730); -#730 = AXIS2_PLACEMENT_3D('',#731,#732,#733); -#731 = CARTESIAN_POINT('',(29.709510205968,3.,-63.87899747347)); -#732 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#733 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#734 = ADVANCED_FACE('',(#735),#753,.T.); -#735 = FACE_BOUND('',#736,.T.); -#736 = EDGE_LOOP('',(#737,#745,#746,#747)); -#737 = ORIENTED_EDGE('',*,*,#738,.F.); -#738 = EDGE_CURVE('',#693,#739,#741,.T.); -#739 = VERTEX_POINT('',#740); -#740 = CARTESIAN_POINT('',(42.298608189024,3.2,-7.015765476549)); -#741 = LINE('',#742,#743); -#742 = CARTESIAN_POINT('',(32.699020781567,3.2,-37.13346923684)); -#743 = VECTOR('',#744,1.); -#744 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#745 = ORIENTED_EDGE('',*,*,#692,.T.); -#746 = ORIENTED_EDGE('',*,*,#165,.T.); -#747 = ORIENTED_EDGE('',*,*,#748,.F.); -#748 = EDGE_CURVE('',#739,#166,#749,.T.); -#749 = LINE('',#750,#751); -#750 = CARTESIAN_POINT('',(42.298608189024,3.,-7.015765476549)); -#751 = VECTOR('',#752,1.); -#752 = DIRECTION('',(0.,-1.,0.)); -#753 = PLANE('',#754); -#754 = AXIS2_PLACEMENT_3D('',#755,#756,#757); -#755 = CARTESIAN_POINT('',(34.581352051556,3.,-31.22785130119)); -#756 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#757 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#758 = ADVANCED_FACE('',(#759),#777,.T.); -#759 = FACE_BOUND('',#760,.T.); -#760 = EDGE_LOOP('',(#761,#769,#775,#776)); -#761 = ORIENTED_EDGE('',*,*,#762,.F.); -#762 = EDGE_CURVE('',#763,#715,#765,.T.); -#763 = VERTEX_POINT('',#764); -#764 = CARTESIAN_POINT('',(20.532019001374,3.2,-60.98947335481)); -#765 = LINE('',#766,#767); -#766 = CARTESIAN_POINT('',(9.922784884512,3.2,-50.72247862452)); -#767 = VECTOR('',#768,1.); -#768 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#769 = ORIENTED_EDGE('',*,*,#770,.T.); -#770 = EDGE_CURVE('',#763,#266,#771,.T.); -#771 = LINE('',#772,#773); -#772 = CARTESIAN_POINT('',(20.532019001374,3.,-60.98947335481)); -#773 = VECTOR('',#774,1.); -#774 = DIRECTION('',(0.,-1.,0.)); -#775 = ORIENTED_EDGE('',*,*,#273,.T.); -#776 = ORIENTED_EDGE('',*,*,#714,.T.); -#777 = PLANE('',#778); -#778 = AXIS2_PLACEMENT_3D('',#779,#780,#781); -#779 = CARTESIAN_POINT('',(23.522653113203,3.,-63.8836336993)); -#780 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#781 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#782 = ADVANCED_FACE('',(#783),#801,.T.); -#783 = FACE_BOUND('',#784,.T.); -#784 = EDGE_LOOP('',(#785,#786,#787,#795)); -#785 = ORIENTED_EDGE('',*,*,#748,.T.); -#786 = ORIENTED_EDGE('',*,*,#173,.T.); -#787 = ORIENTED_EDGE('',*,*,#788,.F.); -#788 = EDGE_CURVE('',#789,#174,#791,.T.); -#789 = VERTEX_POINT('',#790); -#790 = CARTESIAN_POINT('',(35.082842712475,3.2,0.2)); -#791 = LINE('',#792,#793); -#792 = CARTESIAN_POINT('',(35.082842712475,3.,0.2)); -#793 = VECTOR('',#794,1.); -#794 = DIRECTION('',(0.,-1.,0.)); -#795 = ORIENTED_EDGE('',*,*,#796,.F.); -#796 = EDGE_CURVE('',#739,#789,#797,.T.); -#797 = LINE('',#798,#799); -#798 = CARTESIAN_POINT('',(36.596246576251,3.2,-1.313403863776)); -#799 = VECTOR('',#800,1.); -#800 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#801 = PLANE('',#802); -#802 = AXIS2_PLACEMENT_3D('',#803,#804,#805); -#803 = CARTESIAN_POINT('',(38.67695526217,3.,-3.394112549695)); -#804 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#805 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#806 = ADVANCED_FACE('',(#807),#825,.T.); -#807 = FACE_BOUND('',#808,.T.); -#808 = EDGE_LOOP('',(#809,#817,#818,#819)); -#809 = ORIENTED_EDGE('',*,*,#810,.F.); -#810 = EDGE_CURVE('',#258,#811,#813,.T.); -#811 = VERTEX_POINT('',#812); -#812 = CARTESIAN_POINT('',(-20.53201900137,3.2,-60.98947335481)); -#813 = LINE('',#814,#815); -#814 = CARTESIAN_POINT('',(-20.53201900137,3.,-60.98947335481)); -#815 = VECTOR('',#816,1.); -#816 = DIRECTION('',(0.,1.,0.)); -#817 = ORIENTED_EDGE('',*,*,#265,.T.); -#818 = ORIENTED_EDGE('',*,*,#770,.F.); -#819 = ORIENTED_EDGE('',*,*,#820,.F.); -#820 = EDGE_CURVE('',#811,#763,#821,.T.); -#821 = LINE('',#822,#823); -#822 = CARTESIAN_POINT('',(5.354765181569,3.2,-60.98947335481)); -#823 = VECTOR('',#824,1.); -#824 = DIRECTION('',(1.,0.,0.)); -#825 = PLANE('',#826); -#826 = AXIS2_PLACEMENT_3D('',#827,#828,#829); -#827 = CARTESIAN_POINT('',(10.306473847682,3.,-60.98947335481)); -#828 = DIRECTION('',(0.,0.,1.)); -#829 = DIRECTION('',(0.,-1.,0.)); -#830 = ADVANCED_FACE('',(#831),#849,.F.); -#831 = FACE_BOUND('',#832,.F.); -#832 = EDGE_LOOP('',(#833,#834,#842,#848)); -#833 = ORIENTED_EDGE('',*,*,#788,.F.); -#834 = ORIENTED_EDGE('',*,*,#835,.F.); -#835 = EDGE_CURVE('',#836,#789,#838,.T.); -#836 = VERTEX_POINT('',#837); -#837 = CARTESIAN_POINT('',(-32.57517518159,3.2,0.2)); -#838 = LINE('',#839,#840); -#839 = CARTESIAN_POINT('',(-7.942265537672,3.2,0.2)); -#840 = VECTOR('',#841,1.); -#841 = DIRECTION('',(1.,0.,0.)); -#842 = ORIENTED_EDGE('',*,*,#843,.T.); -#843 = EDGE_CURVE('',#836,#182,#844,.T.); -#844 = LINE('',#845,#846); -#845 = CARTESIAN_POINT('',(-32.57517518159,3.,0.2)); -#846 = VECTOR('',#847,1.); -#847 = DIRECTION('',(0.,-1.,0.)); -#848 = ORIENTED_EDGE('',*,*,#181,.T.); -#849 = PLANE('',#850); -#850 = AXIS2_PLACEMENT_3D('',#851,#852,#853); -#851 = CARTESIAN_POINT('',(-16.28758759079,3.,0.2)); -#852 = DIRECTION('',(0.,0.,1.)); -#853 = DIRECTION('',(0.,-1.,0.)); -#854 = ADVANCED_FACE('',(#855),#873,.F.); -#855 = FACE_BOUND('',#856,.F.); -#856 = EDGE_LOOP('',(#857,#865,#871,#872)); -#857 = ORIENTED_EDGE('',*,*,#858,.F.); -#858 = EDGE_CURVE('',#859,#249,#861,.T.); -#859 = VERTEX_POINT('',#860); -#860 = CARTESIAN_POINT('',(-25.53052705686,3.2,-65.82673637491)); -#861 = LINE('',#862,#863); -#862 = CARTESIAN_POINT('',(-25.53052705686,3.,-65.82673637491)); -#863 = VECTOR('',#864,1.); -#864 = DIRECTION('',(0.,-1.,0.)); -#865 = ORIENTED_EDGE('',*,*,#866,.F.); -#866 = EDGE_CURVE('',#811,#859,#867,.T.); -#867 = LINE('',#868,#869); -#868 = CARTESIAN_POINT('',(-9.454421870603,3.2,-50.26922436104)); -#869 = VECTOR('',#870,1.); -#870 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#871 = ORIENTED_EDGE('',*,*,#810,.F.); -#872 = ORIENTED_EDGE('',*,*,#257,.T.); -#873 = PLANE('',#874); -#874 = AXIS2_PLACEMENT_3D('',#875,#876,#877); -#875 = CARTESIAN_POINT('',(-23.00219525444,3.,-63.37996509944)); -#876 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#877 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#878 = ADVANCED_FACE('',(#879),#898,.F.); -#879 = FACE_BOUND('',#880,.F.); -#880 = EDGE_LOOP('',(#881,#882,#891,#897)); -#881 = ORIENTED_EDGE('',*,*,#843,.F.); -#882 = ORIENTED_EDGE('',*,*,#883,.T.); -#883 = EDGE_CURVE('',#836,#884,#886,.T.); -#884 = VERTEX_POINT('',#885); -#885 = CARTESIAN_POINT('',(-36.85603142851,3.2,-1.573188716044)); -#886 = CIRCLE('',#887,6.054044962965); -#887 = AXIS2_PLACEMENT_3D('',#888,#889,#890); -#888 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#889 = DIRECTION('',(0.,-1.,0.)); -#890 = DIRECTION('',(-1.,0.,0.)); -#891 = ORIENTED_EDGE('',*,*,#892,.T.); -#892 = EDGE_CURVE('',#884,#190,#893,.T.); -#893 = LINE('',#894,#895); -#894 = CARTESIAN_POINT('',(-36.85603142851,3.,-1.573188716044)); -#895 = VECTOR('',#896,1.); -#896 = DIRECTION('',(0.,-1.,0.)); -#897 = ORIENTED_EDGE('',*,*,#189,.F.); -#898 = CYLINDRICAL_SURFACE('',#899,6.054044962965); -#899 = AXIS2_PLACEMENT_3D('',#900,#901,#902); -#900 = CARTESIAN_POINT('',(-32.57517518159,3.,-5.854044962965)); -#901 = DIRECTION('',(0.,-1.,0.)); -#902 = DIRECTION('',(-1.,0.,0.)); -#903 = ADVANCED_FACE('',(#904),#923,.F.); -#904 = FACE_BOUND('',#905,.F.); -#905 = EDGE_LOOP('',(#906,#914,#921,#922)); -#906 = ORIENTED_EDGE('',*,*,#907,.F.); -#907 = EDGE_CURVE('',#908,#241,#910,.T.); -#908 = VERTEX_POINT('',#909); -#909 = CARTESIAN_POINT('',(-27.86158468659,3.2,-65.78852163128)); -#910 = LINE('',#911,#912); -#911 = CARTESIAN_POINT('',(-27.86158468659,3.,-65.78852163128)); -#912 = VECTOR('',#913,1.); -#913 = DIRECTION('',(0.,-1.,0.)); -#914 = ORIENTED_EDGE('',*,*,#915,.T.); -#915 = EDGE_CURVE('',#908,#859,#916,.T.); -#916 = CIRCLE('',#917,1.648528137424); -#917 = AXIS2_PLACEMENT_3D('',#918,#919,#920); -#918 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#919 = DIRECTION('',(0.,-1.,0.)); -#920 = DIRECTION('',(-1.,0.,0.)); -#921 = ORIENTED_EDGE('',*,*,#858,.T.); -#922 = ORIENTED_EDGE('',*,*,#248,.F.); -#923 = CYLINDRICAL_SURFACE('',#924,1.648528137424); -#924 = AXIS2_PLACEMENT_3D('',#925,#926,#927); -#925 = CARTESIAN_POINT('',(-26.67694849991,3.,-64.64210018823)); -#926 = DIRECTION('',(0.,-1.,0.)); -#927 = DIRECTION('',(-1.,0.,0.)); -#928 = ADVANCED_FACE('',(#929),#947,.F.); -#929 = FACE_BOUND('',#930,.F.); -#930 = EDGE_LOOP('',(#931,#932,#940,#946)); -#931 = ORIENTED_EDGE('',*,*,#892,.F.); -#932 = ORIENTED_EDGE('',*,*,#933,.F.); -#933 = EDGE_CURVE('',#934,#884,#936,.T.); -#934 = VERTEX_POINT('',#935); -#935 = CARTESIAN_POINT('',(-39.69176606491,3.2,-4.408923352436)); -#936 = LINE('',#937,#938); -#937 = CARTESIAN_POINT('',(-36.19319006079,3.2,-0.910347348321)); -#938 = VECTOR('',#939,1.); -#939 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#940 = ORIENTED_EDGE('',*,*,#941,.T.); -#941 = EDGE_CURVE('',#934,#199,#942,.T.); -#942 = LINE('',#943,#944); -#943 = CARTESIAN_POINT('',(-39.69176606491,3.,-4.408923352436)); -#944 = VECTOR('',#945,1.); -#945 = DIRECTION('',(0.,-1.,0.)); -#946 = ORIENTED_EDGE('',*,*,#198,.T.); -#947 = PLANE('',#948); -#948 = AXIS2_PLACEMENT_3D('',#949,#950,#951); -#949 = CARTESIAN_POINT('',(-38.27389874671,3.,-2.99105603424)); -#950 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#951 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#952 = ADVANCED_FACE('',(#953),#971,.F.); -#953 = FACE_BOUND('',#954,.F.); -#954 = EDGE_LOOP('',(#955,#963,#969,#970)); -#955 = ORIENTED_EDGE('',*,*,#956,.F.); -#956 = EDGE_CURVE('',#957,#232,#959,.T.); -#957 = VERTEX_POINT('',#958); -#958 = CARTESIAN_POINT('',(-29.08766684168,3.2,-64.52156932717)); -#959 = LINE('',#960,#961); -#960 = CARTESIAN_POINT('',(-29.08766684168,3.,-64.52156932717)); -#961 = VECTOR('',#962,1.); -#962 = DIRECTION('',(0.,-1.,0.)); -#963 = ORIENTED_EDGE('',*,*,#964,.F.); -#964 = EDGE_CURVE('',#908,#957,#965,.T.); -#965 = LINE('',#966,#967); -#966 = CARTESIAN_POINT('',(-29.44004200272,3.2,-64.15744811364)); -#967 = VECTOR('',#968,1.); -#968 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#969 = ORIENTED_EDGE('',*,*,#907,.T.); -#970 = ORIENTED_EDGE('',*,*,#240,.T.); -#971 = PLANE('',#972); -#972 = AXIS2_PLACEMENT_3D('',#973,#974,#975); -#973 = CARTESIAN_POINT('',(-28.47462576413,3.,-65.15504547923)); -#974 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#975 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#976 = ADVANCED_FACE('',(#977),#996,.F.); -#977 = FACE_BOUND('',#978,.F.); -#978 = EDGE_LOOP('',(#979,#980,#989,#995)); -#979 = ORIENTED_EDGE('',*,*,#941,.F.); -#980 = ORIENTED_EDGE('',*,*,#981,.T.); -#981 = EDGE_CURVE('',#934,#982,#984,.T.); -#982 = VERTEX_POINT('',#983); -#983 = CARTESIAN_POINT('',(-41.17904151244,3.2,-10.52828909594)); -#984 = CIRCLE('',#985,6.054044962965); -#985 = AXIS2_PLACEMENT_3D('',#986,#987,#988); -#986 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#987 = DIRECTION('',(0.,-1.,0.)); -#988 = DIRECTION('',(-1.,0.,0.)); -#989 = ORIENTED_EDGE('',*,*,#990,.T.); -#990 = EDGE_CURVE('',#982,#207,#991,.T.); -#991 = LINE('',#992,#993); -#992 = CARTESIAN_POINT('',(-41.17904151244,3.,-10.52828909594)); -#993 = VECTOR('',#994,1.); -#994 = DIRECTION('',(0.,-1.,0.)); -#995 = ORIENTED_EDGE('',*,*,#206,.F.); -#996 = CYLINDRICAL_SURFACE('',#997,6.054044962965); -#997 = AXIS2_PLACEMENT_3D('',#998,#999,#1000); -#998 = CARTESIAN_POINT('',(-35.41090981799,3.,-8.689779599357)); -#999 = DIRECTION('',(0.,-1.,0.)); -#1000 = DIRECTION('',(-1.,0.,0.)); -#1001 = ADVANCED_FACE('',(#1002),#1021,.F.); -#1002 = FACE_BOUND('',#1003,.F.); -#1003 = EDGE_LOOP('',(#1004,#1012,#1019,#1020)); -#1004 = ORIENTED_EDGE('',*,*,#1005,.F.); -#1005 = EDGE_CURVE('',#1006,#224,#1008,.T.); -#1006 = VERTEX_POINT('',#1007); -#1007 = CARTESIAN_POINT('',(-28.96712497021,3.2,-57.16864680227)); -#1008 = LINE('',#1009,#1010); -#1009 = CARTESIAN_POINT('',(-28.96712497021,3.,-57.16864680227)); -#1010 = VECTOR('',#1011,1.); -#1011 = DIRECTION('',(0.,-1.,0.)); -#1012 = ORIENTED_EDGE('',*,*,#1013,.T.); -#1013 = EDGE_CURVE('',#1006,#957,#1014,.T.); -#1014 = CIRCLE('',#1015,5.2); -#1015 = AXIS2_PLACEMENT_3D('',#1016,#1017,#1018); -#1016 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#1017 = DIRECTION('',(0.,-1.,0.)); -#1018 = DIRECTION('',(-1.,0.,0.)); -#1019 = ORIENTED_EDGE('',*,*,#956,.T.); -#1020 = ORIENTED_EDGE('',*,*,#231,.F.); -#1021 = CYLINDRICAL_SURFACE('',#1022,5.2); -#1022 = AXIS2_PLACEMENT_3D('',#1023,#1024,#1025); -#1023 = CARTESIAN_POINT('',(-25.35093464349,3.,-60.90537900045)); -#1024 = DIRECTION('',(0.,-1.,0.)); -#1025 = DIRECTION('',(-1.,0.,0.)); -#1026 = ADVANCED_FACE('',(#1027),#1045,.F.); -#1027 = FACE_BOUND('',#1028,.F.); -#1028 = EDGE_LOOP('',(#1029,#1030,#1038,#1044)); -#1029 = ORIENTED_EDGE('',*,*,#990,.F.); -#1030 = ORIENTED_EDGE('',*,*,#1031,.F.); -#1031 = EDGE_CURVE('',#1032,#982,#1034,.T.); -#1032 = VERTEX_POINT('',#1033); -#1033 = CARTESIAN_POINT('',(-26.93875323652,3.2,-55.20570756731)); -#1034 = LINE('',#1035,#1036); -#1035 = CARTESIAN_POINT('',(-32.39120436163,3.2,-38.09921113329)); -#1036 = VECTOR('',#1037,1.); -#1037 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#1038 = ORIENTED_EDGE('',*,*,#1039,.T.); -#1039 = EDGE_CURVE('',#1032,#216,#1040,.T.); -#1040 = LINE('',#1041,#1042); -#1041 = CARTESIAN_POINT('',(-26.93875323652,3.,-55.20570756731)); -#1042 = VECTOR('',#1043,1.); -#1043 = DIRECTION('',(0.,-1.,0.)); -#1044 = ORIENTED_EDGE('',*,*,#215,.T.); -#1045 = PLANE('',#1046); -#1046 = AXIS2_PLACEMENT_3D('',#1047,#1048,#1049); -#1047 = CARTESIAN_POINT('',(-34.04006158346,3.,-32.92609366041)); -#1048 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#1049 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#1050 = ADVANCED_FACE('',(#1051),#1062,.F.); -#1051 = FACE_BOUND('',#1052,.F.); -#1052 = EDGE_LOOP('',(#1053,#1054,#1060,#1061)); -#1053 = ORIENTED_EDGE('',*,*,#1039,.F.); -#1054 = ORIENTED_EDGE('',*,*,#1055,.F.); -#1055 = EDGE_CURVE('',#1006,#1032,#1056,.T.); -#1056 = LINE('',#1057,#1058); -#1057 = CARTESIAN_POINT('',(-14.90185526362,3.2,-43.55710346492)); -#1058 = VECTOR('',#1059,1.); -#1059 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#1060 = ORIENTED_EDGE('',*,*,#1005,.T.); -#1061 = ORIENTED_EDGE('',*,*,#223,.T.); -#1062 = PLANE('',#1063); -#1063 = AXIS2_PLACEMENT_3D('',#1064,#1065,#1066); -#1064 = CARTESIAN_POINT('',(-27.90836811563,3.,-56.14404399617)); -#1065 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#1066 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#1067 = ADVANCED_FACE('',(#1068),#1086,.T.); -#1068 = FACE_BOUND('',#1069,.T.); -#1069 = EDGE_LOOP('',(#1070,#1071,#1072,#1073,#1074,#1075,#1076,#1077, - #1078,#1079,#1080,#1081,#1082,#1083,#1084,#1085)); -#1070 = ORIENTED_EDGE('',*,*,#304,.F.); -#1071 = ORIENTED_EDGE('',*,*,#668,.F.); -#1072 = ORIENTED_EDGE('',*,*,#651,.F.); -#1073 = ORIENTED_EDGE('',*,*,#627,.F.); -#1074 = ORIENTED_EDGE('',*,*,#603,.F.); -#1075 = ORIENTED_EDGE('',*,*,#572,.T.); -#1076 = ORIENTED_EDGE('',*,*,#554,.F.); -#1077 = ORIENTED_EDGE('',*,*,#523,.T.); -#1078 = ORIENTED_EDGE('',*,*,#505,.F.); -#1079 = ORIENTED_EDGE('',*,*,#474,.T.); -#1080 = ORIENTED_EDGE('',*,*,#450,.T.); -#1081 = ORIENTED_EDGE('',*,*,#432,.F.); -#1082 = ORIENTED_EDGE('',*,*,#401,.T.); -#1083 = ORIENTED_EDGE('',*,*,#383,.F.); -#1084 = ORIENTED_EDGE('',*,*,#352,.T.); -#1085 = ORIENTED_EDGE('',*,*,#335,.F.); -#1086 = PLANE('',#1087); -#1087 = AXIS2_PLACEMENT_3D('',#1088,#1089,#1090); -#1088 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153, - -70.97315781796)); -#1089 = DIRECTION('',(0.,1.,0.)); -#1090 = DIRECTION('',(0.,0.,1.)); -#1091 = ADVANCED_FACE('',(#1092,#1142,#1153,#1171,#1205),#1216,.F.); -#1092 = FACE_BOUND('',#1093,.F.); -#1093 = EDGE_LOOP('',(#1094,#1104,#1112,#1120,#1128,#1136)); -#1094 = ORIENTED_EDGE('',*,*,#1095,.F.); -#1095 = EDGE_CURVE('',#1096,#1098,#1100,.T.); -#1096 = VERTEX_POINT('',#1097); -#1097 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#1098 = VERTEX_POINT('',#1099); -#1099 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#1100 = LINE('',#1101,#1102); -#1101 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#1102 = VECTOR('',#1103,1.); -#1103 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#1104 = ORIENTED_EDGE('',*,*,#1105,.F.); -#1105 = EDGE_CURVE('',#1106,#1096,#1108,.T.); -#1106 = VERTEX_POINT('',#1107); -#1107 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#1108 = LINE('',#1109,#1110); -#1109 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#1110 = VECTOR('',#1111,1.); -#1111 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#1112 = ORIENTED_EDGE('',*,*,#1113,.F.); -#1113 = EDGE_CURVE('',#1114,#1106,#1116,.T.); -#1114 = VERTEX_POINT('',#1115); -#1115 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#1116 = LINE('',#1117,#1118); -#1117 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#1118 = VECTOR('',#1119,1.); -#1119 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#1120 = ORIENTED_EDGE('',*,*,#1121,.F.); -#1121 = EDGE_CURVE('',#1122,#1114,#1124,.T.); -#1122 = VERTEX_POINT('',#1123); -#1123 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#1124 = LINE('',#1125,#1126); -#1125 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#1126 = VECTOR('',#1127,1.); -#1127 = DIRECTION('',(1.,0.,0.)); -#1128 = ORIENTED_EDGE('',*,*,#1129,.F.); -#1129 = EDGE_CURVE('',#1130,#1122,#1132,.T.); -#1130 = VERTEX_POINT('',#1131); -#1131 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#1132 = LINE('',#1133,#1134); -#1133 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#1134 = VECTOR('',#1135,1.); -#1135 = DIRECTION('',(0.,0.,1.)); -#1136 = ORIENTED_EDGE('',*,*,#1137,.F.); -#1137 = EDGE_CURVE('',#1098,#1130,#1138,.T.); -#1138 = LINE('',#1139,#1140); -#1139 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#1140 = VECTOR('',#1141,1.); -#1141 = DIRECTION('',(-1.,0.,0.)); -#1142 = FACE_BOUND('',#1143,.F.); -#1143 = EDGE_LOOP('',(#1144)); -#1144 = ORIENTED_EDGE('',*,*,#1145,.F.); -#1145 = EDGE_CURVE('',#1146,#1146,#1148,.T.); -#1146 = VERTEX_POINT('',#1147); -#1147 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#1148 = CIRCLE('',#1149,4.735522705283); -#1149 = AXIS2_PLACEMENT_3D('',#1150,#1151,#1152); -#1150 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#1151 = DIRECTION('',(-0.,1.,0.)); -#1152 = DIRECTION('',(1.,0.,0.)); -#1153 = FACE_BOUND('',#1154,.F.); -#1154 = EDGE_LOOP('',(#1155,#1156,#1157,#1158,#1159,#1160,#1161,#1162, - #1163,#1164,#1165,#1166,#1167,#1168,#1169,#1170)); -#1155 = ORIENTED_EDGE('',*,*,#1031,.T.); -#1156 = ORIENTED_EDGE('',*,*,#981,.F.); -#1157 = ORIENTED_EDGE('',*,*,#933,.T.); -#1158 = ORIENTED_EDGE('',*,*,#883,.F.); -#1159 = ORIENTED_EDGE('',*,*,#835,.T.); -#1160 = ORIENTED_EDGE('',*,*,#796,.F.); -#1161 = ORIENTED_EDGE('',*,*,#738,.F.); -#1162 = ORIENTED_EDGE('',*,*,#700,.F.); -#1163 = ORIENTED_EDGE('',*,*,#724,.F.); -#1164 = ORIENTED_EDGE('',*,*,#762,.F.); -#1165 = ORIENTED_EDGE('',*,*,#820,.F.); -#1166 = ORIENTED_EDGE('',*,*,#866,.T.); -#1167 = ORIENTED_EDGE('',*,*,#915,.F.); -#1168 = ORIENTED_EDGE('',*,*,#964,.T.); -#1169 = ORIENTED_EDGE('',*,*,#1013,.F.); -#1170 = ORIENTED_EDGE('',*,*,#1055,.T.); -#1171 = FACE_BOUND('',#1172,.F.); -#1172 = EDGE_LOOP('',(#1173,#1183,#1191,#1199)); -#1173 = ORIENTED_EDGE('',*,*,#1174,.F.); -#1174 = EDGE_CURVE('',#1175,#1177,#1179,.T.); -#1175 = VERTEX_POINT('',#1176); -#1176 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#1177 = VERTEX_POINT('',#1178); -#1178 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#1179 = LINE('',#1180,#1181); -#1180 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#1181 = VECTOR('',#1182,1.); -#1182 = DIRECTION('',(-8.501532861638E-02,0.,-0.996379643459)); -#1183 = ORIENTED_EDGE('',*,*,#1184,.F.); -#1184 = EDGE_CURVE('',#1185,#1175,#1187,.T.); -#1185 = VERTEX_POINT('',#1186); -#1186 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#1187 = LINE('',#1188,#1189); -#1188 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#1189 = VECTOR('',#1190,1.); -#1190 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#1191 = ORIENTED_EDGE('',*,*,#1192,.F.); -#1192 = EDGE_CURVE('',#1193,#1185,#1195,.T.); -#1193 = VERTEX_POINT('',#1194); -#1194 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#1195 = LINE('',#1196,#1197); -#1196 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#1197 = VECTOR('',#1198,1.); -#1198 = DIRECTION('',(-8.501532861638E-02,0.,0.996379643459)); -#1199 = ORIENTED_EDGE('',*,*,#1200,.F.); -#1200 = EDGE_CURVE('',#1177,#1193,#1201,.T.); -#1201 = LINE('',#1202,#1203); -#1202 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#1203 = VECTOR('',#1204,1.); -#1204 = DIRECTION('',(-1.,0.,0.)); -#1205 = FACE_BOUND('',#1206,.F.); -#1206 = EDGE_LOOP('',(#1207)); -#1207 = ORIENTED_EDGE('',*,*,#1208,.F.); -#1208 = EDGE_CURVE('',#1209,#1209,#1211,.T.); -#1209 = VERTEX_POINT('',#1210); -#1210 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#1211 = CIRCLE('',#1212,4.735522705283); -#1212 = AXIS2_PLACEMENT_3D('',#1213,#1214,#1215); -#1213 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#1214 = DIRECTION('',(-0.,1.,0.)); -#1215 = DIRECTION('',(1.,0.,0.)); -#1216 = PLANE('',#1217); -#1217 = AXIS2_PLACEMENT_3D('',#1218,#1219,#1220); -#1218 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#1219 = DIRECTION('',(0.,1.,0.)); -#1220 = DIRECTION('',(1.,0.,0.)); -#1221 = ADVANCED_FACE('',(#1222),#1247,.T.); -#1222 = FACE_BOUND('',#1223,.T.); -#1223 = EDGE_LOOP('',(#1224,#1232,#1240,#1246)); -#1224 = ORIENTED_EDGE('',*,*,#1225,.F.); -#1225 = EDGE_CURVE('',#1226,#1096,#1228,.T.); -#1226 = VERTEX_POINT('',#1227); -#1227 = CARTESIAN_POINT('',(16.626582997737,0.,-8.940188245231)); -#1228 = LINE('',#1229,#1230); -#1229 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#1230 = VECTOR('',#1231,1.); -#1231 = DIRECTION('',(0.,1.,0.)); -#1232 = ORIENTED_EDGE('',*,*,#1233,.T.); -#1233 = EDGE_CURVE('',#1226,#1234,#1236,.T.); -#1234 = VERTEX_POINT('',#1235); -#1235 = CARTESIAN_POINT('',(-5.329070518201E-15,0.,-8.903751135252)); -#1236 = LINE('',#1237,#1238); -#1237 = CARTESIAN_POINT('',(-18.54556462154,1.7763568394E-15, - -8.863107566442)); -#1238 = VECTOR('',#1239,1.); -#1239 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#1240 = ORIENTED_EDGE('',*,*,#1241,.T.); -#1241 = EDGE_CURVE('',#1234,#1098,#1242,.T.); -#1242 = LINE('',#1243,#1244); -#1243 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#1244 = VECTOR('',#1245,1.); -#1245 = DIRECTION('',(0.,1.,0.)); -#1246 = ORIENTED_EDGE('',*,*,#1095,.F.); -#1247 = PLANE('',#1248); -#1248 = AXIS2_PLACEMENT_3D('',#1249,#1250,#1251); -#1249 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#1250 = DIRECTION('',(-2.19152081707E-03,0.,-0.999997598615)); -#1251 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#1252 = ADVANCED_FACE('',(#1253),#1271,.T.); -#1253 = FACE_BOUND('',#1254,.T.); -#1254 = EDGE_LOOP('',(#1255,#1263,#1269,#1270)); -#1255 = ORIENTED_EDGE('',*,*,#1256,.F.); -#1256 = EDGE_CURVE('',#1257,#1106,#1259,.T.); -#1257 = VERTEX_POINT('',#1258); -#1258 = CARTESIAN_POINT('',(19.029295926024,0.,-17.63009960955)); -#1259 = LINE('',#1260,#1261); -#1260 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#1261 = VECTOR('',#1262,1.); -#1262 = DIRECTION('',(0.,1.,0.)); -#1263 = ORIENTED_EDGE('',*,*,#1264,.T.); -#1264 = EDGE_CURVE('',#1257,#1226,#1265,.T.); -#1265 = LINE('',#1266,#1267); -#1266 = CARTESIAN_POINT('',(23.053273013696,0.,-32.18365022821)); -#1267 = VECTOR('',#1268,1.); -#1268 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#1269 = ORIENTED_EDGE('',*,*,#1225,.T.); -#1270 = ORIENTED_EDGE('',*,*,#1105,.F.); -#1271 = PLANE('',#1272); -#1272 = AXIS2_PLACEMENT_3D('',#1273,#1274,#1275); -#1273 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#1274 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#1275 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#1276 = ADVANCED_FACE('',(#1277),#1295,.T.); -#1277 = FACE_BOUND('',#1278,.T.); -#1278 = EDGE_LOOP('',(#1279,#1287,#1288,#1289)); -#1279 = ORIENTED_EDGE('',*,*,#1280,.T.); -#1280 = EDGE_CURVE('',#1281,#1257,#1283,.T.); -#1281 = VERTEX_POINT('',#1282); -#1282 = CARTESIAN_POINT('',(22.059435554995,0.,-3.734519760785)); -#1283 = LINE('',#1284,#1285); -#1284 = CARTESIAN_POINT('',(12.741012548745,1.7763568394E-15, - -46.46683800444)); -#1285 = VECTOR('',#1286,1.); -#1286 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#1287 = ORIENTED_EDGE('',*,*,#1256,.T.); -#1288 = ORIENTED_EDGE('',*,*,#1113,.F.); -#1289 = ORIENTED_EDGE('',*,*,#1290,.F.); -#1290 = EDGE_CURVE('',#1281,#1114,#1291,.T.); -#1291 = LINE('',#1292,#1293); -#1292 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#1293 = VECTOR('',#1294,1.); -#1294 = DIRECTION('',(0.,1.,0.)); -#1295 = PLANE('',#1296); -#1296 = AXIS2_PLACEMENT_3D('',#1297,#1298,#1299); -#1297 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#1298 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#1299 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#1300 = ADVANCED_FACE('',(#1301),#1319,.T.); -#1301 = FACE_BOUND('',#1302,.T.); -#1302 = EDGE_LOOP('',(#1303,#1311,#1312,#1313)); -#1303 = ORIENTED_EDGE('',*,*,#1304,.T.); -#1304 = EDGE_CURVE('',#1305,#1281,#1307,.T.); -#1305 = VERTEX_POINT('',#1306); -#1306 = CARTESIAN_POINT('',(-21.72552223146,0.,-3.734519760785)); -#1307 = LINE('',#1308,#1309); -#1308 = CARTESIAN_POINT('',(-22.63692080725,0.,-3.734519760785)); -#1309 = VECTOR('',#1310,1.); -#1310 = DIRECTION('',(1.,0.,0.)); -#1311 = ORIENTED_EDGE('',*,*,#1290,.T.); -#1312 = ORIENTED_EDGE('',*,*,#1121,.F.); -#1313 = ORIENTED_EDGE('',*,*,#1314,.F.); -#1314 = EDGE_CURVE('',#1305,#1122,#1315,.T.); -#1315 = LINE('',#1316,#1317); -#1316 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#1317 = VECTOR('',#1318,1.); -#1318 = DIRECTION('',(0.,1.,0.)); -#1319 = PLANE('',#1320); -#1320 = AXIS2_PLACEMENT_3D('',#1321,#1322,#1323); -#1321 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#1322 = DIRECTION('',(0.,0.,1.)); -#1323 = DIRECTION('',(0.,-1.,0.)); -#1324 = ADVANCED_FACE('',(#1325),#1343,.T.); -#1325 = FACE_BOUND('',#1326,.T.); -#1326 = EDGE_LOOP('',(#1327,#1335,#1336,#1337)); -#1327 = ORIENTED_EDGE('',*,*,#1328,.T.); -#1328 = EDGE_CURVE('',#1329,#1305,#1331,.T.); -#1329 = VERTEX_POINT('',#1330); -#1330 = CARTESIAN_POINT('',(-21.72552223146,0.,-8.903751135252)); -#1331 = LINE('',#1332,#1333); -#1332 = CARTESIAN_POINT('',(-21.72552223146,0.,-38.64614663299)); -#1333 = VECTOR('',#1334,1.); -#1334 = DIRECTION('',(0.,0.,1.)); -#1335 = ORIENTED_EDGE('',*,*,#1314,.T.); -#1336 = ORIENTED_EDGE('',*,*,#1129,.F.); -#1337 = ORIENTED_EDGE('',*,*,#1338,.F.); -#1338 = EDGE_CURVE('',#1329,#1130,#1339,.T.); -#1339 = LINE('',#1340,#1341); -#1340 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#1341 = VECTOR('',#1342,1.); -#1342 = DIRECTION('',(0.,1.,0.)); -#1343 = PLANE('',#1344); -#1344 = AXIS2_PLACEMENT_3D('',#1345,#1346,#1347); -#1345 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#1346 = DIRECTION('',(-1.,0.,0.)); -#1347 = DIRECTION('',(0.,1.,0.)); -#1348 = ADVANCED_FACE('',(#1349),#1360,.T.); -#1349 = FACE_BOUND('',#1350,.T.); -#1350 = EDGE_LOOP('',(#1351,#1357,#1358,#1359)); -#1351 = ORIENTED_EDGE('',*,*,#1352,.T.); -#1352 = EDGE_CURVE('',#1234,#1329,#1353,.T.); -#1353 = LINE('',#1354,#1355); -#1354 = CARTESIAN_POINT('',(-28.21385794834,0.,-8.903751135252)); -#1355 = VECTOR('',#1356,1.); -#1356 = DIRECTION('',(-1.,0.,0.)); -#1357 = ORIENTED_EDGE('',*,*,#1338,.T.); -#1358 = ORIENTED_EDGE('',*,*,#1137,.F.); -#1359 = ORIENTED_EDGE('',*,*,#1241,.F.); -#1360 = PLANE('',#1361); -#1361 = AXIS2_PLACEMENT_3D('',#1362,#1363,#1364); -#1362 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#1363 = DIRECTION('',(0.,0.,-1.)); -#1364 = DIRECTION('',(0.,1.,0.)); -#1365 = ADVANCED_FACE('',(#1366),#1385,.T.); -#1366 = FACE_BOUND('',#1367,.T.); -#1367 = EDGE_LOOP('',(#1368,#1377,#1383,#1384)); -#1368 = ORIENTED_EDGE('',*,*,#1369,.T.); -#1369 = EDGE_CURVE('',#1370,#1370,#1372,.T.); -#1370 = VERTEX_POINT('',#1371); -#1371 = CARTESIAN_POINT('',(21.163799345768,0.,-48.00951684793)); -#1372 = CIRCLE('',#1373,4.735522705283); -#1373 = AXIS2_PLACEMENT_3D('',#1374,#1375,#1376); -#1374 = CARTESIAN_POINT('',(16.428276640485,0.,-48.00951684793)); -#1375 = DIRECTION('',(-0.,1.,0.)); -#1376 = DIRECTION('',(1.,0.,0.)); -#1377 = ORIENTED_EDGE('',*,*,#1378,.T.); -#1378 = EDGE_CURVE('',#1370,#1146,#1379,.T.); -#1379 = LINE('',#1380,#1381); -#1380 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#1381 = VECTOR('',#1382,1.); -#1382 = DIRECTION('',(0.,1.,0.)); -#1383 = ORIENTED_EDGE('',*,*,#1145,.F.); -#1384 = ORIENTED_EDGE('',*,*,#1378,.F.); -#1385 = CYLINDRICAL_SURFACE('',#1386,4.735522705283); -#1386 = AXIS2_PLACEMENT_3D('',#1387,#1388,#1389); -#1387 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#1388 = DIRECTION('',(0.,1.,0.)); -#1389 = DIRECTION('',(1.,0.,0.)); -#1390 = ADVANCED_FACE('',(#1391),#1416,.F.); -#1391 = FACE_BOUND('',#1392,.F.); -#1392 = EDGE_LOOP('',(#1393,#1403,#1409,#1410)); -#1393 = ORIENTED_EDGE('',*,*,#1394,.T.); -#1394 = EDGE_CURVE('',#1395,#1397,#1399,.T.); -#1395 = VERTEX_POINT('',#1396); -#1396 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#1397 = VERTEX_POINT('',#1398); -#1398 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#1399 = LINE('',#1400,#1401); -#1400 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#1401 = VECTOR('',#1402,1.); -#1402 = DIRECTION('',(5.275122655165E-17,0.227455280238,0.97378852709)); -#1403 = ORIENTED_EDGE('',*,*,#1404,.F.); -#1404 = EDGE_CURVE('',#1175,#1397,#1405,.T.); -#1405 = LINE('',#1406,#1407); -#1406 = CARTESIAN_POINT('',(5.649679875255,3.602918464526, - -13.21082950266)); -#1407 = VECTOR('',#1408,1.); -#1408 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#1409 = ORIENTED_EDGE('',*,*,#1174,.T.); -#1410 = ORIENTED_EDGE('',*,*,#1411,.T.); -#1411 = EDGE_CURVE('',#1177,#1395,#1412,.T.); -#1412 = LINE('',#1413,#1414); -#1413 = CARTESIAN_POINT('',(1.103762571829,7.940067898719, - -47.92064259636)); -#1414 = VECTOR('',#1415,1.); -#1415 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#1416 = PLANE('',#1417); -#1417 = AXIS2_PLACEMENT_3D('',#1418,#1419,#1420); -#1418 = CARTESIAN_POINT('',(5.823691883056,3.068404028665, - -13.45978839622)); -#1419 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1420 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487825E-02) - ); -#1421 = ADVANCED_FACE('',(#1422),#1432,.F.); -#1422 = FACE_BOUND('',#1423,.F.); -#1423 = EDGE_LOOP('',(#1424,#1425,#1431)); -#1424 = ORIENTED_EDGE('',*,*,#1404,.T.); -#1425 = ORIENTED_EDGE('',*,*,#1426,.T.); -#1426 = EDGE_CURVE('',#1397,#1185,#1427,.T.); -#1427 = LINE('',#1428,#1429); -#1428 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#1429 = VECTOR('',#1430,1.); -#1430 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#1431 = ORIENTED_EDGE('',*,*,#1184,.T.); -#1432 = PLANE('',#1433); -#1433 = AXIS2_PLACEMENT_3D('',#1434,#1435,#1436); -#1434 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -13.01628215822)); -#1435 = DIRECTION('',(2.88163763217E-16,0.342020143326,0.939692620786)); -#1436 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326 - )); -#1437 = ADVANCED_FACE('',(#1438),#1449,.F.); -#1438 = FACE_BOUND('',#1439,.F.); -#1439 = EDGE_LOOP('',(#1440,#1441,#1442,#1443)); -#1440 = ORIENTED_EDGE('',*,*,#1192,.T.); -#1441 = ORIENTED_EDGE('',*,*,#1426,.F.); -#1442 = ORIENTED_EDGE('',*,*,#1394,.F.); -#1443 = ORIENTED_EDGE('',*,*,#1444,.F.); -#1444 = EDGE_CURVE('',#1193,#1395,#1445,.T.); -#1445 = LINE('',#1446,#1447); -#1446 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#1447 = VECTOR('',#1448,1.); -#1448 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#1449 = PLANE('',#1450); -#1450 = AXIS2_PLACEMENT_3D('',#1451,#1452,#1453); -#1451 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#1452 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1453 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487825E-02) - ); -#1454 = ADVANCED_FACE('',(#1455),#1460,.F.); -#1455 = FACE_BOUND('',#1456,.F.); -#1456 = EDGE_LOOP('',(#1457,#1458,#1459)); -#1457 = ORIENTED_EDGE('',*,*,#1444,.T.); -#1458 = ORIENTED_EDGE('',*,*,#1411,.F.); -#1459 = ORIENTED_EDGE('',*,*,#1200,.T.); -#1460 = PLANE('',#1461); -#1461 = AXIS2_PLACEMENT_3D('',#1462,#1463,#1464); -#1462 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -49.69378323641)); -#1463 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#1464 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#1465 = ADVANCED_FACE('',(#1466),#1485,.T.); -#1466 = FACE_BOUND('',#1467,.T.); -#1467 = EDGE_LOOP('',(#1468,#1477,#1483,#1484)); -#1468 = ORIENTED_EDGE('',*,*,#1469,.T.); -#1469 = EDGE_CURVE('',#1470,#1470,#1472,.T.); -#1470 = VERTEX_POINT('',#1471); -#1471 = CARTESIAN_POINT('',(-11.6927539352,0.,-48.00951684793)); -#1472 = CIRCLE('',#1473,4.735522705283); -#1473 = AXIS2_PLACEMENT_3D('',#1474,#1475,#1476); -#1474 = CARTESIAN_POINT('',(-16.42827664048,0.,-48.00951684793)); -#1475 = DIRECTION('',(-0.,1.,0.)); -#1476 = DIRECTION('',(1.,0.,0.)); -#1477 = ORIENTED_EDGE('',*,*,#1478,.T.); -#1478 = EDGE_CURVE('',#1470,#1209,#1479,.T.); -#1479 = LINE('',#1480,#1481); -#1480 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#1481 = VECTOR('',#1482,1.); -#1482 = DIRECTION('',(0.,1.,0.)); -#1483 = ORIENTED_EDGE('',*,*,#1208,.F.); -#1484 = ORIENTED_EDGE('',*,*,#1478,.F.); -#1485 = CYLINDRICAL_SURFACE('',#1486,4.735522705283); -#1486 = AXIS2_PLACEMENT_3D('',#1487,#1488,#1489); -#1487 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#1488 = DIRECTION('',(0.,1.,0.)); -#1489 = DIRECTION('',(1.,0.,0.)); -#1490 = ADVANCED_FACE('',(#1491),#1499,.F.); -#1491 = FACE_BOUND('',#1492,.F.); -#1492 = EDGE_LOOP('',(#1493,#1494,#1495,#1496,#1497,#1498)); -#1493 = ORIENTED_EDGE('',*,*,#1264,.T.); -#1494 = ORIENTED_EDGE('',*,*,#1233,.T.); -#1495 = ORIENTED_EDGE('',*,*,#1352,.T.); -#1496 = ORIENTED_EDGE('',*,*,#1328,.T.); -#1497 = ORIENTED_EDGE('',*,*,#1304,.T.); -#1498 = ORIENTED_EDGE('',*,*,#1280,.T.); -#1499 = PLANE('',#1500); -#1500 = AXIS2_PLACEMENT_3D('',#1501,#1502,#1503); -#1501 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1502 = DIRECTION('',(0.,1.,0.)); -#1503 = DIRECTION('',(0.,0.,1.)); -#1504 = ADVANCED_FACE('',(#1505),#1508,.F.); -#1505 = FACE_BOUND('',#1506,.F.); -#1506 = EDGE_LOOP('',(#1507)); -#1507 = ORIENTED_EDGE('',*,*,#1369,.T.); -#1508 = PLANE('',#1509); -#1509 = AXIS2_PLACEMENT_3D('',#1510,#1511,#1512); -#1510 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1511 = DIRECTION('',(0.,1.,0.)); -#1512 = DIRECTION('',(0.,0.,1.)); -#1513 = ADVANCED_FACE('',(#1514),#1517,.F.); -#1514 = FACE_BOUND('',#1515,.F.); -#1515 = EDGE_LOOP('',(#1516)); -#1516 = ORIENTED_EDGE('',*,*,#1469,.T.); -#1517 = PLANE('',#1518); -#1518 = AXIS2_PLACEMENT_3D('',#1519,#1520,#1521); -#1519 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1520 = DIRECTION('',(0.,1.,0.)); -#1521 = DIRECTION('',(0.,0.,1.)); -#1522 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1526)) -GLOBAL_UNIT_ASSIGNED_CONTEXT((#1523,#1524,#1525)) REPRESENTATION_CONTEXT -('Context #1','3D Context with UNIT and UNCERTAINTY') ); -#1523 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#1524 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#1525 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#1526 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(2.E-06),#1523, - 'distance_accuracy_value','confusion accuracy'); -#1527 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.stl b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.stl deleted file mode 100644 index 5c1f741349..0000000000 Binary files a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.stl and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/DESIGN_MATE_CONNECTORS.md b/docs/CAD/design/mate-connectors/DESIGN_MATE_CONNECTORS.md deleted file mode 100644 index fe1a7a5fee..0000000000 --- a/docs/CAD/design/mate-connectors/DESIGN_MATE_CONNECTORS.md +++ /dev/null @@ -1,922 +0,0 @@ -# Mate connectors: aligning with the mainstream CAD systems - -Research date: 2026-08-05. Written against `orca_cad` / `Snapmaker` at the M8 state -(`CadDocument.{hpp,cpp}`, `apply_mate`, `datum_frame`, the `Mate` card in `DesignPanel.cpp`). - -**Brief:** align with the mate-connector concept as the main CAD programs actually implement it, -and be simple, unequivocal, unconfusing. Alignment is the organising principle of this document: -every recommendation is labelled either **[INDUSTRY]** — do what they all do — or **[DEVIATION]** — -we would be departing, here is why and what it costs. - ---- - -## 0. The answer in ten lines - -1. Seven systems surveyed. **Five of the seven use the same model**; two are the old world. -2. The model: a joint is defined between **two local coordinate frames**, one rigidly attached to - each part, plus **one type** naming which DOF stay free. -3. The frame is called a mate connector (Onshape), a **joint origin** (Fusion, Inventor), a joint - connector (FreeCAD 1.0). Same object, three names. -4. **Every one of them expresses every DOF about the frame's Z axis.** One axis, one convention. -5. **Five types appear in every frame-based system with identical names and identical DOF**: - Fastened/Rigid, Revolute, Slider, Cylindrical, Planar. Ball is in four of five. -6. That is not fashion — those are the classical **lower kinematic pairs**. The vocabulary converged - because the mechanics converged. -7. Our kernel is already on the right side of the line: frame-based, five types, Z-relative, - superimpose-then-relax. **The architecture needs no revisiting.** -8. Where we are out of step: connectors that are not attached to a body; an origin that can only be - a face centroid; no live preview of the two Z arrows; a mate card of abstract dropdowns. -9. Where we would knowingly deviate: refusing a second mate per body (no vendor does this — it is - forced on us by having no solver) and possibly inverting the default mate direction. -10. Biggest single win for the stated goal, and it costs no kernel work: **draw both frames and - ghost the result before Confirm.** The convention stops needing to be remembered. - ---- - -## 1. The two families - -**Constraint-based ("old CAD").** The user states pairwise *geometric relations* between raw -topology — this face coincident with that face, this axis concentric with that axis, this plane -parallel at 12 mm. Each relation removes some DOF; a numerical solver satisfies all of them at once. -Fully positioning one part typically takes **three or more mates**, and the set can be -over-constrained, under-constrained, or satisfiable in several configurations. - -**Frame-based ("mate connectors").** The user places a *local coordinate system* on each part and -states **one** relation between the two frames. The relation is not "these surfaces touch" but -"these frames coincide, except for the following DOF, which stay free." - -Onshape's help page opens by drawing exactly this line: - -> *"Mates in Onshape are different than mates in old CAD systems. Many assemblies require only one -> Onshape Mate between any two instances, as the movement (degrees of freedom) between those two -> instances is embedded in the Mate."* - -The frame-based model won for three reasons, all of which matter here: - -- **One mate per pair.** No mental arithmetic about which three constraints add up to a hinge. -- **The DOF are declared, not deduced.** A revolute mate *is* one rotation. You do not discover the - remaining freedom by dragging. -- **It needs no simultaneous solver for the common case.** Frame-to-frame alignment is a matrix - composition — precisely what `apply_mate` already does. - -> **Caveat — several vendors ship both, and "align with X" is therefore ambiguous.** **Inventor** -> kept its legacy constraints *and* added frame-based Joints in 2012; many Inventor users still build -> assemblies entirely with the old constraint stack. **Creo** has placement constraints *and* -> Mechanism connections. **FreeCAD** had constraint-based Assembly2/3 add-ons before the frame-based -> Assembly workbench shipped in 1.0. So copying "what Inventor does" means copying **one of two -> coexisting workflows**. **Onshape and Fusion 360 are the only pure frame-based examples**, and they -> are the ones to weight most heavily when the evidence conflicts. - ---- - -## 2. Field survey — seven systems - -| | Onshape | Fusion 360 | Inventor | FreeCAD 1.0 | Creo | Siemens NX | SOLIDWORKS | -|---|---|---|---|---|---|---|---| -| **Family** | Frame | Frame | Frame (+ legacy constraints) | Frame (+ legacy add-ons) | Both | Constraint | Constraint | -| **Frame object** | Mate connector | Joint origin | Joint origin | Joint connector (`Placement1/2`) | CSYS on `Weld`/`6DOF` | — | — (nearest: **mate reference**) | -| **Where it lives** | Part Studio **and** Assembly; in the feature list | Component, inside the joint | Component / inside the joint | Inside the Joint object | Part | — | Part (up to 3 named entities) | -| **Origin placement** | Inferred family on hover; `Shift` locks | Discrete **snap points**; `Ctrl` cycles | Snap points + explicit origins | Inferred, previewed on hover | Picked CSYS | Picked entities | Picked entities | -| **Orientation control** | Primary axis (Z) + secondary axis; flip + 90° reorient | Flip, angle, offsets | Flip, angle, offsets | `Placement1/2` + `Offset1/2` | CSYS + offset | — | — | -| **Type inference** | No — explicit | No — explicit | **Yes — "Automatic"** from picked geometry | No | No | No | Partial (mate reference type) | -| **Solver** | Yes, simultaneous — *"order won't affect a Mate"* | Yes | Yes | Yes (Ondsel) | Yes | Yes | Yes | -| **Reuse across instances** | **Yes** — a Part Studio connector exists on every instance | Weak | Partial | Per-joint | Interfaces | Product Interface | Mate references auto-mate on insert | - -Three observations that shape everything below. - -- **Every frame-based system reduced the type list by an order of magnitude** relative to SOLIDWORKS - (7–13 vs ~25) and lost nothing. That is not simplification-by-omission; it is what happens when the - DOF live in the mate instead of being assembled from constraints. -- **Every one of them defines its types relative to a single axis.** Slider translates along Z, - Revolute rotates about Z, Cylindrical does both, Planar translates in X/Y and rotates about Z. - One axis carries the whole vocabulary. -- **Onshape alone treats the connector as a first-class, reusable, named object** — and that is also - where its worst usability complaints come from (§4). - ---- - -## 3. The type vocabulary — cross-system table - -DOF = degrees of freedom left **free**, stated about/along the connector Z. - -| DOF | Onshape | Fusion 360 | Inventor | FreeCAD 1.0 | Creo | **Ours today** | -|---|---|---|---|---|---|---| -| 0 | Fastened | Rigid | Rigid | Fixed | Rigid / Weld | **Fastened** ✅ | -| 1 — rot Z | Revolute | Revolute | Rotational | Revolute | Pin | **Revolute** ✅ | -| 1 — trans Z | Slider | Slider | Slider | Slider | Slider | **Slider** ✅ | -| 2 — rot + trans Z | Cylindrical | Cylindrical | Cylindrical | Cylindrical | Cylinder | **Cylindrical** ✅ | -| 3 — trans XY + rot Z | Planar | Planar | Planar | *(Parallel+Distance)* | Planar | **Planar** ✅ | -| 3 — rot XYZ | Ball | Ball | Ball | Ball | Ball | — | -| 2 — different axes | Pin slot | Pin-Slot | — | — | Slot / Bearing | — | -| 1 — coupled | Screw | — | — | Screw | — | — | -| 4 | Parallel | — | — | Parallel | — | — | -| other | Tangent, Width, Group | As-built | Automatic | Perpendicular, Angle, Distance, Gears, Belt, RackPinion | General, 6DOF | — | - -**Five types appear in every frame-based system, with the same name and the same DOF.** Those five -are the industry's common denominator, and they are exactly `mate_kind` 0–4 as already implemented. -Ball is in four of five. Everything past that is a long tail no two vendors agree on. - -### Why the convergence is a fact, not a fashion - -A rigid-body placement is an element of SE(3). A mate leaves some set of relative motions free. For -the mate to behave the same throughout its range — for a hinge to be a hinge at every angle — that -free set must be **closed under composition**: two allowed motions must compose to an allowed motion. -A closed set of motions is a **subgroup** of SE(3). - -The subgroups corresponding to physical surface-on-surface contact are the classical **six lower -pairs** (Reuleaux): - -| Pair | Free motion relative to Z | DOF | -|---|---|---| -| Revolute (R) | rotation about Z | 1 | -| Prismatic / slider (P) | translation along Z | 1 | -| Helical / screw (H) | coupled rotation + translation | 1 | -| Cylindrical (C) | rotation about **and** translation along Z | 2 | -| Planar (E/G) | translation in X,Y + rotation about Z | 3 | -| Spherical / ball (S) | rotation about X, Y, Z | 3 | - -Plus the two trivial ends: identity (0 DOF — **fastened**) and all of SE(3) (6 DOF — floating, i.e. -no mate). Hervé's Lie-subgroup analysis of the displacement group is the standard reference for -treating these as the algebraic building blocks of mechanism synthesis. - -**Consequence.** Anything outside this table is either (a) a *composition* needing a solver, or -(b) not a joint at all but a *measurement*: - -- Onshape's **Parallel** (4 DOF), **Tangent**, **Width**, **Pin slot**, and FreeCAD's **Distance / - Angle / Perpendicular** are constraints, not pairs — their free set is not a subgroup, so they only - make sense alongside a simultaneous solver. -- **Gear, Belt, Rack-and-pinion** are *relations between two mates*, a different object entirely. -- **Screw (H)** is a legitimate lower pair but needs a pitch parameter and is rare in printed parts. - -So the vendors' shared five, the lower pairs, and our `mate_kind` 0–4 are the same list arrived at -three ways. **[INDUSTRY] Stop looking for missing types and spend the budget on the connector.** - ---- - -## 4. What they all agree on — adopt verbatim - -Deviating from any of these makes an experienced user's intuition *wrong*, which is the operational -definition of "confusing". - -**A1 [INDUSTRY] — The connector is a full right-handed frame.** -Origin + Z (primary) + X (secondary). Onshape and Fusion expose exactly these two axis controls and -nothing else. A point cannot express spin; an axis cannot express clocking. -*Status: we comply* — `DatumCoordSys` carries origin/x/y and derives Z. - -**A2 [INDUSTRY] — Z is the joint axis; every DOF is about or along Z.** -Revolute rotates about Z. Slider translates along Z. Planar's free plane is normal to Z. Offsets run -along Z. This single rule is what makes the system learnable: **one axis to look at, and its meaning -never changes.** -*Status: we comply* — `mate_offset` along A's z, `mate_angle` about A's z. - -**A3 [INDUSTRY] — Mating superimposes the two frames; the type then relaxes specific DOF.** -FreeCAD states it most plainly: *"the second connector is superimposed on the first connector by -default and may change its position according to the joint type."* Fastened is not a special case — -it is the base case with nothing relaxed. -*Status: we comply* — `T = M_A · Rz · Tz · F · M_B⁻¹`, looser kinds relaxing from there. - -**A4 [INDUSTRY] — The connector belongs to a part and moves with it.** -Onshape: a connector defined in a Part Studio *"is available for reuse on every instance of that part -in every assembly in which it is instanced."* It is part geometry, not assembly geometry. -*Status: **violated**.* `CoordSysType::PointWorld` is a bare world XYZ with `X = world X` and no -`coordsys_body`. Such a connector does not follow its part. See §6 G1. - -**A5 [INDUSTRY] — Selection order is meaningful and must be visible.** -One connector is the reference; the other is driven onto it. Onshape spells out that offsets are -measured *"from the second Mate connector selected to the first"*, and that reversing the order -flips the sign. -*Status: complied with in the data model* (`mate_cs_a` fixed, `mate_cs_b` moves) *but not in the UI* — -two dropdowns labelled A and B do not tell the user which part is about to jump. - -**A6 [INDUSTRY] — Flip and re-clock live in the mate dialog, always.** -Onshape: *"Click the arrow icon to flip the direction of the primary axis. Click the Reorient -secondary axis icon to rotate the secondary axis in 90-degree increments."* -*Status: partial.* We have `mate_flip` (Z reversal). We have `mate_angle` as a free number — strictly -more powerful than 90° steps, and much worse to *use*: the common case is "it came in a quarter turn -out", and typing 90 is a worse gesture than pressing a button. - -**A7 [INDUSTRY] — DOF are shown, not inferred by the user.** -Onshape animates each mate's remaining DOF on demand; Fusion and Inventor name the DOF in the type -list. Our dropdown text already does this in words ("free spin + axial slide"). Keep it. - -**A8 [INDUSTRY] — Free DOF are preserved from the current placement, not zeroed.** -Onshape: a Planar mate aligns the frames *"but they are not restricted to this location with respect -to their degrees of freedom."* -*Status: we comply* — and it must be *said*, because a Planar mate that leaves the part where it was -looks like a mate that did nothing. - ---- - -## 5. Where they diverge — who to copy, and why - -### D1 — Where the connector's origin comes from - -| | Behaviour | -|---|---| -| **Fusion 360** | Discrete **snap points** only: vertex, edge midpoint, face centre, arc centre. `Ctrl` cycles the candidates under the cursor. A circle icon denotes a vertex, a triangle a midpoint. "Between two faces" is a separate explicit option. | -| **Onshape** | Infers a *family* on hover — centroid, every vertex, every edge midpoint, every arc centre, the centroids of interior regions (holes, slots), and the virtual sharps of conical faces. `Shift` locks the current candidate. | -| **Inventor** | Snap points, plus explicit joint origins for awkward cases. | -| **FreeCAD 1.0** | Hovering previews where the connector will land before you commit. | -| **Ours** | Always the **face centroid**. No alternative exists. | - -Onshape's richness has a cost its own documentation admits: *"The suggested locations are based on -the underlying geometry of the part and changing the geometry will change the location of the Mate. -This can be undesirable in certain situations."* On the forum this shows up as connectors that move -or break on edit — the classic topological-naming failure. Fusion's discrete set is poorer and far -more predictable. - -> **[INDUSTRY] Copy Fusion's candidate *set*.** A small, closed, enumerable set — **face centroid, -> vertex, edge midpoint, arc/circle centre** — each drawn before commit, with the card naming which is -> in use ("Origin: edge midpoint"). This is our largest expressiveness gap: a face centroid alone -> cannot place a hinge pin on a corner boss. It is also the one place where copying the *simpler* -> vendor is clearly right. -> -> **Open sub-choice — how the candidate is chosen.** Three options, in increasing order of magic: -> (1) **explicit dropdown** in the card after picking the face — no hover behaviour at all; -> (2) **Fusion's `Ctrl` cycling** through candidates under the cursor; (3) **Onshape's hover -> inference**. Kimi's independent review argued for (1) on the grounds that hover is exactly where -> both vendors' instability complaints originate, and that a dropdown gets ~90% of the expressiveness -> with none of the hover-guess debugging. That is a fair reading and (1) is the cheapest to build and -> the easiest to make unequivocal. **Recommendation: build (1) first; if hover is added later, let it -> *pre-fill the dropdown* rather than silently create an implicit connector** — which also keeps R2 -> (one kind of connector) intact. - -### D2 — Explicit type, or inferred from the geometry? - -Inventor is the only surveyed system that infers: *"Rotational is selected if the two selected -origins are circular. Cylindrical if the two selected origins are points on a cylinder. Ball if -points on a sphere. Rigid for all other origin selections."* Onshape and Fusion require an explicit -choice. - -> **[INDUSTRY, Inventor] Do both, in Inventor's order.** Infer a *default* type from what was picked, -> then show it in an editable control. Inference is what makes the tool feel like it understands the -> geometry; the visible, editable result is what keeps it unequivocal. Pure inference with no visible -> type is the confusing option; a pure dropdown with no default is the tedious one. This also fits -> the Design tab's geometry-first charter exactly: point at a bore, get Revolute offered. - -### D3 — How the Z-direction ambiguity is resolved - -This is the specific failure the brief is aimed at. A former IT trainer stated it precisely on the -Onshape forum: - -> *"There is always the risk that users will build their own conceptual models of how software works -> which may not match the designer's concept. The result is usually a poor user experience and many -> mistakes… for a good (say) Fixed mate to occur do the Z axes of the two mates have to be pointing -> in the same direction… Alternatively, should they be facing each other?"* - -He is asking the right question and **no vendor's documentation answers it.** Onshape's own advice — -*"if the behavior is not what you expected, try flipping the primary and/or secondary axis"* — is -trial and error. This is a gap in the industry, not a convention to copy. - -> **[INDUSTRY, method] Resolve it with live preview, not documentation.** FreeCAD previews the -> connector on hover; Onshape and Fusion both draw the frames. Draw **both** Z arrows the moment the -> second connector is picked, and ghost the resulting placement *before* Confirm. The convention then -> never has to be remembered because it is on screen. -> -> **[DEVIATION, optional] Name the two cases in the user's words** rather than in axis-speak: -> "the two faces come together" vs "the axes run the same way". No surveyed vendor does this — they -> all ship a flip arrow. It is a small, low-risk improvement on the state of the art, and it is -> separable from the default-direction question in §8 D1. - -### D4 — Named, reusable connectors on the part - -Onshape: connectors created in the Part Studio are reused on every instance in every assembly. -SOLIDWORKS' **mate reference** reaches the same end by another route: up to three named entities -(primary/secondary/tertiary) baked into the part so it auto-mates on drag-and-drop — and a *named* -mate reference seeks out a matching name on insertion. That naming trick is how a library of -fasteners assembles itself. - -> **[INDUSTRY] Out of scope now, but do not preclude it.** Give connectors a stable, user-visible -> name at creation. One string today; expensive to add once documents exist in the wild. - ---- - -## 6. Confusion catalogue - -Documented ways real implementations confuse people. Each is a requirement in disguise. - -**C1 — Which way does Z point?** See D3. If a user has to ask once, they will mis-predict a hundred -times. - -**C2 — The roll is unspecified.** Aligning Z leaves one rotation about Z undetermined. Something must -pin it, and if that something is world-derived, the frame does not rotate with its part. **This -codebase shipped exactly this bug** (`en4`): a face-only connector took Z from the face -normal but X from `coordsys_x_hint`, a world constant, so Fastened and Slider claimed to lock an -orientation the frame could not see. Fixed 2026-07-26 by deriving X from the face's own first usable -edge — but note the fix's own caveat: *"replaying an older document whose face-only connector fed a -mate can now place that body differently."* Roll conventions are load-bearing, and changing one is a -document-format change. - -**C3 — The origin drifts.** See D1. - -**C4 — Implicit and explicit connectors are not the same thing.** On the Onshape forum, implicit -connectors are reported to change their query structure when a feature is edited and re-accepted, and -are unusable in places explicit ones work. Two things called by one name that behave differently is a -permanent tax. - -**C5 — Which part moves?** A frame alignment is asymmetric. If the UI does not say which frame is -driven, the user finds out by watching the wrong part jump. - -**C6 — Which direction is a positive offset?** Onshape measures *"from the second Mate connector -selected to the first"* — the sign depends on pick order, and swapping the picks flips it. Documented -behaviour, documented surprise. - -**C7 — One intent, several mates.** The SOLIDWORKS failure: expressing "this shaft is in this hole, -resting on this shoulder" as three constraints, then discovering the solver picked the mirror -configuration. Frame-based systems fix this by construction; the requirement is not to reintroduce it. - -**C8 — Degenerate frames.** A circular face has no usable in-plane edge direction; a cylinder seam -projects to nothing; a picked edge parallel to Z gives a zero cross product. `datum_frame` handles all -three with fallbacks — the requirement is that a fallback be *visible*, because a silent fallback is -C2 wearing a different hat. - -**C9 — Order dependence without a solver.** Onshape can say *"Onshape solves Mates simultaneously so -order won't affect a Mate."* A system that composes transforms in tree order cannot say that. Two -mates driving one body means the second wins and the first is a lie on screen. - -**C10 — Mirrors and patterns.** A mirrored instance has a left-handed frame. Blindly mirroring a -connector gives a frame whose Z still points "out" but whose handedness flipped, so every rotation -runs backwards. Cheap to handle now, miserable to retrofit. - ---- - -## 7. Requirements - -Labelled **[INDUSTRY]** (what the frame-based systems do) or **[DEVIATION]** (we would depart). - -### Definition - -**R1 [INDUSTRY] — A mate connector is a frame attached to exactly one body.** No body, no connector. -*Test:* creating a connector without a body is rejected at creation, not at mate time. -→ **`CoordSysType::PointWorld` violates this.** It is a datum wearing a connector's name. - -**R2 [INDUSTRY] — One kind of connector, not two.** No "implicit" connector that behaves differently -from an explicit one. If hover inference is offered, hovering *creates* an ordinary connector. -*Why:* C4. *Test:* everything that accepts a connector accepts any connector. - -**R3 [INDUSTRY] — A mate names exactly one subgroup of free motion.** Fastened (0), Revolute (1), -Slider (1), Cylindrical (2), Planar (3), optionally Ball (3). *Why:* §3. *Test:* every type's free -set is closed; no type is "A and also B". - -### Orientation - -**R4 [INDUSTRY] — Everything is about Z. Say so once, in the UI.** *Test:* no mate parameter refers -to any other axis. - -**R5 [DEVIATION] — Z is the outward material direction, and mates default to FACING.** -A mate would drive B's Z onto **−A's Z** by default, so picking two faces that should touch makes -them touch with no options changed. *Why:* it is the whole of C1. -**Cost and caveat:** this inverts today's default (`mate_flip=false` currently *aligns*), and I could -not establish from any vendor's documentation what their default actually is — the forum question in -D3 went unanswered precisely because it is undocumented. So this is marked a deviation on the honest -grounds that **I cannot prove the industry agrees with it.** If D3's live preview lands first, the -default matters much less, because the user sees the outcome before committing. See §9 D1. - -**R6 [DEVIATION] — Name the two directions; do not ship a boolean called "flip".** -`Direction: Facing | Aligned`. Every surveyed vendor ships a flip arrow instead. A boolean requires -remembering what unticked means; two named values do not. Low risk, small improvement on the state of -the art. - -**R7 [INDUSTRY] — Roll is picked, or a stored quarter turn. Never world-derived.** -X from a referenced edge or in-plane direction; failing that, a deterministic body-attached seed, with -**Rotate 90°** offered as a stored integer 0–3 on top (this is Onshape's "reorient secondary axis", -A6). *Why:* C2 and the world-constant bug this project already shipped. *Test:* rotate the parent -body by any angle; the connector's X rotates with it — *this test already exists* ("a face-only frame -rotates with its body"). - -**R8 [INDUSTRY] — A degenerate roll is reported, not absorbed.** *Test:* a connector on a full -cylindrical face reports "roll undefined — pick a direction" rather than silently taking a fallback. - -### Placement - -**R9 [INDUSTRY, Fusion] — Origin comes from a small closed set of named candidates.** -**Face centroid, arc/circle centre, edge midpoint, vertex.** Four. Each stored as -`(kind, topological reference)` and resolved at rebuild. *Why:* D1. *Test:* the stored kind is visible -in the card; a rebuild either resolves it or raises an error. - -**R10 [INDUSTRY] — An unresolvable reference is an error, never a silent relocation.** -*Test:* delete the referenced face; the mate reports "connector A: face not found" and the body stays -where it was. - -### Semantics without a solver - -**R11 [DEVIATION] — A body is driven by at most one mate. The second is refused.** -**No surveyed system does this** — they all have solvers and all accept many mates per body. It is -forced on us by tree-order composition: a second mate on the same body silently overrides the first -and the screen shows a configuration satisfying only one stated intent (C9). *Test:* creating a -second mate whose moving body already has one is rejected, naming the existing mate. -This is the single largest departure in this document. See §9 D4. - -> **A tempting misreading, checked and rejected.** It is easy to find the claim that Onshape mandates -> *"exactly one Mate between any two instances"*, which would make R11 an industry agreement rather -> than a deviation. **The Onshape page does not say that.** It says *"**Many assemblies require only** -> one Onshape Mate between any two instances"* and then lists, as an explicit remedy, *"**Use more -> than one Mate if necessary.**"* One mate per pair is Onshape's *typical case*, not its rule. R11 -> remains a deviation and must be justified on our own architecture, not on theirs. - -**R11a [DEVIATION] — The refusal list.** With no solver, these are unsupportable and must be refused -rather than half-done: a second mate on an already-driven body; cycles (A→B, B→A); closed loops -(A→B, A→C, B→C); relations *between* mates (gear, belt, rack-and-pinion, screw coupling); **joint -limits**, which nothing can enforce without a solver; and **dragging a body to exercise a free DOF**, -which requires keeping the body on the allowed manifold. Motion analysis and animation follow from the -same lack. *Requirement:* none of these may appear in the UI as something that half-works. - -**R12 [DEVIATION] — The mate graph is an acyclic forest rooted at fixed bodies.** A body reached by -no mate is fixed; cycles are refused. Same root cause as R11. *Test:* A→B, B→A rejected at creation. - -**R13 [INDUSTRY] — Free DOF are preserved from the current placement, and the user is told.** -Behaviour already matches Onshape (A8); the telling does not. *Test:* the card for any type with -DOF > 0 says which motions remain and that dragging exercises them. - -**R14 [INDUSTRY] — State what mirroring does to a connector.** -*Checked in the code:* `datum_frame` ends with a Gram-Schmidt forcing a right-handed frame -(`ds.x = Y.cross(Z)`), so a connector resolved on a mirrored body comes out **right-handed, not -mirror-imaged**. Z follows the mirrored face's outward normal, X follows a mirrored edge, handedness -is re-imposed. Defensible — a mate on the mirrored part still turns the way its type says — but it -means a mirrored sub-assembly is *not* the mirror image of the original in its rotation sense. -*Requirement:* document it and pin it with a test. *Why:* C10. - -### Feedback — the part that actually removes confusion - -**R15 [INDUSTRY] — Before Confirm, the card answers four questions in words.** Which body moves; -which way Z points on each connector; how many DOF remain; what the offset is measured from. - -**R16 [INDUSTRY] — Draw both frames live, with Z distinguishable, and ghost the result.** -Two triads with Z rendered differently from X/Y (length, arrowhead, colour). *Why:* D3 — the fastest -way to make a convention unequivocal is to show it. *Test:* both Z directions are readable in a -screenshot. - -**R17 [INDUSTRY] — Show the DOF budget per body.** "Body 2: 1 of 6 DOF free (rotation about Z)." -The most educational readout in any assembly system, and free to compute here — the type *is* the DOF -count. *Test:* the number changes when the type changes. - -**R18 [DEVIATION] — Refuse loudly and name the alternative.** Where something is out of scope (a -second mate, a tangency, a gear ratio), say what is unsupported and what to do instead. Vendors do not -need this because their solvers accept the input. *Test:* no refusal message ends without a suggested -next action. - ---- - -## 8. Minimal specification, and gap analysis - -### The connector - -``` -MateConnector - body int required, ≥ 0 (R1) - origin_kind enum FaceCentroid | ArcCentre | EdgeMidpoint | Vertex (R9) - origin_ref topo ref face / edge / vertex index on that body - z_source implied by origin_kind: face normal, arc axis, edge tangent - roll_ref topo ref optional in-plane edge; else deterministic seed (R7) - roll_quarters int 0..3 stored quarter turns on top of the seed (R7, A6) - flip_z bool reverse Z at the connector - name string stable, user-visible (D4) -``` - -`flip_z` is a property of the **connector**, chosen once when it is made — not a per-mate -afterthought. Keeping connector-flip and mate-direction separate is what stops the "which flip do I -tick?" question. - -### The mate - -``` -Mate - kind enum Fastened | Revolute | Slider | Cylindrical | Planar [| Ball] (R3) - fixed connector A — its body does not move - moving connector B — its body is driven (A5, C5) - direction enum Facing | Aligned (R5, R6) - offset mm along A's Z, measured A → B — state this in the label (C6) - angle deg about A's Z (R4) -``` - -Within one field of what exists. - -### Gaps against today - -Source of record: `CadDocument.hpp:26,247-252,298-310`; `CadDocument.cpp:1669` (`datum_frame`), -`:2961` (`apply_mate`), `:1302` (`add_mate`); `DesignPanel.cpp:2671-2709` (the Mate card). - -| # | Gap | Severity | Ref | -|---|---|---|---| -| G1 | `PointWorld` connectors are not attached to a body and their X is a world constant | **High — data model** | A4/R1 | -| G2 | Origin is always the face centroid; no vertex / edge-midpoint / arc-centre snap | **High — expressiveness** | D1/R9 | -| G3 | No live preview of the two Z arrows or of the resulting placement | **High — this is the brief** | D3/R16 | -| G4 | Mate card is two abstract dropdowns; nothing says which body moves | High — charter + A5 | R15 | -| G5 | No joint-type inference from the picked geometry | Medium — feel | D2 | -| G6 | `add_mate` validates nothing — no one-mate-per-body, no cycle check | Medium | R11/R12 | -| G7 | No `Ball` type | Low | §3 | -| G8 | Re-clocking needs a typed angle; no 90° step control | Low, cheap | A6/R7 | -| G9 | Degenerate roll falls back silently | Low | C8/R8 | -| G10 | Connectors have no stable user-facing name | Low now, expensive later | D4 | - -**Already aligned — do not "fix" these:** the five types and their DOF; the frame definition (A1); -Z as the joint axis (A2); superimpose-then-relax (A3); the fixed/moving asymmetry in the data model -(A5); DOF wording in the type list (A7); free-DOF preservation (A8); right-handed frames under mirror -(R14); and `en4`'s fix, which put roll derivation on the body where it belongs (C2). - -**The pattern worth naming: the kernel is in good shape and the concept is under-explained.** Half the -requirements here are wording and drawing, not geometry. The two real engineering items are R9 (origin -candidates) and R11/R12 (the mate-graph rules). - -### Expensive-to-retrofit decisions — get these right in the data model now - -Changing any of these after documents exist in the wild costs a migration, not an edit. - -1. **Topological reference stability.** Storing raw face/edge indices is brittle — editing a body - renumbers faces. Either persistent topology IDs, or store the named origin *kind* plus a - deterministic search that re-finds the same geometric intent on rebuild. The latter is cheaper and - probably sufficient here; it is also what makes R10's "error, never silent relocation" enforceable. -2. **Connector ownership** (R1). Remove `PointWorld` or bind it to a body. Do this first. -3. **Mate direction semantics** (R5/D1). Inverting the default rewrites the meaning of every saved - mate. -4. **Roll representation** (R7). "First usable edge" is better than world-X but still fragile. Store - an explicit roll reference plus quarter turns. -5. **Coordinate convention** — Z = joint axis, X = roll reference. Changing this after release - invalidates every mate. -6. **Units** — offset in mm, angle in degrees. Never change. -7. **Mirror handedness** (R14) — document the decision, do not let it stay an accident. -8. **Flat body index vs. a component tree.** Mates currently reference bodies in a flat vector. If - **sub-assemblies** are ever in scope, mates must reference nodes in a tree instead. Retrofitting - this is painful and it is the one item on this list not already implied elsewhere in the document — - **decide now whether nested assemblies are in scope.** -9. **Serialization field semantics.** Adding fields is easy; redefining `mate_flip` or - `coordsys_x_hint` is not. -10. **The one-mate-per-body rule** (R11). Enforce at creation. Relaxing it later by adding a solver is - straightforward; allowing many mates now and discovering later that they silently conflict is not. - ---- - -## 8b. The visual shape of the connector — polarity and verse - -Researched separately (2026-08-05) by downloading and **looking at** the vendors' own figures, not -by reading their prose. Files kept alongside this document in `doc/design/mate-connectors/`. - -### What the systems actually draw - -**Onshape** — verified from `planarfacemateconnectors.png`, `cylindricalmateconnectors.png`, -`linearedgemateconnectors.png`, `mateconnector-planarpoints.png`, `matepointiconLG.png`: - -> **A small circle with one quadrant filled, plus three short coloured axis arms (X red, Y green, -> Z blue).** - -Three parts, each doing one job: - -| Element | What it says | -|---|---| -| The **circle** | "I am a frame, and this is my XY plane." | -| The **filled quadrant** | **The roll.** The shaded sector is the +X/+Y quadrant. | -| The **coloured arms** | The three axis directions, Z distinguished by colour. | - -The quadrant is the cleverest part of the whole design and it is easy to miss. The figure -`matepointreorientsecondaryaxis.png` shows three connectors side by side with the quadrant in three -different rotations — **it is the live readout of "reorient secondary axis in 90° increments" (A6).** -One glyph element makes the otherwise-invisible clocking visible, and makes the 90° button's effect -legible before you commit. The toolbar icon `matepointiconLG.png` is that same circle-with-a-quadrant, -so the symbol is consistent from toolbar to viewport. - -Candidate snap points, before you choose one, are drawn as **plain small white dots** on the model -(clear in `mateconnector-planarpoints.png`: dots at every corner and edge midpoint). Candidate and -committed are deliberately different weights — dots propose, the circle-and-triad commits. - -**FreeCAD 1.0** — verbatim from the wiki: *"Connectors are local coordinate systems and are marked by -a symbol with three axes (X, Y, Z) and a circle representing the XY-plane."* Same core as Onshape — -circle plus triad — **without** the quadrant. - -**Fusion 360** — the joint origin glyph, plus a documented icon language for *candidates*: *"A circle -denotes a vertex, and a triangle denotes a midpoint."* Shape encodes what kind of point it is. - -**Convergent core:** *circle for the XY plane + coloured triad*. Onshape alone adds the roll quadrant. - -### What none of them draw — and it is exactly what was asked for - -**Nothing in any vendor's glyph says which connector is the reference and which one is about to -move.** Both ends of a mate are drawn identically. That is confusion C5 ("which part moves?") left -unsolved in the visual language, and it is why the honest recommendation earlier was a live ghost — -the ghost compensates for a glyph that does not carry the information. - -So the two things asked for split cleanly, and only one of them is solved upstream: - -- **Verse** (*verso* — which way it points): **solved**. Z has a colour and a direction. -- **Polarity** (which end receives, which end inserts; who is anchored, who travels): **unsolved - everywhere.** This is open ground, and getting it right is a genuine improvement rather than a - deviation to justify. - -### Our starting point - -**We draw nothing.** `resolve_datum_coordsys()` (`CadDocument.cpp:1749`) has exactly one consumer in -the entire tree — `McpControl.cpp:1310`, the agent socket. A mate connector is today visible only to -a program. The glyph is unbuilt, so there is no migration cost to designing it properly now. - -### Proposed glyph: the magnet - -Adopt Onshape's proven core, then add the missing polarity with a metaphor that carries its own -instructions. - -``` - ▲ solid cone on +Z ONLY ← verse - | - ────●──── ← the disc = XY plane, ● = exact origin - ▨ quadrant filled ← roll / clocking, steps 90° -``` - -**Rule 1 — verse: draw +Z and never −Z.** A single stem with a cone head, on the positive side only. -No stem below the disc. A double-headed axis is the one thing that guarantees the question gets asked; -an arrow that exists on one side only cannot be misread. Length is asymmetric on purpose. - -**Rule 2 — roll: keep Onshape's quadrant.** Filled sector = the +X/+Y quadrant. It rotates in 90° -steps with the reorient control (A6/R7). This is aligned *and* it is the only in-glyph answer to -"where is X?", which matters because Fastened and Slider lock the clocking. - -**Rule 3 — polarity: solid cone travels, open collar receives.** -- The **driven** connector (B, on the body that will move) draws a **solid filled cone** — the plug. -- The **fixed** connector (A) draws an **open ring / hollow cone outline** — the socket. - -Same silhouette, so they read as a matched pair; opposite fill, so which one is about to jump is -answerable at a glance and without a legend. Plug-into-socket is the one mechanical metaphor every -user of this tool already has in their hands. - -**Rule 4 — the pair reads as a magnet.** Draw a dashed line joining the two origins the moment both -are picked. Two poles, one field line. And because a magnet's north seeks a south, **"facing" becomes -the self-evident default** — which quietly settles open decision D1 (§9) on visual grounds rather than -on a convention nobody can look up. If the glyph looks like a magnet, nobody has to be told that two -faces which touch have opposed normals. - -**Rule 5 — three states, three weights.** - -| State | Drawing | -|---|---| -| **Candidate** (hover) | small dot only — Onshape's white dots; shape may encode kind, Fusion-style | -| **Picked** | full glyph: disc + quadrant + cone | -| **Degenerate roll** (C8/R8) | the quadrant is drawn **hollow/hatched** — "roll undefined, pick a direction" | - -That last row is worth the trouble: it turns R8 from a message nobody reads into a mark you cannot -miss, and it costs one branch in the renderer. - -**Rule 6 — do not reuse the existing triad.** The bed-centre world triad -(`DesignCanvas.cpp:65`, `set_axes_at_bed_center`) and the move gizmo are already three-coloured arrows. -The connector must not be a fourth set of RGB arrows or the viewport becomes unreadable. The disc and -the quadrant are what distinguish it; keep the arms short, and consider drawing only Z on the -committed glyph, with X/Y implied by the quadrant. - -### Built and judged in the viewport, not in a mock - -The browser mock that first accompanied this section was the wrong instrument and its proportions -were meaningless: **every gizmo in this codebase is sized in SCREEN PIXELS** via `upp = 1/zoom` -(`render_shell_gizmo` uses `15.0 * upp`, `render_hole_gizmo` `9.0 * upp` for its cube). A connector -is a symbol, not a part — it must not shrink with the model. Nothing about that is visible in SVG. - -The glyph was therefore implemented and driven on the rig. Screenshots: `g-0*.png`, left in the workspace `artifacts/shots/` and not moved into the repo. -Five findings, none of which a mock could have produced: - -**F1 — Three axis arms lose to one.** Rendered side by side (`ORCA_CAD_GLYPH=A` vs default), the -Onshape-style RGB trio crowds a 22 px disc: the arrowheads are as large as the disc, they bury the -gold quadrant, and at an oblique angle the three heads pile into a coloured smudge. Worse, **it is -indistinguishable from the move gizmo and the bed triad**, which are already RGB arrow trios in this -viewport. One-sided Z wins on evidence, not taste. (`g-01-zoom.png` vs `g-02-zoom.png`.) - -**F2 — Polarity works, and colour does more of the work than fill.** A filled blue head against an -open grey outline head is readable instantly at 22 px (`g-03-zoom.png`). But the fill difference is -the *second* cue; the colour split carries it. Keep both — fill survives greyscale and colour-blind -palettes, colour survives small size. - -**F3 — Depth off floats, depth on tears.** With `GL_DEPTH_TEST` off, connectors on faces pointing -*away* from the camera still drew their discs over the solid, so the part looked covered in frames -that were really on its back. Turning depth on fixed that and immediately caused **z-fighting**: the -disc is exactly coplanar with its face, and came out as a broken dotted arc. The fix is depth **on** -plus a sub-pixel lift along Z (`0.7 * upp`), scaled by `upp` so it never becomes a visible gap on -zoom-in. Both failure modes are in the images (`g-03` torn, `g-04` clean). - -**F4 — The quadrant is the first thing to die at a grazing angle.** On a face seen nearly edge-on the -disc foreshortens to a sliver and the fan collapses into a blob (`g-01-zoom.png`, lower-right glyph). -The roll is exactly the information that is hardest to read when you most need it. Not yet solved — -see the open item below. - -**F5 — Roll-undefined in red is too loud.** It works, but it makes the *least* important connector -the most eye-catching thing on screen. Amber, or the same grey with a hatched quadrant, is enough. - -Also surfaced while testing, and unrelated to the glyph: `add_mate` accepted a mate between two -connectors **on the same body**, which is meaningless, and duly transformed the body relative to -itself. Concrete instance of gap G6. - -**Still untested:** a true grazing view (the view-cube click missed), a connector on a curved face, -and behaviour when a connector overlaps the move gizmo. F4 is the open design question — the disc may -need to billboard its *quadrant* while keeping the disc in-plane, which is a compromise no surveyed -vendor makes and which should be tried before being adopted. - -### What this costs - -A renderer for `resolve_datum_coordsys()` — which does not exist and has to be written whatever glyph -is chosen — plus one dashed line and three fill states. No kernel work. It is the same piece of work -as G3 (live preview), and doing them together is what makes the mate card honest. - ---- - -## 8c. The "faceted ridge dome" proposal — built, rendered, judged - -A colleague proposed replacing the flat disc with an **asymmetric low-poly solid**: a faceted -prismatic wedge with a dominant longitudinal ridge that **slopes** from a tall steep back to a long -shallow front, plus a male protrusion / female pocket pair with a 0.2 mm clearance. - -It was built rather than discussed. `faceted_ridge_key.scad` (this folder) (6 vertices, 7 faces), -verified as a closed manifold, exported through OpenSCAD, and flat-shaded from five directions with -`render_key.py` / `render_stl.py`. Sheets: `rk-sheet.png`, `cmp-sheet.png`. - -### The verdict: the shape is right, the male/female polarity cue is not - -**It solves F4, decisively.** The grazing view — where the flat disc dies, its quadrant collapsing to -a blob — is the view where this shape is *most* legible: the tall back and long shallow front are -unmistakable in silhouette. At a grazing angle the silhouette IS the information, and this solid's -silhouette is maximally informative there. That is a real, evidence-backed win over what is currently -in the code. - -**Down the mating axis (+Z) it also reads well**, which matters because that is the natural viewing -direction when you are looking at a face you intend to mate. - -**One degenerate view, and it is not the one I predicted.** I expected the ±X views (along the ridge) -to be silhouette-ambiguous, resolved only by shading. Wrong: front and back are clearly *different* — -the front shows several facets, the back is a **single flat featureless triangle**. So they are not -confusable, but the view from directly behind the tall end tells you nothing about roll or slope. -A second blind spot remains untested: from below the base, where the protrusion is hidden behind its -own face. - -**The female half fails, and much harder than expected.** Rendered with flat shading and no outlines — -the honest test, since a viewport draws no black edges — a recessed pocket is *invisible*: iso and -grazing show a plain block with a hairline; straight down the axis shows a **completely blank -rectangle**. The interior faces are lit almost identically to the top face and are occluded by the rim -from most angles. As a polarity cue, male/female therefore works in exactly one direction and returns -nothing in the other. - -> **Conclusion: do not overload shape with all three jobs.** Let the solid carry **verse and roll**, -> where it is excellent, and carry **polarity on a second channel** — colour plus the filled/open head -> that already tested well at 22 px (F2). Drawing the fixed connector as an outline/wireframe of the -> same solid is the variant worth trying; drawing it as a pocket is not. - -### Two premises in the brief are wrong - -**"Avoid curved surfaces to optimise rendering computations / rapid mesh processing."** Not a reason -for a viewport glyph. There are 2–20 connectors on screen, the renderer pushes `GLModel` triangles -directly, and it performs no CSG or mesh processing at all. **The real argument for flat facets is -legibility**: hard normals give distinct value steps between adjacent facets, and the renders confirm -that is exactly what makes the shape readable from an arbitrary angle. Keep the constraint, fix the -justification. (For a *printed* part the original justification is sound for a different reason: flat -facets slice without the stair-stepping a tessellated curve produces.) - -**"0.2 mm clearance for smooth mechanical mating."** Meaningless for a glyph. A symbol mates with -nothing, and every gizmo here is sized in screen pixels via `upp`, so a millimetre tolerance has no -referent. This is the strongest signal that **the brief was written for a physical printed part**, -not for a viewport symbol — as are "scannable" and "mechanical mating". See the open question below. - -### Two defects the build caught that discussion would not have - -1. **The flank quads are not planar.** Written as `[0,3,5,4]` and `[1,4,5,2]` the base edge and the - ridge edge are skew, so the four corners do not share a plane — my own first draft asserted the - opposite in a comment. Left as quads, the tessellator picks the fold direction, the "flat facet" - promise is broken by an unspecified crease, and two exporters can disagree about the shape. Fixed - by triangulating explicitly (7 faces, Euler 6 − 11 + 7 = 2). -2. **The pocket punched through its own plate.** A 4.5 mm key against a 3 mm demo plate gives a - through-hole, not a pocket. Minimum stock = height + clearance + pocket depth + a wall. - -Also worth recording: the first female render was misleading because the debug renderer outlined -*every* triangle, so a flat top face triangulated by CGAL looked like a faceted dome. The instrument -lied before the geometry did. Conclusions were only drawn after outlines were removed. - -### Second opinion, and the one disagreement worth resolving - -Kimi reviewed the proposal independently and **rejected it for the viewport**. It agreed on the two -wrong premises, agreed the female pocket is unreadable, and added the useful framing that a -screen-constant symbol and a model-constant part feature are two different design spaces that cannot -be served by one geometry. It also noted correctly that there is **no single scalar** that removes -ambiguity from every view: you need one asymmetry in the base plane (for top-down roll) and one out -of plane (the ridge slope, for front/back). Our base is scalene, so it has both. - -Its central objection was numeric and testable: *"at 22 px with 6–8 facets each facet is 3–7 px wide, -that is at the aliasing limit … minimum useful size is roughly 32–48 px, which is not compatible with -a 22 px screen-constant symbol."* My own renders were ~300 px, so the claim was unaddressed by my -evidence and would have killed the concept if true. - -**Rendered at 22, 32 and 48 px (`size-test.png`), it is false for this shape.** At 22 px all three -views still read: the grazing view shows the tall back and shallow front unmistakably, and the -down-axis view keeps a strong dark/light split. The reason Kimi's arithmetic does not apply is that -this solid presents only **four or five large facets with high value contrast**, not eight small ones — -the silhouette does most of the work, and silhouettes survive downsampling far better than facet -detail does. - -*Honest limit on that result:* the test renderer has no anti-aliasing, no perspective, one directional -light, and no background. Readable at 22 px against white is not the same as readable at 22 px on top -of a shaded gold part next to the move gizmo. That case still needs the rig. - -**Where I do not follow Kimi:** its recommendation is to **billboard** the existing flat glyph so it -never turns edge-on. That kills F4 by construction, but a billboarded frame cannot show the frame's -orientation *in place* — which is the entire reason the disc is a disc and not a dot — and it is what -no surveyed CAD system does; Onshape, Fusion and FreeCAD all draw the frame in the geometry. Worth -prototyping as an option, not worth adopting on argument. - -### Open question for Tommaso - -**Is this a viewport glyph or a printable alignment feature?** The vertex logic is identical either -way; only the units and the clearance change, and the `.scad` file states both readings. But the -answer decides whether `clr`/`depth` are real millimetres or meaningless, and whether the geometry -scales with the model or stays screen-constant. The brief's own language points at "physical", the -conversation it arrived in points at "glyph". - ---- - -## 9. Decisions for you - -**D1 — Invert the default direction to Facing?** [DEVIATION, R5] -It changes the meaning of every stored document containing a mate. Options: (a) invert and migrate, -writing `direction=Aligned` where `mate_flip` was false; (b) invert only for new mates and store -`direction` explicitly from now on. (b) is safer and costs one field. Note this project has taken one -such semantic hit knowingly before — the `en4` fix — and the golden fixture survived, so the -migration path is a known quantity. **If G3 (live preview) lands first, this matters much less.** - -**D2 — How far to take origin candidates?** [R9] -Four kinds is the Fusion-aligned recommendation. Two (face centroid + arc centre) would cover "sit on -a face" and "go down a hole" — most printed-part assembly — at a third of the work. Where do you want -to stop? - -**D3 — Ball mate: in or out?** -In four of five frame-based systems, so including it is the aligned choice. Out is defensible for -printable mechanical parts. Cheap either way — align origins, leave orientation free. Kimi's review -argued **out**: a true ball joint is hard to print and hard to use without a roll reference, and a -Fastened connector at the ball centre approximates it. - -**D3a — Should Planar be dropped?** [dissent worth recording] -Kimi's independent review recommended **removing Planar** and shipping four types, on the grounds that -"slide on a flat surface" is rarely how printed mechanisms work — you usually want a rail or a hinge — -and that Planar is the type most likely to confuse a user who expected "put this flat on that" and got -a part free to slide. It further ranked the honest minimum as **three**: Fastened, Revolute, Slider, -with Cylindrical useful and decomposable. -**I do not agree, and the reason is alignment.** Planar appears in every frame-based system surveyed, -it is a genuine lower pair, it is already implemented and tested, and removing it is a document-format -change made in exchange for nothing. The confusion Kimi names is real but it is a *feedback* problem — -it is exactly what R17 (show the DOF budget) and R13 (say that free DOF are preserved) exist to fix. -Recorded here because it is a legitimate reading of the same evidence and the call is yours. - -**D4 — Is refusing a second mate per body acceptable?** [DEVIATION, R11 — the big one] -It is the honest consequence of having no solver, and it is what makes the tool predictable. But **no -mainstream system behaves this way**, so it is the point where an experienced user's intuition will -break. It means a part cannot be constrained by two independent relationships — "in this hole *and* -resting on this shoulder" must be expressed by placing one connector correctly rather than by two -mates. If that trade is unacceptable, the answer is a solver, and the scope of this document changes -entirely. - -There is a strong argument that the trade is not merely acceptable but *correct for this product*: -the Design tab lives inside a slicer, and most of its users are positioning parts for printing rather -than building working mechanisms. For layout-and-export, tree-order composition is genuinely enough, -and adding a solver to look like Onshape would buy complexity nobody asked for. The rule to publish is -then simple and defensible: **one mate per moving body, acyclic, no relations between mates** — with -R18's loud refusals carrying the honesty. - ---- - -## Sources - -**Onshape** — [Mate Connector](https://cad.onshape.com/help/Content/PartStudio/mate_connector.htm) · -[Mates](https://cad.onshape.com/help/Content/Assembly/mates.htm) · -[Fastened](https://cad.onshape.com/help/Content/Assembly/fastened_mate.htm) · -[Revolute](https://cad.onshape.com/help/Content/Assembly/revolute_mate.htm) · -[Slider](https://cad.onshape.com/help/Content/Assembly/slider_mate.htm) · -[Cylindrical](https://cad.onshape.com/help/Content/Assembly/cylindrical_mate.htm) · -[Planar](https://cad.onshape.com/help/Content/Assembly/planar_mate.htm) · -[Ball](https://cad.onshape.com/help/Content/Assembly/ball_mate.htm) · -[Parallel](https://cad.onshape.com/help/Content/Assembly/parallel_mate.htm) · -[Tangent](https://cad.onshape.com/help/Content/Assembly/tangent_mate.htm) · -[Pin Slot](https://cad.onshape.com/help/Content/Assembly/pin_slot_mate.htm) · -[5 things you can do with mate connectors in Part Studios](https://www.onshape.com/en/resource-center/tech-tips/tech-tip-5-things-you-can-do-with-mate-connectors-in-onshape-part-studios) - -**Onshape forum** — [The concept behind Mates Z Axes](https://forum.onshape.com/discussion/22828/the-concept-behind-mates-z-axes) (C1/D3) · -[Implicit mate connectors act differently than explicit ones](https://forum.onshape.com/discussion/15736/implicit-mate-connectors-act-differently-than-explicit-ones) (C4) · -[Efficiently set mate connectors](https://forum.onshape.com/discussion/13133/efficiently-set-mate-connectors) - -**Fusion 360** — [Joint types](https://help.autodesk.com/cloudhelp/ENU/Fusion-Assemble/files/GUID-8818AE31-958A-4A59-989B-9875A174C67A.htm) · -[Joint origins](https://help.autodesk.com/view/fusion360/ENU/?guid=ASM-JOINT-ORIGIN) · -[Joints vs. Mates in Fusion](https://www.autodesk.com/products/fusion-360/blog/joints-mates-moving-fusion/) · -[Joint tips — snap points and Ctrl cycling](https://mgfx.co.za/blog/engineering-manufacturing-design/fusion-360-joint-tips/) - -**Inventor** — [Create Joints Reference](https://help.autodesk.com/cloudhelp/2026/ENU/Inventor-Help/files/GUID-6AA68E8F-7C97-4806-8483-3941DE915E70.htm) · -[Use Joint to define and manage relationships](https://knowledge.autodesk.com/support/inventor-products/learn-explore/caas/CloudHelp/cloudhelp/2014/ENU/Inventor/files/GUID-21DC3336-5C51-42C1-90FB-4299CD66E0C6-htm.html) (type inference, D2) - -**FreeCAD 1.0** — [Assembly Workbench](https://wiki.freecad.org/Assembly_Workbench) · -[Fixed Joint properties](https://wiki.freecad.org/Assembly_CreateJointFixed) - -**Creo** — [About Predefined Constraint Sets](https://support.ptc.com/help/creo/creo_pma/r12/usascii/assembly/asm/About_Predefined_Constraint_Sets.html) - -**Siemens NX** — [Assembly constraints](https://learnnx.com/lesson/siemens-nx-assemblies-assembly-constraints/) - -**SOLIDWORKS** — [Mate References](https://help.solidworks.com/2025/English/SolidWorks/sldworks/c_Mate_References_Overview_SWassy.htm) · -[Creating and using mate references](https://blogs.solidworks.com/tech/2019/07/creating-and-using-mate-references.html) - -**Theory** — [Hervé, The Lie group of rigid body displacements, a fundamental tool for mechanism design](https://www.sciencedirect.com/science/article/abs/pii/S0094114X98000512) · -[Joint kinematics — the six lower pairs and their DOF](https://erc-bpgc.github.io/handbook/mechanical/Joint%20Kinematics/) · -[ISO 10303-105 — Kinematics (STEP integrated resource)](https://www.iso.org/standard/78589.html) - -**Internal** — `en4` (closed 2026-07-26, fixes C2 here) · `CadDocument.cpp:1669` -`datum_frame` · `CadDocument.cpp:2961` `apply_mate` · `CadDocument.cpp:1302` `add_mate` - -**Second opinion** — an independent review by Kimi Code (2026-08-05) contributed the -vendors-ship-both caveat (§1), the explicit-dropdown option for origin choice (D1), the expanded -refusal list (R11a), the retrofit list (§8), and the dissents recorded at D3/D3a. One of its claims — -that Onshape mandates *"exactly one Mate between any two instances"* — **was checked against the -source and is wrong**; the correction is recorded at R11 because it is a misreading that would -otherwise turn our largest deviation into a false agreement. diff --git a/docs/CAD/design/mate-connectors/bear-01-view.png b/docs/CAD/design/mate-connectors/bear-01-view.png deleted file mode 100644 index eb57aaeefe..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-01-view.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-02-view.png b/docs/CAD/design/mate-connectors/bear-02-view.png deleted file mode 100644 index 46b6d834fa..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-02-view.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-02-zoom.png b/docs/CAD/design/mate-connectors/bear-02-zoom.png deleted file mode 100644 index 437adaee9d..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-02-zoom.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-flat.png b/docs/CAD/design/mate-connectors/bear-flat.png deleted file mode 100644 index 16375b9d5c..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-flat.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-sil-cmp.png b/docs/CAD/design/mate-connectors/bear-sil-cmp.png deleted file mode 100644 index eb2f283f95..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-sil-cmp.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-sil.png b/docs/CAD/design/mate-connectors/bear-sil.png deleted file mode 100644 index 2b6e51067e..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-sil.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear_glyph_table.h b/docs/CAD/design/mate-connectors/bear_glyph_table.h deleted file mode 100644 index c26631e7e0..0000000000 --- a/docs/CAD/design/mate-connectors/bear_glyph_table.h +++ /dev/null @@ -1,30 +0,0 @@ -// Emitted by doc/design/mate-connectors/emit_glyph_table.py from bear.step — do not hand-edit. -// Normalised to the part's bounding span and centred: the renderer scales by one radius. -static const Vec2d kBearOutline[] = { // 12 verts, RDP eps 0.030, CCW - {+0.3842, +0.3294}, {+0.3156, +0.4002}, {+0.2424, +0.3294}, - {-0.2524, +0.3294}, {-0.3377, +0.3877}, {-0.3693, +0.3298}, - {-0.3256, +0.2631}, {-0.4893, -0.3337}, {-0.3960, -0.4002}, - {+0.4151, -0.4002}, {+0.5000, -0.3154}, {+0.3156, +0.2631}, -}; -static const Vec2d kBearChin[] = { // the CHIN BAR, flat. The muzzle is relief — see kBearCrest. - {-0.2682, -0.3578}, {+0.2628, -0.3578}, {+0.2237, -0.1786}, -}; -// {cx, cy, r}: two eyes, then the cheek dot that carries handedness (wi3z). -static const Vec3d kBearMarks[] = { - {-0.1997, +0.1760, +0.0590}, - {+0.1947, +0.1760, +0.0590}, - {+0.2797, +0.0760, +0.0380}, -}; -// THE MUZZLE, lifted off the mesh: a tapered wedge, base quad + crest edge, 6 facets. -// This is the only feature standing along +Z and the only one still legible edge-on. -static const double kBearPlateZ = +0.0360; -static const Vec2d kBearSnoutBase[] = { // CCW from the nose end - {-0.0727, -0.2417}, - {+0.0630, -0.2417}, - {+0.0259, +0.1939}, - {-0.0356, +0.1939}, -}; -static const Vec3d kBearCrest[] = { // nose (tall) -> tail (short) - {-0.0048, -0.1793, +0.2073}, - {-0.0048, +0.1605, +0.1279}, -}; diff --git a/docs/CAD/design/mate-connectors/bear_mesh.json b/docs/CAD/design/mate-connectors/bear_mesh.json deleted file mode 100644 index 4bfb6aa361..0000000000 --- a/docs/CAD/design/mate-connectors/bear_mesh.json +++ /dev/null @@ -1 +0,0 @@ -{"v": [[-36.7146, 0.0, -1.7146], [-36.0624, 0.0, -1.152], [-36.5065, 0.0, -1.5165], [-36.2889, 0.0, -1.3288], [-39.9409, 0.0, -4.9818], [-40.1196, 0.0, -5.2115], [-39.751, 0.0, -4.7612], [-39.5503, 0.0, -4.5503], [-35.8275, 0.0, -0.9866], [-35.3348, 0.0, -0.6912], [-35.5848, 0.0, -0.8329], [-40.4417, 0.0, -5.6962], [-40.5842, 0.0, -5.95], [-40.2867, 0.0, -5.4499], [-35.0781, 0.0, -0.5621], [-40.714, 0.0, -6.2105], [-34.5473, 0.0, -0.3422], [-34.8154, 0.0, -0.4456], [-40.8307, 0.0, -6.4772], [-40.934, 0.0, -6.7493], [-41.0236, 0.0, -7.0262], [-33.9976, 0.0, -0.1754], [-34.2745, 0.0, -0.2521], [-41.161, 0.0, -7.5917], [-41.2085, 0.0, -7.8789], [-41.0994, 0.0, -7.3072], [-33.149, 0.0, -0.0282], [-33.7172, 0.0, -0.1125], [-33.4341, 0.0, -0.0634], [-32.8624, 0.0, -0.0071], [-32.5752, 0.0, -0.0], [-41.2544, 0.0, -9.0404], [-41.2298, 0.0, -9.3304], [-41.2646, 0.0, -8.7495], [-41.2604, 0.0, -8.4585], [-41.2417, 0.0, -8.168], [-41.1908, 0.0, -9.6189], [-41.1374, 0.0, -9.905], [-41.07, 0.0, -10.1881], [-40.9885, 0.0, -10.4676], [-21.9255, 0.0, -9.1038], [-21.9255, 0.0, -3.5345], [-20.0463, 0.0, -44.6525], [-19.8744, 0.0, -44.4763], [-19.694, 0.0, -44.309], [-20.2091, 0.0, -44.837], [-19.5055, 0.0, -44.1508], [-20.3625, 0.0, -45.0294], [-19.3094, 0.0, -44.0022], [-20.5062, 0.0, -45.2292], [-19.106, 0.0, -43.8635], [-20.6397, 0.0, -45.436], [-18.896, 0.0, -43.7352], [-20.7628, 0.0, -45.6491], [-18.6799, 0.0, -43.6175], [-20.875, 0.0, -45.8681], [-18.4582, 0.0, -43.5108], [-20.9762, 0.0, -46.0924], [-18.2314, 0.0, -43.4152], [-21.0662, 0.0, -46.3215], [-18.0002, 0.0, -43.331], [-17.765, 0.0, -43.2585], [-17.5265, 0.0, -43.1977], [22.3077, 0.0, -3.5345], [-17.2853, 0.0, -43.149], [-17.042, 0.0, -43.1123], [-16.7971, 0.0, -43.0878], [-16.5513, 0.0, -43.0755], [-16.3052, 0.0, -43.0755], [-16.0594, 0.0, -43.0878], [-15.8146, 0.0, -43.1123], [-15.5712, 0.0, -43.149], [-15.33, 0.0, -43.1977], [-0.0, 0.0, -9.1038], [-15.0915, 0.0, -43.2585], [-14.8564, 0.0, -43.331], [-21.2112, 0.0, -49.2274], [-26.7105, 0.0, -55.2632], [-21.1445, 0.0, -49.4643], [-21.2659, 0.0, -48.9875], [-21.3087, 0.0, -48.7451], [-21.3393, 0.0, -48.5009], [-21.3577, 0.0, -48.2555], [-21.3638, 0.0, -48.0095], [-21.3577, 0.0, -47.7635], [-21.3393, 0.0, -47.5181], [-21.3087, 0.0, -47.2739], [-21.2659, 0.0, -47.0316], [-21.2112, 0.0, -46.7916], [-21.1445, 0.0, -46.5547], [-21.0662, 0.0, -49.6976], [-14.6251, 0.0, -43.4152], [-20.9762, 0.0, -49.9266], [-14.3984, 0.0, -43.5108], [-20.875, 0.0, -50.151], [-14.1766, 0.0, -43.6175], [-20.7628, 0.0, -50.37], [-13.9605, 0.0, -43.7352], [-20.6397, 0.0, -50.5831], [-13.7505, 0.0, -43.8635], [-20.5062, 0.0, -50.7898], [-13.5472, 0.0, -44.0022], [-20.3625, 0.0, -50.9896], [-13.351, 0.0, -44.1508], [-20.2091, 0.0, -51.182], [-13.1625, 0.0, -44.309], [-20.0463, 0.0, -51.3665], [-19.8744, 0.0, -51.5427], [-19.694, 0.0, -51.7101], [-19.5055, 0.0, -51.8683], [-19.3094, 0.0, -52.0169], [-19.106, 0.0, -52.1555], [35.0, 0.0, 0.0], [19.0522, 0.0, -18.4636], [16.4743, 0.0, -9.1399], [-27.6672, 0.0, -65.6993], [-27.6141, 0.0, -65.7466], [-27.7179, 0.0, -65.6494], [-27.5588, 0.0, -65.7913], [-27.4419, 0.0, -65.8722], [-27.3806, 0.0, -65.9082], [-27.5013, 0.0, -65.8332], [-27.3177, 0.0, -65.9412], [-27.2531, 0.0, -65.9711], [-27.1872, 0.0, -65.9978], [-27.1201, 0.0, -66.0212], [-27.0519, 0.0, -66.0413], [-26.9828, 0.0, -66.058], [-26.9129, 0.0, -66.0713], [-26.8425, 0.0, -66.0811], [-26.7007, 0.0, -66.0904], [-26.7717, 0.0, -66.0875], [-26.6296, 0.0, -66.0899], [-26.4879, 0.0, -66.0782], [-26.4177, 0.0, -66.0672], [-26.5586, 0.0, -66.0858], [-26.3481, 0.0, -66.0528], [-26.2792, 0.0, -66.035], [-26.2114, 0.0, -66.0138], [-26.1446, 0.0, -65.9893], [-26.0792, 0.0, -65.9615], [-26.0151, 0.0, -65.9306], [-25.9527, 0.0, -65.8966], [-25.892, 0.0, -65.8595], [-25.8332, 0.0, -65.8196], [-25.7765, 0.0, -65.7767], [-25.7219, 0.0, -65.7312], [-25.6696, 0.0, -65.683], [-28.9439, 0.0, -64.3825], [-29.1102, 0.0, -64.202], [-29.2675, 0.0, -64.0136], [-29.4153, 0.0, -63.8176], [-29.5533, 0.0, -63.6147], [-29.6811, 0.0, -63.4052], [-29.7986, 0.0, -63.1898], [-29.9053, 0.0, -62.9688], [-30.0011, 0.0, -62.7428], [-30.0856, 0.0, -62.5124], [-30.1588, 0.0, -62.2782], [-30.2204, 0.0, -62.0406], [-30.2702, 0.0, -61.8003], [-30.3082, 0.0, -61.5579], [-30.3342, 0.0, -61.3138], [-30.3483, 0.0, -61.0688], [-30.3503, 0.0, -60.8234], [-30.3402, 0.0, -60.5782], [-30.3182, 0.0, -60.3338], [-30.2841, 0.0, -60.0908], [-30.2382, 0.0, -59.8497], [-30.1805, 0.0, -59.6111], [-30.1112, 0.0, -59.3757], [-30.0304, 0.0, -59.144], [-29.9383, 0.0, -58.9165], [-29.8352, 0.0, -58.6938], [-29.7213, 0.0, -58.4764], [-29.5969, 0.0, -58.2649], [-13.7505, 0.0, -52.1555], [-20.6129, 0.0, -60.7895], [-13.5472, 0.0, -52.0169], [-13.9605, 0.0, -52.2838], [-14.1766, 0.0, -52.4015], [-14.3984, 0.0, -52.5083], [-14.6251, 0.0, -52.6039], [-14.8564, 0.0, -52.688], [-15.0915, 0.0, -52.7606], [-15.33, 0.0, -52.8213], [-15.5712, 0.0, -52.8701], [-15.8146, 0.0, -52.9067], [-16.0594, 0.0, -52.9312], [-16.3052, 0.0, -52.9435], [-16.5513, 0.0, -52.9435], [-16.7971, 0.0, -52.9312], [-17.042, 0.0, -52.9067], [-17.2853, 0.0, -52.8701], [-17.5265, 0.0, -52.8213], [-17.765, 0.0, -52.7606], [-18.0002, 0.0, -52.688], [-18.2314, 0.0, -52.6039], [-18.4582, 0.0, -52.5083], [-18.6799, 0.0, -52.4015], [-18.896, 0.0, -52.2838], [-29.4622, 0.0, -58.0598], [-29.3176, 0.0, -57.8615], [-29.1635, 0.0, -57.6705], [-29.0002, 0.0, -57.4873], [-28.828, 0.0, -57.3124], [42.0711, 0.0, -7.0711], [-12.9821, 0.0, -44.4763], [12.9821, 0.0, -44.4763], [-12.8103, 0.0, -44.6525], [12.8103, 0.0, -44.6525], [-12.6474, 0.0, -44.837], [13.1625, 0.0, -44.309], [12.6474, 0.0, -44.837], [13.351, 0.0, -44.1508], [-12.494, 0.0, -45.0294], [12.494, 0.0, -45.0294], [13.5472, 0.0, -44.0022], [-12.3504, 0.0, -45.2292], [12.3504, 0.0, -45.2292], [-12.2168, 0.0, -45.436], [13.7505, 0.0, -43.8635], [-12.0938, 0.0, -45.6491], [12.2168, 0.0, -45.436], [13.9605, 0.0, -43.7352], [12.0938, 0.0, -45.6491], [14.1766, 0.0, -43.6175], [-11.9815, 0.0, -45.8681], [11.9815, 0.0, -45.8681], [14.3984, 0.0, -43.5108], [-11.8803, 0.0, -46.0924], [11.8803, 0.0, -46.0924], [14.6251, 0.0, -43.4152], [11.7904, 0.0, -46.3215], [-11.7904, 0.0, -46.3215], [-11.712, 0.0, -46.5547], [14.8564, 0.0, -43.331], [11.712, 0.0, -46.5547], [15.0915, 0.0, -43.2585], [-11.6454, 0.0, -46.7916], [11.6454, 0.0, -46.7916], [15.33, 0.0, -43.1977], [-11.5906, 0.0, -47.0316], [11.5906, 0.0, -47.0316], [15.5712, 0.0, -43.149], [-11.5479, 0.0, -47.2739], [11.5479, 0.0, -47.2739], [15.8146, 0.0, -43.1123], [-11.5173, 0.0, -47.5181], [11.5173, 0.0, -47.5181], [16.0594, 0.0, -43.0878], [11.4989, 0.0, -47.7635], [-11.4989, 0.0, -47.7635], [16.3052, 0.0, -43.0755], [11.4928, 0.0, -48.0095], [-11.4928, 0.0, -48.0095], [16.5513, 0.0, -43.0755], [-11.4989, 0.0, -48.2555], [11.4989, 0.0, -48.2555], [-11.5173, 0.0, -48.5009], [16.7971, 0.0, -43.0878], [11.5173, 0.0, -48.5009], [-11.5479, 0.0, -48.7451], [17.042, 0.0, -43.1123], [11.5479, 0.0, -48.7451], [17.2853, 0.0, -43.149], [11.5906, 0.0, -48.9875], [-11.5906, 0.0, -48.9875], [17.5265, 0.0, -43.1977], [11.6454, 0.0, -49.2274], [-11.6454, 0.0, -49.2274], [17.765, 0.0, -43.2585], [-11.712, 0.0, -49.4643], [11.712, 0.0, -49.4643], [-11.7904, 0.0, -49.6976], [18.0002, 0.0, -43.331], [11.7904, 0.0, -49.6976], [18.2314, 0.0, -43.4152], [-11.8803, 0.0, -49.9266], [11.8803, 0.0, -49.9266], [18.4582, 0.0, -43.5108], [-11.9815, 0.0, -50.151], [11.9815, 0.0, -50.151], [18.6799, 0.0, -43.6175], [-12.0938, 0.0, -50.37], [12.0938, 0.0, -50.37], [18.896, 0.0, -43.7352], [-12.2168, 0.0, -50.5831], [12.2168, 0.0, -50.5831], [-12.3504, 0.0, -50.7898], [19.106, 0.0, -43.8635], [12.3504, 0.0, -50.7898], [19.3094, 0.0, -44.0022], [-12.494, 0.0, -50.9896], [12.494, 0.0, -50.9896], [19.5055, 0.0, -44.1508], [-12.6474, 0.0, -51.182], [12.6474, 0.0, -51.182], [-12.8103, 0.0, -51.3665], [19.694, 0.0, -44.309], [12.8103, 0.0, -51.3665], [-12.9821, 0.0, -51.5427], [19.8744, 0.0, -44.4763], [-13.1625, 0.0, -51.7101], [12.9821, 0.0, -51.5427], [20.0463, 0.0, -44.6525], [13.1625, 0.0, -51.7101], [20.2091, 0.0, -44.837], [13.351, 0.0, -51.8683], [-13.351, 0.0, -51.8683], [20.3625, 0.0, -45.0294], [13.5472, 0.0, -52.0169], [20.5062, 0.0, -45.2292], [20.6397, 0.0, -45.436], [20.7628, 0.0, -45.6491], [20.875, 0.0, -45.8681], [20.9762, 0.0, -46.0924], [20.6129, 0.0, -60.7895], [18.896, 0.0, -52.2838], [19.106, 0.0, -52.1555], [18.6799, 0.0, -52.4015], [18.4582, 0.0, -52.5083], [18.2314, 0.0, -52.6039], [18.0002, 0.0, -52.688], [17.765, 0.0, -52.7606], [17.5265, 0.0, -52.8213], [17.2853, 0.0, -52.8701], [17.042, 0.0, -52.9067], [16.7971, 0.0, -52.9312], [16.5513, 0.0, -52.9435], [16.3052, 0.0, -52.9435], [16.0594, 0.0, -52.9312], [15.8146, 0.0, -52.9067], [15.5712, 0.0, -52.8701], [15.33, 0.0, -52.8213], [15.0915, 0.0, -52.7606], [14.8564, 0.0, -52.688], [14.6251, 0.0, -52.6039], [14.3984, 0.0, -52.5083], [14.1766, 0.0, -52.4015], [13.9605, 0.0, -52.2838], [13.7505, 0.0, -52.1555], [26.7105, 0.0, -55.2632], [21.3577, 0.0, -48.2555], [21.3638, 0.0, -48.0095], [21.3393, 0.0, -48.5009], [21.3087, 0.0, -48.7451], [21.2659, 0.0, -48.9875], [21.2112, 0.0, -49.2274], [21.1445, 0.0, -49.4643], [21.0662, 0.0, -49.6976], [20.9762, 0.0, -49.9266], [20.875, 0.0, -50.151], [20.7628, 0.0, -50.37], [20.6397, 0.0, -50.5831], [20.5062, 0.0, -50.7898], [20.3625, 0.0, -50.9896], [20.2091, 0.0, -51.182], [20.0463, 0.0, -51.3665], [19.8744, 0.0, -51.5427], [19.694, 0.0, -51.7101], [21.0662, 0.0, -46.3215], [19.5055, 0.0, -51.8683], [21.1445, 0.0, -46.5547], [19.3094, 0.0, -52.0169], [21.2112, 0.0, -46.7916], [21.2659, 0.0, -47.0316], [21.3087, 0.0, -47.2739], [21.3393, 0.0, -47.5181], [21.3577, 0.0, -47.7635], [26.7105, 0.0, -66.6904], [32.4211, 0.0, -60.7895], [-40.1196, 3.0, -5.2115], [-39.9409, 3.0, -4.9818], [-39.751, 3.0, -4.7612], [-39.5503, 3.0, -4.5503], [-35.3348, 3.0, -0.6912], [-35.8275, 3.0, -0.9866], [-35.5848, 3.0, -0.8329], [-36.0624, 3.0, -1.152], [-40.714, 3.0, -6.2105], [-40.5842, 3.0, -5.95], [-40.4417, 3.0, -5.6962], [-40.2867, 3.0, -5.4499], [-34.5473, 3.0, -0.3422], [-35.0781, 3.0, -0.5621], [-34.8154, 3.0, -0.4456], [-41.0236, 3.0, -7.0262], [-40.934, 3.0, -6.7493], [-40.8307, 3.0, -6.4772], [-33.9976, 3.0, -0.1754], [-34.2745, 3.0, -0.2521], [-36.5065, 3.0, -1.5165], [-36.2889, 3.0, -1.3288], [-41.2085, 3.0, -7.8789], [-41.161, 3.0, -7.5917], [-41.0994, 3.0, -7.3072], [-33.149, 3.0, -0.0282], [-33.7172, 3.0, -0.1125], [-33.4341, 3.0, -0.0634], [-36.7146, 3.0, -1.7146], [-41.2417, 3.0, -8.168], [-32.8624, 3.0, -0.0071], [-32.5752, 3.0, -0.0], [-41.2298, 3.0, -9.3304], [-41.2544, 3.0, -9.0404], [-41.2646, 3.0, -8.7495], [-41.2604, 3.0, -8.4585], [-41.07, 3.0, -10.1881], [-41.1374, 3.0, -9.905], [-41.1908, 3.0, -9.6189], [-40.9885, 3.0, -10.4676], [-21.9255, 3.0, -9.1038], [-21.9255, 3.0, -3.5345], [5.6569, 3.0, -13.2042], [-5.6569, 3.0, -13.2042], [-0.0, 3.0, -9.1038], [-20.0463, 3.0, -44.6525], [-19.8744, 3.0, -44.4763], [-19.694, 3.0, -44.309], [-20.2091, 3.0, -44.837], [-19.5055, 3.0, -44.1508], [-20.3625, 3.0, -45.0294], [-19.3094, 3.0, -44.0022], [-20.5062, 3.0, -45.2292], [-19.106, 3.0, -43.8635], [-20.6397, 3.0, -45.436], [-18.896, 3.0, -43.7352], [-20.7628, 3.0, -45.6491], [-18.6799, 3.0, -43.6175], [-20.875, 3.0, -45.8681], [-18.4582, 3.0, -43.5108], [-20.9762, 3.0, -46.0924], [-18.2314, 3.0, -43.4152], [-21.0662, 3.0, -46.3215], [-18.0002, 3.0, -43.331], [-17.765, 3.0, -43.2585], [16.4743, 3.0, -9.1399], [-17.5265, 3.0, -43.1977], [22.3077, 3.0, -3.5345], [-17.2853, 3.0, -43.149], [-17.042, 3.0, -43.1123], [-16.7971, 3.0, -43.0878], [-16.5513, 3.0, -43.0755], [-16.3052, 3.0, -43.0755], [-16.0594, 3.0, -43.0878], [-15.8146, 3.0, -43.1123], [-15.5712, 3.0, -43.149], [-15.33, 3.0, -43.1977], [-15.0915, 3.0, -43.2585], [-14.8564, 3.0, -43.331], [-26.7105, 3.0, -55.2632], [-21.2112, 3.0, -49.2274], [-21.1445, 3.0, -49.4643], [-21.2659, 3.0, -48.9875], [-21.3087, 3.0, -48.7451], [-21.3393, 3.0, -48.5009], [-21.3577, 3.0, -48.2555], [-21.3638, 3.0, -48.0095], [-21.3577, 3.0, -47.7635], [-21.3393, 3.0, -47.5181], [-21.3087, 3.0, -47.2739], [-21.2659, 3.0, -47.0316], [-21.2112, 3.0, -46.7916], [-21.1445, 3.0, -46.5547], [-21.0662, 3.0, -49.6976], [-14.6251, 3.0, -43.4152], [-20.9762, 3.0, -49.9266], [-14.3984, 3.0, -43.5108], [-20.875, 3.0, -50.151], [-14.1766, 3.0, -43.6175], [-20.7628, 3.0, -50.37], [-13.9605, 3.0, -43.7352], [-20.6397, 3.0, -50.5831], [-13.7505, 3.0, -43.8635], [-20.5062, 3.0, -50.7898], [-13.5472, 3.0, -44.0022], [-20.3625, 3.0, -50.9896], [-13.351, 3.0, -44.1508], [-20.2091, 3.0, -51.182], [-13.1625, 3.0, -44.309], [-20.0463, 3.0, -51.3665], [-12.9821, 3.0, -44.4763], [-19.8744, 3.0, -51.5427], [-19.694, 3.0, -51.7101], [-19.5055, 3.0, -51.8683], [-19.3094, 3.0, -52.0169], [-19.106, 3.0, -52.1555], [35.0, 3.0, 0.0], [19.0522, 3.0, -18.4636], [-27.6141, 3.0, -65.7466], [-27.6672, 3.0, -65.6993], [-27.7179, 3.0, -65.6494], [-27.5588, 3.0, -65.7913], [-27.3806, 3.0, -65.9082], [-27.4419, 3.0, -65.8722], [-27.5013, 3.0, -65.8332], [-27.2531, 3.0, -65.9711], [-27.3177, 3.0, -65.9412], [-27.1872, 3.0, -65.9978], [-27.0519, 3.0, -66.0413], [-27.1201, 3.0, -66.0212], [-26.9129, 3.0, -66.0713], [-26.9828, 3.0, -66.058], [-26.8425, 3.0, -66.0811], [-26.7007, 3.0, -66.0904], [-26.7717, 3.0, -66.0875], [-26.5586, 3.0, -66.0858], [-26.6296, 3.0, -66.0899], [-26.2792, 3.0, -66.035], [-26.3481, 3.0, -66.0528], [-26.4177, 3.0, -66.0672], [-26.4879, 3.0, -66.0782], [-26.1446, 3.0, -65.9893], [-26.2114, 3.0, -66.0138], [-26.0792, 3.0, -65.9615], [-25.9527, 3.0, -65.8966], [-26.0151, 3.0, -65.9306], [-25.8332, 3.0, -65.8196], [-25.892, 3.0, -65.8595], [-25.7765, 3.0, -65.7767], [-25.6696, 3.0, -65.683], [-25.7219, 3.0, -65.7312], [-28.9439, 3.0, -64.3825], [-29.1102, 3.0, -64.202], [-29.2675, 3.0, -64.0136], [-29.4153, 3.0, -63.8176], [-29.5533, 3.0, -63.6147], [-29.6811, 3.0, -63.4052], [-29.7986, 3.0, -63.1898], [-29.9053, 3.0, -62.9688], [-30.0011, 3.0, -62.7428], [-30.0856, 3.0, -62.5124], [-30.1588, 3.0, -62.2782], [-30.2204, 3.0, -62.0406], [-30.2702, 3.0, -61.8003], [-30.3082, 3.0, -61.5579], [-30.3342, 3.0, -61.3138], [-30.3483, 3.0, -61.0688], [-30.3503, 3.0, -60.8234], [-30.3402, 3.0, -60.5782], [-30.3182, 3.0, -60.3338], [-30.2841, 3.0, -60.0908], [-30.2382, 3.0, -59.8497], [-30.1805, 3.0, -59.6111], [-30.1112, 3.0, -59.3757], [-30.0304, 3.0, -59.144], [-29.9383, 3.0, -58.9165], [-29.8352, 3.0, -58.6938], [-29.7213, 3.0, -58.4764], [-29.5969, 3.0, -58.2649], [-20.6129, 3.0, -60.7895], [-13.9605, 3.0, -52.2838], [-13.7505, 3.0, -52.1555], [-14.1766, 3.0, -52.4015], [-14.3984, 3.0, -52.5083], [-14.6251, 3.0, -52.6039], [-14.8564, 3.0, -52.688], [-15.0915, 3.0, -52.7606], [-15.33, 3.0, -52.8213], [-15.5712, 3.0, -52.8701], [-15.8146, 3.0, -52.9067], [-16.0594, 3.0, -52.9312], [-16.3052, 3.0, -52.9435], [-16.5513, 3.0, -52.9435], [-16.7971, 3.0, -52.9312], [-17.042, 3.0, -52.9067], [-17.2853, 3.0, -52.8701], [-17.5265, 3.0, -52.8213], [-17.765, 3.0, -52.7606], [-18.0002, 3.0, -52.688], [-18.2314, 3.0, -52.6039], [-18.4582, 3.0, -52.5083], [-18.6799, 3.0, -52.4015], [-18.896, 3.0, -52.2838], [-29.4622, 3.0, -58.0598], [-29.3176, 3.0, -57.8615], [-29.1635, 3.0, -57.6705], [-29.0002, 3.0, -57.4873], [-28.828, 3.0, -57.3124], [-2.5595, 3.0, -49.5058], [-11.4989, 3.0, -48.2555], [-11.4928, 3.0, -48.0095], [-11.5173, 3.0, -48.5009], [-11.5479, 3.0, -48.7451], [-11.5906, 3.0, -48.9875], [-11.6454, 3.0, -49.2274], [-11.712, 3.0, -49.4643], [-11.7904, 3.0, -49.6976], [-11.8803, 3.0, -49.9266], [-11.9815, 3.0, -50.151], [-12.8103, 3.0, -44.6525], [-12.0938, 3.0, -50.37], [-12.6474, 3.0, -44.837], [-12.2168, 3.0, -50.5831], [-12.494, 3.0, -45.0294], [-12.3504, 3.0, -50.7898], [-12.3504, 3.0, -45.2292], [-12.494, 3.0, -50.9896], [-12.2168, 3.0, -45.436], [-12.6474, 3.0, -51.182], [-12.0938, 3.0, -45.6491], [-12.8103, 3.0, -51.3665], [-11.9815, 3.0, -45.8681], [-12.9821, 3.0, -51.5427], [-11.8803, 3.0, -46.0924], [-13.1625, 3.0, -51.7101], [-11.7904, 3.0, -46.3215], [-13.351, 3.0, -51.8683], [-11.712, 3.0, -46.5547], [-13.5472, 3.0, -52.0169], [-11.6454, 3.0, -46.7916], [-11.5906, 3.0, -47.0316], [-11.5479, 3.0, -47.2739], [-11.5173, 3.0, -47.5181], [-11.4989, 3.0, -47.7635], [42.0711, 3.0, -7.0711], [2.5595, 3.0, -49.5058], [12.9821, 3.0, -44.4763], [12.8103, 3.0, -44.6525], [13.1625, 3.0, -44.309], [12.6474, 3.0, -44.837], [13.351, 3.0, -44.1508], [12.494, 3.0, -45.0294], [13.5472, 3.0, -44.0022], [12.3504, 3.0, -45.2292], [13.7505, 3.0, -43.8635], [12.2168, 3.0, -45.436], [13.9605, 3.0, -43.7352], [12.0938, 3.0, -45.6491], [14.1766, 3.0, -43.6175], [11.9815, 3.0, -45.8681], [14.3984, 3.0, -43.5108], [11.8803, 3.0, -46.0924], [14.6251, 3.0, -43.4152], [11.7904, 3.0, -46.3215], [14.8564, 3.0, -43.331], [11.712, 3.0, -46.5547], [15.0915, 3.0, -43.2585], [11.6454, 3.0, -46.7916], [15.33, 3.0, -43.1977], [11.5906, 3.0, -47.0316], [15.5712, 3.0, -43.149], [11.5479, 3.0, -47.2739], [15.8146, 3.0, -43.1123], [11.5173, 3.0, -47.5181], [16.0594, 3.0, -43.0878], [11.4989, 3.0, -47.7635], [16.3052, 3.0, -43.0755], [11.4928, 3.0, -48.0095], [16.5513, 3.0, -43.0755], [11.4989, 3.0, -48.2555], [16.7971, 3.0, -43.0878], [11.5173, 3.0, -48.5009], [17.042, 3.0, -43.1123], [11.5479, 3.0, -48.7451], [17.2853, 3.0, -43.149], [11.5906, 3.0, -48.9875], [17.5265, 3.0, -43.1977], [11.6454, 3.0, -49.2274], [17.765, 3.0, -43.2585], [11.712, 3.0, -49.4643], [18.0002, 3.0, -43.331], [11.7904, 3.0, -49.6976], [18.2314, 3.0, -43.4152], [11.8803, 3.0, -49.9266], [18.4582, 3.0, -43.5108], [11.9815, 3.0, -50.151], [18.6799, 3.0, -43.6175], [12.0938, 3.0, -50.37], [18.896, 3.0, -43.7352], [12.2168, 3.0, -50.5831], [19.106, 3.0, -43.8635], [12.3504, 3.0, -50.7898], [19.3094, 3.0, -44.0022], [12.494, 3.0, -50.9896], [19.5055, 3.0, -44.1508], [12.6474, 3.0, -51.182], [19.694, 3.0, -44.309], [12.8103, 3.0, -51.3665], [19.8744, 3.0, -44.4763], [12.9821, 3.0, -51.5427], [20.0463, 3.0, -44.6525], [13.1625, 3.0, -51.7101], [20.2091, 3.0, -44.837], [13.351, 3.0, -51.8683], [20.3625, 3.0, -45.0294], [13.5472, 3.0, -52.0169], [20.5062, 3.0, -45.2292], [13.7505, 3.0, -52.1555], [20.6397, 3.0, -45.436], [20.7628, 3.0, -45.6491], [20.875, 3.0, -45.8681], [20.9762, 3.0, -46.0924], [20.6129, 3.0, -60.7895], [13.9605, 3.0, -52.2838], [14.1766, 3.0, -52.4015], [14.3984, 3.0, -52.5083], [14.6251, 3.0, -52.6039], [14.8564, 3.0, -52.688], [15.0915, 3.0, -52.7606], [15.33, 3.0, -52.8213], [15.5712, 3.0, -52.8701], [15.8146, 3.0, -52.9067], [16.0594, 3.0, -52.9312], [16.3052, 3.0, -52.9435], [16.5513, 3.0, -52.9435], [16.7971, 3.0, -52.9312], [17.042, 3.0, -52.9067], [17.2853, 3.0, -52.8701], [17.5265, 3.0, -52.8213], [17.765, 3.0, -52.7606], [18.0002, 3.0, -52.688], [18.2314, 3.0, -52.6039], [18.4582, 3.0, -52.5083], [18.6799, 3.0, -52.4015], [18.896, 3.0, -52.2838], [19.106, 3.0, -52.1555], [26.7105, 3.0, -55.2632], [21.3638, 3.0, -48.0095], [21.3577, 3.0, -47.7635], [21.3393, 3.0, -47.5181], [21.3087, 3.0, -47.2739], [21.2659, 3.0, -47.0316], [21.2112, 3.0, -46.7916], [21.1445, 3.0, -46.5547], [19.3094, 3.0, -52.0169], [21.0662, 3.0, -46.3215], [19.5055, 3.0, -51.8683], [19.694, 3.0, -51.7101], [19.8744, 3.0, -51.5427], [20.0463, 3.0, -51.3665], [20.2091, 3.0, -51.182], [20.3625, 3.0, -50.9896], [20.5062, 3.0, -50.7898], [20.6397, 3.0, -50.5831], [20.7628, 3.0, -50.37], [20.875, 3.0, -50.151], [20.9762, 3.0, -49.9266], [21.0662, 3.0, -49.6976], [21.1445, 3.0, -49.4643], [21.2112, 3.0, -49.2274], [21.2659, 3.0, -48.9875], [21.3087, 3.0, -48.7451], [21.3393, 3.0, -48.5009], [21.3577, 3.0, -48.2555], [26.7105, 3.0, -66.6904], [32.4211, 3.0, -60.7895], [-0.0, 17.2725, -18.399], [-0.0, 10.6576, -46.7187]], "f": [[0, 1, 2], [2, 1, 3], [4, 5, 6], [6, 5, 7], [8, 9, 10], [11, 12, 13], [13, 12, 5], [8, 14, 9], [1, 14, 8], [12, 15, 5], [14, 16, 17], [18, 19, 15], [19, 20, 15], [5, 20, 7], [15, 20, 5], [16, 21, 22], [14, 21, 16], [1, 21, 14], [23, 24, 25], [25, 24, 20], [21, 26, 27], [27, 26, 28], [1, 26, 21], [0, 26, 1], [0, 29, 26], [0, 30, 29], [31, 32, 33], [33, 32, 34], [34, 32, 35], [36, 37, 32], [24, 38, 20], [32, 38, 35], [37, 38, 32], [35, 38, 24], [20, 39, 7], [38, 39, 20], [7, 39, 0], [0, 40, 30], [39, 40, 0], [30, 40, 41], [39, 42, 43], [43, 44, 39], [39, 45, 42], [44, 46, 39], [39, 47, 45], [46, 48, 39], [39, 49, 47], [39, 50, 40], [48, 50, 39], [39, 51, 49], [50, 52, 40], [39, 53, 51], [52, 54, 40], [39, 55, 53], [54, 56, 40], [39, 57, 55], [56, 58, 40], [39, 59, 57], [58, 60, 40], [60, 61, 40], [61, 62, 40], [41, 63, 30], [62, 64, 40], [64, 65, 40], [65, 66, 40], [66, 67, 40], [67, 68, 40], [68, 69, 40], [69, 70, 40], [70, 71, 40], [71, 72, 40], [40, 72, 73], [72, 74, 73], [74, 75, 73], [76, 77, 78], [79, 77, 76], [80, 77, 79], [81, 77, 80], [82, 77, 81], [83, 77, 82], [84, 77, 83], [85, 77, 84], [86, 77, 85], [87, 77, 86], [88, 77, 87], [89, 77, 88], [59, 77, 89], [39, 77, 59], [77, 90, 78], [75, 91, 73], [77, 92, 90], [91, 93, 73], [77, 94, 92], [93, 95, 73], [77, 96, 94], [95, 97, 73], [77, 98, 96], [97, 99, 73], [77, 100, 98], [99, 101, 73], [77, 102, 100], [101, 103, 73], [77, 104, 102], [103, 105, 73], [77, 106, 104], [77, 107, 106], [77, 108, 107], [77, 109, 108], [77, 110, 109], [77, 111, 110], [63, 112, 30], [73, 113, 114], [115, 116, 117], [116, 118, 117], [119, 120, 121], [121, 120, 118], [122, 123, 120], [118, 123, 117], [120, 123, 118], [123, 124, 117], [125, 126, 124], [124, 126, 117], [127, 128, 126], [128, 129, 126], [129, 130, 126], [131, 130, 129], [130, 132, 126], [133, 134, 135], [135, 134, 132], [132, 136, 126], [134, 136, 132], [137, 138, 136], [138, 139, 136], [139, 140, 136], [140, 141, 136], [142, 143, 141], [141, 143, 136], [143, 144, 136], [136, 145, 126], [144, 145, 136], [146, 147, 145], [145, 147, 126], [117, 147, 148], [148, 147, 149], [149, 147, 150], [150, 147, 151], [151, 147, 152], [152, 147, 153], [153, 147, 154], [154, 147, 155], [155, 147, 156], [156, 147, 157], [157, 147, 158], [158, 147, 159], [159, 147, 160], [160, 147, 161], [161, 147, 162], [162, 147, 163], [163, 147, 164], [164, 147, 165], [165, 147, 166], [166, 147, 167], [167, 147, 168], [168, 147, 169], [169, 147, 170], [170, 147, 171], [171, 147, 172], [172, 147, 173], [173, 147, 174], [174, 147, 175], [126, 147, 117], [176, 177, 178], [179, 177, 176], [180, 177, 179], [181, 177, 180], [182, 177, 181], [183, 177, 182], [184, 177, 183], [185, 177, 184], [186, 177, 185], [187, 177, 186], [188, 177, 187], [189, 177, 188], [190, 177, 189], [191, 177, 190], [192, 177, 191], [193, 177, 192], [194, 177, 193], [195, 177, 194], [77, 177, 111], [196, 177, 195], [197, 177, 196], [198, 177, 197], [199, 177, 198], [200, 177, 199], [111, 177, 200], [175, 177, 201], [201, 177, 202], [202, 177, 203], [203, 177, 204], [204, 177, 205], [205, 177, 77], [147, 177, 175], [113, 206, 63], [63, 206, 112], [207, 208, 105], [209, 210, 207], [211, 210, 209], [207, 210, 208], [105, 212, 73], [208, 212, 105], [211, 213, 210], [212, 214, 73], [215, 216, 211], [211, 216, 213], [73, 217, 113], [214, 217, 73], [218, 219, 215], [220, 219, 218], [215, 219, 216], [217, 221, 113], [222, 223, 220], [220, 223, 219], [221, 224, 113], [222, 225, 223], [224, 226, 113], [227, 228, 222], [222, 228, 225], [226, 229, 113], [230, 231, 227], [227, 231, 228], [229, 232, 113], [230, 233, 231], [234, 233, 230], [235, 233, 234], [232, 236, 113], [235, 237, 233], [236, 238, 113], [239, 240, 235], [235, 240, 237], [238, 241, 113], [242, 243, 239], [239, 243, 240], [241, 244, 113], [245, 246, 242], [242, 246, 243], [244, 247, 113], [248, 249, 245], [245, 249, 246], [247, 250, 113], [248, 251, 249], [252, 251, 248], [250, 253, 113], [252, 254, 251], [255, 254, 252], [253, 256, 113], [257, 258, 255], [259, 258, 257], [255, 258, 254], [256, 260, 113], [259, 261, 258], [262, 261, 259], [260, 263, 113], [262, 264, 261], [263, 265, 113], [262, 266, 264], [267, 266, 262], [265, 268, 113], [267, 269, 266], [270, 269, 267], [268, 271, 113], [272, 273, 270], [274, 273, 272], [270, 273, 269], [271, 275, 113], [274, 276, 273], [275, 277, 113], [278, 279, 274], [274, 279, 276], [277, 280, 113], [281, 282, 278], [278, 282, 279], [280, 283, 113], [284, 285, 281], [281, 285, 282], [283, 286, 113], [287, 288, 284], [289, 288, 287], [284, 288, 285], [286, 290, 113], [289, 291, 288], [290, 292, 113], [293, 294, 289], [289, 294, 291], [292, 295, 113], [296, 297, 293], [298, 297, 296], [293, 297, 294], [295, 299, 113], [298, 300, 297], [301, 300, 298], [299, 302, 113], [303, 304, 301], [301, 304, 300], [302, 305, 113], [303, 306, 304], [305, 307, 113], [303, 308, 306], [309, 308, 303], [178, 308, 309], [113, 310, 206], [307, 310, 113], [178, 311, 308], [310, 312, 206], [312, 313, 206], [313, 314, 206], [314, 315, 206], [315, 316, 206], [177, 317, 178], [318, 317, 319], [320, 317, 318], [321, 317, 320], [322, 317, 321], [323, 317, 322], [324, 317, 323], [325, 317, 324], [326, 317, 325], [327, 317, 326], [178, 317, 311], [328, 317, 327], [329, 317, 328], [330, 317, 329], [331, 317, 330], [332, 317, 331], [333, 317, 332], [334, 317, 333], [335, 317, 334], [336, 317, 335], [337, 317, 336], [338, 317, 337], [339, 317, 338], [340, 317, 339], [341, 317, 340], [311, 317, 341], [316, 342, 206], [343, 342, 344], [345, 342, 343], [346, 342, 345], [347, 342, 346], [348, 342, 347], [349, 342, 348], [350, 342, 349], [351, 342, 350], [352, 342, 351], [353, 342, 352], [354, 342, 353], [355, 342, 354], [356, 342, 355], [357, 342, 356], [317, 342, 319], [358, 342, 357], [359, 342, 358], [360, 342, 359], [361, 342, 316], [362, 342, 360], [363, 342, 361], [364, 342, 362], [365, 342, 363], [319, 342, 364], [366, 342, 365], [367, 342, 366], [368, 342, 367], [369, 342, 368], [344, 342, 369], [342, 370, 371], [317, 370, 342], [372, 373, 374], [372, 374, 375], [376, 377, 378], [376, 379, 377], [380, 381, 382], [380, 382, 383], [380, 383, 372], [384, 385, 386], [387, 380, 372], [387, 388, 389], [387, 389, 380], [387, 372, 375], [390, 379, 376], [390, 376, 385], [390, 384, 391], [390, 385, 384], [390, 392, 393], [390, 393, 379], [394, 395, 396], [394, 396, 387], [397, 390, 398], [397, 398, 399], [397, 392, 390], [397, 400, 392], [401, 387, 375], [401, 394, 387], [402, 400, 397], [403, 400, 402], [404, 405, 406], [404, 406, 407], [404, 407, 401], [408, 401, 375], [408, 404, 401], [408, 409, 410], [408, 410, 404], [411, 408, 375], [411, 375, 400], [412, 411, 400], [412, 400, 403], [412, 403, 413], [414, 415, 416], [417, 411, 418], [419, 418, 411], [420, 411, 417], [421, 419, 411], [422, 411, 420], [423, 421, 411], [424, 411, 422], [425, 411, 412], [425, 423, 411], [426, 411, 424], [427, 425, 412], [428, 411, 426], [429, 427, 412], [430, 411, 428], [431, 429, 412], [432, 411, 430], [433, 431, 412], [434, 411, 432], [435, 433, 412], [436, 435, 412], [437, 414, 416], [438, 436, 412], [439, 413, 403], [440, 438, 412], [441, 440, 412], [442, 441, 412], [443, 442, 412], [443, 412, 415], [444, 443, 415], [445, 444, 415], [446, 445, 415], [447, 446, 415], [448, 447, 415], [449, 448, 415], [450, 449, 415], [451, 411, 434], [451, 452, 453], [451, 454, 452], [451, 455, 454], [451, 456, 455], [451, 457, 456], [451, 458, 457], [451, 459, 458], [451, 460, 459], [451, 461, 460], [451, 462, 461], [451, 463, 462], [451, 464, 463], [451, 434, 464], [465, 451, 453], [466, 450, 415], [467, 451, 465], [468, 466, 415], [469, 451, 467], [470, 468, 415], [471, 451, 469], [472, 470, 415], [473, 451, 471], [474, 472, 415], [475, 451, 473], [476, 474, 415], [477, 451, 475], [478, 476, 415], [479, 451, 477], [480, 478, 415], [481, 451, 479], [482, 480, 415], [483, 451, 481], [484, 451, 483], [485, 451, 484], [486, 451, 485], [487, 451, 486], [488, 439, 403], [489, 414, 437], [490, 491, 492], [493, 490, 492], [494, 495, 496], [494, 496, 493], [497, 493, 492], [497, 498, 494], [497, 494, 493], [499, 497, 492], [500, 501, 499], [500, 499, 492], [502, 503, 500], [504, 502, 500], [505, 506, 504], [505, 504, 500], [507, 508, 505], [509, 510, 511], [509, 511, 512], [509, 512, 507], [513, 514, 509], [515, 507, 505], [515, 509, 507], [515, 513, 509], [516, 517, 515], [516, 515, 505], [518, 519, 516], [518, 516, 505], [520, 505, 500], [520, 518, 505], [521, 522, 520], [521, 500, 492], [521, 492, 523], [521, 520, 500], [521, 523, 524], [521, 524, 525], [521, 525, 526], [521, 526, 527], [521, 527, 528], [521, 528, 529], [521, 529, 530], [521, 530, 531], [521, 531, 532], [521, 532, 533], [521, 533, 534], [521, 534, 535], [521, 535, 536], [521, 536, 537], [521, 537, 538], [521, 538, 539], [521, 539, 540], [521, 540, 541], [521, 541, 542], [521, 542, 543], [521, 543, 544], [521, 544, 545], [521, 545, 546], [521, 546, 547], [521, 547, 548], [521, 548, 549], [521, 549, 550], [551, 552, 553], [551, 554, 552], [551, 555, 554], [551, 556, 555], [551, 557, 556], [551, 558, 557], [551, 559, 558], [551, 560, 559], [551, 561, 560], [551, 562, 561], [551, 563, 562], [551, 564, 563], [551, 451, 487], [551, 565, 564], [551, 566, 565], [551, 567, 566], [551, 568, 567], [551, 569, 568], [551, 570, 569], [551, 571, 570], [551, 572, 571], [551, 573, 572], [551, 574, 573], [551, 487, 574], [551, 550, 575], [551, 575, 576], [551, 576, 577], [551, 577, 578], [551, 578, 579], [551, 579, 451], [551, 521, 550], [580, 482, 415], [580, 581, 582], [580, 583, 581], [580, 584, 583], [580, 585, 584], [580, 586, 585], [580, 587, 586], [580, 588, 587], [580, 589, 588], [580, 590, 589], [580, 591, 482], [580, 592, 590], [580, 593, 591], [580, 594, 592], [580, 595, 593], [580, 596, 594], [580, 597, 595], [580, 598, 596], [580, 599, 597], [580, 600, 598], [580, 601, 599], [580, 602, 600], [580, 603, 601], [580, 604, 602], [580, 605, 603], [580, 606, 604], [580, 607, 605], [580, 608, 606], [580, 609, 607], [580, 610, 608], [580, 611, 609], [580, 553, 610], [580, 612, 611], [580, 613, 612], [580, 614, 613], [580, 615, 614], [580, 582, 615], [580, 551, 553], [616, 439, 488], [616, 489, 439], [617, 551, 580], [618, 617, 414], [619, 617, 618], [620, 618, 414], [621, 617, 619], [622, 620, 414], [623, 617, 621], [624, 622, 414], [625, 617, 623], [626, 624, 414], [627, 617, 625], [628, 626, 414], [629, 617, 627], [630, 414, 489], [630, 628, 414], [631, 617, 629], [632, 630, 489], [633, 617, 631], [634, 632, 489], [635, 617, 633], [636, 634, 489], [637, 617, 635], [638, 636, 489], [639, 617, 637], [640, 638, 489], [641, 617, 639], [642, 640, 489], [643, 617, 641], [644, 642, 489], [645, 617, 643], [646, 644, 489], [647, 617, 645], [648, 646, 489], [649, 617, 647], [650, 648, 489], [651, 617, 649], [652, 650, 489], [653, 617, 651], [654, 652, 489], [655, 617, 653], [656, 654, 489], [657, 617, 655], [658, 656, 489], [659, 617, 657], [660, 658, 489], [661, 617, 659], [662, 660, 489], [663, 617, 661], [664, 662, 489], [665, 617, 663], [666, 664, 489], [667, 617, 665], [668, 666, 489], [669, 617, 667], [670, 668, 489], [671, 617, 669], [672, 670, 489], [673, 617, 671], [674, 672, 489], [675, 617, 673], [676, 674, 489], [677, 617, 675], [678, 676, 489], [679, 617, 677], [680, 678, 489], [681, 617, 679], [682, 680, 489], [683, 617, 681], [684, 682, 489], [685, 617, 683], [686, 489, 616], [686, 684, 489], [687, 617, 685], [688, 686, 616], [689, 617, 687], [690, 688, 616], [691, 690, 616], [692, 691, 616], [693, 692, 616], [694, 617, 689], [694, 689, 695], [694, 695, 696], [694, 696, 697], [694, 697, 698], [694, 698, 699], [694, 699, 700], [694, 700, 701], [694, 701, 702], [694, 702, 703], [694, 703, 704], [694, 704, 705], [694, 705, 706], [694, 706, 707], [694, 707, 708], [694, 708, 709], [694, 709, 710], [694, 710, 711], [694, 711, 712], [694, 712, 713], [694, 713, 714], [694, 714, 715], [694, 715, 716], [694, 716, 717], [694, 551, 617], [718, 693, 616], [718, 694, 717], [718, 719, 720], [718, 720, 721], [718, 721, 722], [718, 722, 723], [718, 723, 724], [718, 724, 725], [718, 717, 726], [718, 725, 727], [718, 726, 728], [718, 727, 693], [718, 728, 729], [718, 729, 730], [718, 730, 731], [718, 731, 732], [718, 732, 733], [718, 733, 734], [718, 734, 735], [718, 735, 736], [718, 736, 737], [718, 737, 738], [718, 738, 739], [718, 739, 740], [718, 740, 741], [718, 741, 742], [718, 742, 743], [718, 743, 744], [718, 744, 745], [718, 745, 719], [746, 718, 747], [746, 694, 718], [412, 416, 415], [718, 616, 342], [342, 616, 206], [747, 718, 371], [371, 718, 342], [746, 747, 370], [370, 747, 371], [694, 746, 317], [317, 746, 370], [694, 317, 551], [551, 317, 177], [147, 551, 177], [521, 551, 147], [115, 117, 492], [115, 492, 491], [116, 491, 490], [116, 115, 491], [118, 490, 493], [118, 116, 490], [121, 493, 496], [121, 118, 493], [119, 496, 495], [119, 121, 496], [120, 495, 494], [120, 119, 495], [122, 494, 498], [122, 120, 494], [123, 122, 498], [123, 498, 497], [124, 123, 497], [124, 499, 501], [124, 497, 499], [125, 124, 501], [126, 125, 501], [126, 501, 500], [127, 126, 500], [127, 503, 502], [127, 500, 503], [128, 127, 502], [129, 128, 502], [129, 502, 504], [131, 129, 504], [131, 504, 506], [130, 131, 506], [130, 506, 505], [132, 130, 505], [132, 505, 508], [135, 132, 508], [135, 507, 512], [135, 508, 507], [133, 512, 511], [133, 135, 512], [134, 133, 511], [136, 510, 509], [136, 511, 510], [136, 134, 511], [137, 509, 514], [137, 136, 509], [138, 137, 514], [139, 514, 513], [139, 138, 514], [140, 513, 515], [140, 139, 513], [141, 515, 517], [141, 140, 515], [142, 516, 519], [142, 517, 516], [142, 141, 517], [143, 142, 519], [144, 519, 518], [144, 143, 519], [145, 518, 520], [145, 144, 518], [146, 520, 522], [146, 145, 520], [147, 522, 521], [147, 146, 522], [492, 117, 148], [523, 492, 148], [204, 205, 579], [204, 579, 578], [203, 578, 577], [203, 204, 578], [202, 577, 576], [202, 203, 577], [201, 576, 575], [201, 202, 576], [175, 575, 550], [175, 201, 575], [174, 550, 549], [174, 175, 550], [173, 549, 548], [173, 174, 549], [172, 173, 548], [172, 548, 547], [171, 172, 547], [171, 547, 546], [170, 171, 546], [170, 546, 545], [169, 170, 545], [169, 545, 544], [168, 169, 544], [168, 544, 543], [167, 168, 543], [167, 542, 541], [167, 543, 542], [166, 167, 541], [165, 166, 541], [165, 541, 540], [164, 165, 540], [164, 540, 539], [163, 164, 539], [163, 539, 538], [162, 163, 538], [162, 538, 537], [161, 537, 536], [161, 162, 537], [160, 536, 535], [160, 161, 536], [159, 160, 535], [159, 535, 534], [158, 533, 532], [158, 534, 533], [158, 159, 534], [157, 158, 532], [156, 532, 531], [156, 157, 532], [155, 531, 530], [155, 156, 531], [154, 529, 528], [154, 530, 529], [154, 155, 530], [153, 154, 528], [152, 528, 527], [152, 153, 528], [151, 527, 526], [151, 152, 527], [150, 526, 525], [150, 151, 526], [149, 525, 524], [149, 150, 525], [148, 524, 523], [148, 149, 524], [451, 205, 77], [451, 579, 205], [411, 77, 39], [411, 451, 77], [6, 7, 375], [6, 375, 374], [4, 374, 373], [4, 6, 374], [5, 372, 383], [5, 373, 372], [5, 4, 373], [13, 5, 383], [11, 383, 382], [11, 13, 383], [12, 382, 381], [12, 11, 382], [15, 381, 380], [15, 12, 381], [18, 389, 388], [18, 380, 389], [18, 15, 380], [19, 18, 388], [20, 388, 387], [20, 19, 388], [25, 387, 396], [25, 20, 387], [23, 396, 395], [23, 25, 396], [24, 23, 395], [24, 394, 401], [24, 395, 394], [35, 24, 401], [34, 35, 401], [34, 401, 407], [33, 34, 407], [33, 407, 406], [31, 33, 406], [31, 405, 404], [31, 406, 405], [32, 31, 404], [36, 404, 410], [36, 32, 404], [37, 36, 410], [37, 410, 409], [38, 409, 408], [38, 37, 409], [39, 408, 411], [39, 38, 408], [400, 7, 0], [400, 375, 7], [29, 30, 403], [29, 403, 402], [26, 402, 397], [26, 29, 402], [28, 397, 399], [28, 26, 397], [27, 398, 390], [27, 399, 398], [27, 28, 399], [21, 27, 390], [22, 390, 391], [22, 21, 390], [16, 391, 384], [16, 22, 391], [17, 384, 386], [17, 16, 384], [14, 386, 385], [14, 17, 386], [9, 385, 376], [9, 14, 385], [10, 376, 378], [10, 9, 376], [8, 377, 379], [8, 378, 377], [8, 10, 378], [1, 8, 379], [3, 379, 393], [3, 1, 379], [2, 393, 392], [2, 3, 393], [0, 392, 400], [0, 2, 392], [112, 488, 403], [112, 403, 30], [616, 112, 206], [616, 488, 112], [748, 415, 414], [414, 617, 749], [748, 414, 749], [749, 617, 580], [749, 415, 748], [749, 580, 415], [582, 581, 255], [255, 581, 257], [257, 583, 259], [259, 583, 262], [581, 583, 257], [583, 584, 262], [262, 585, 267], [267, 585, 270], [584, 585, 262], [270, 586, 272], [585, 586, 270], [586, 587, 272], [272, 588, 274], [587, 588, 272], [274, 589, 278], [278, 589, 281], [588, 589, 274], [589, 590, 281], [281, 592, 284], [590, 592, 281], [592, 594, 284], [284, 594, 287], [594, 596, 287], [287, 596, 289], [596, 598, 289], [289, 598, 293], [598, 600, 293], [293, 600, 296], [600, 602, 296], [296, 602, 298], [602, 604, 298], [298, 604, 301], [604, 606, 301], [301, 606, 303], [606, 608, 303], [303, 608, 309], [608, 610, 309], [309, 610, 178], [610, 553, 178], [178, 553, 176], [176, 553, 179], [553, 552, 179], [552, 554, 179], [179, 554, 180], [180, 554, 181], [554, 555, 181], [181, 556, 182], [182, 556, 183], [555, 556, 181], [556, 557, 183], [183, 558, 184], [557, 558, 183], [184, 559, 185], [185, 559, 186], [558, 559, 184], [186, 560, 187], [559, 560, 186], [560, 561, 187], [187, 562, 188], [188, 562, 189], [561, 562, 187], [562, 563, 189], [189, 564, 190], [190, 564, 191], [563, 564, 189], [564, 565, 191], [191, 566, 192], [192, 566, 193], [565, 566, 191], [566, 567, 193], [567, 568, 193], [193, 568, 194], [568, 569, 194], [194, 569, 195], [569, 570, 195], [195, 570, 196], [570, 571, 196], [196, 571, 197], [571, 572, 197], [197, 572, 198], [198, 572, 199], [572, 573, 199], [573, 574, 199], [199, 574, 200], [574, 487, 200], [200, 487, 111], [487, 486, 111], [111, 486, 110], [486, 485, 110], [110, 485, 109], [485, 484, 109], [109, 484, 108], [484, 483, 108], [108, 483, 107], [483, 481, 107], [107, 481, 106], [481, 479, 106], [106, 479, 104], [479, 477, 104], [104, 477, 102], [477, 475, 102], [102, 475, 100], [475, 473, 100], [100, 473, 98], [473, 471, 98], [98, 471, 96], [471, 469, 96], [96, 469, 94], [469, 467, 94], [94, 467, 92], [467, 465, 92], [92, 465, 90], [465, 453, 90], [90, 453, 78], [78, 452, 76], [453, 452, 78], [76, 454, 79], [452, 454, 76], [79, 455, 80], [454, 455, 79], [80, 456, 81], [455, 456, 80], [456, 457, 81], [81, 457, 82], [457, 458, 82], [82, 458, 83], [458, 459, 83], [83, 459, 84], [459, 460, 84], [84, 460, 85], [460, 461, 85], [85, 461, 86], [461, 462, 86], [86, 462, 87], [462, 463, 87], [87, 463, 88], [463, 464, 88], [88, 464, 89], [464, 434, 89], [89, 434, 59], [434, 432, 59], [59, 432, 57], [432, 430, 57], [57, 430, 55], [430, 428, 55], [55, 428, 53], [428, 426, 53], [53, 426, 51], [51, 424, 49], [426, 424, 51], [49, 422, 47], [424, 422, 49], [47, 420, 45], [422, 420, 47], [45, 417, 42], [420, 417, 45], [42, 418, 43], [417, 418, 42], [43, 419, 44], [418, 419, 43], [44, 421, 46], [419, 421, 44], [46, 423, 48], [421, 423, 46], [48, 425, 50], [423, 425, 48], [50, 427, 52], [425, 427, 50], [52, 429, 54], [427, 429, 52], [54, 431, 56], [429, 431, 54], [56, 433, 58], [431, 433, 56], [433, 435, 58], [58, 435, 60], [435, 436, 60], [60, 436, 61], [436, 438, 61], [61, 438, 62], [438, 440, 62], [62, 440, 64], [64, 441, 65], [440, 441, 64], [65, 442, 66], [66, 442, 67], [441, 442, 65], [442, 443, 67], [67, 444, 68], [443, 444, 67], [68, 445, 69], [444, 445, 68], [69, 446, 70], [445, 446, 69], [70, 447, 71], [446, 447, 70], [71, 448, 72], [72, 448, 74], [447, 448, 71], [448, 449, 74], [74, 450, 75], [449, 450, 74], [75, 466, 91], [450, 466, 75], [91, 468, 93], [93, 468, 95], [466, 468, 91], [468, 470, 95], [95, 472, 97], [470, 472, 95], [97, 474, 99], [472, 474, 97], [99, 476, 101], [101, 476, 103], [474, 476, 99], [476, 478, 103], [103, 480, 105], [105, 480, 207], [478, 480, 103], [480, 482, 207], [207, 591, 209], [482, 591, 207], [591, 593, 209], [209, 593, 211], [593, 595, 211], [211, 595, 215], [595, 597, 215], [215, 597, 218], [597, 599, 218], [218, 599, 220], [599, 601, 220], [220, 601, 222], [601, 603, 222], [222, 603, 227], [603, 605, 227], [227, 605, 230], [605, 607, 230], [230, 607, 234], [607, 609, 234], [234, 609, 235], [609, 611, 235], [235, 611, 239], [611, 612, 239], [239, 612, 242], [612, 613, 242], [242, 613, 245], [245, 614, 248], [613, 614, 245], [614, 615, 248], [248, 615, 252], [252, 582, 255], [615, 582, 252], [719, 745, 344], [344, 745, 343], [343, 744, 345], [745, 744, 343], [345, 743, 346], [744, 743, 345], [346, 742, 347], [743, 742, 346], [347, 741, 348], [742, 741, 347], [348, 740, 349], [741, 740, 348], [349, 739, 350], [740, 739, 349], [350, 738, 351], [739, 738, 350], [351, 737, 352], [738, 737, 351], [352, 736, 353], [737, 736, 352], [736, 735, 353], [353, 735, 354], [735, 734, 354], [354, 734, 355], [734, 733, 355], [355, 733, 356], [733, 732, 356], [356, 732, 357], [732, 731, 357], [357, 731, 358], [731, 730, 358], [358, 730, 359], [730, 729, 359], [359, 729, 360], [729, 728, 360], [360, 728, 362], [728, 726, 362], [362, 726, 364], [726, 717, 364], [364, 717, 319], [717, 716, 319], [319, 716, 318], [716, 715, 318], [318, 715, 320], [320, 714, 321], [715, 714, 320], [321, 713, 322], [714, 713, 321], [322, 712, 323], [713, 712, 322], [323, 711, 324], [712, 711, 323], [324, 710, 325], [711, 710, 324], [325, 709, 326], [710, 709, 325], [326, 708, 327], [709, 708, 326], [327, 707, 328], [708, 707, 327], [328, 706, 329], [707, 706, 328], [329, 705, 330], [706, 705, 329], [330, 704, 331], [705, 704, 330], [331, 703, 332], [704, 703, 331], [332, 702, 333], [703, 702, 332], [333, 701, 334], [702, 701, 333], [701, 700, 334], [334, 700, 335], [700, 699, 335], [335, 699, 336], [699, 698, 336], [336, 698, 337], [698, 697, 337], [337, 697, 338], [697, 696, 338], [338, 696, 339], [696, 695, 339], [339, 695, 340], [695, 689, 340], [340, 689, 341], [689, 687, 341], [341, 687, 311], [687, 685, 311], [311, 685, 308], [685, 683, 308], [308, 683, 306], [683, 681, 306], [306, 681, 304], [681, 679, 304], [304, 679, 300], [679, 677, 300], [300, 677, 297], [677, 675, 297], [297, 675, 294], [675, 673, 294], [294, 673, 291], [673, 671, 291], [291, 671, 288], [671, 669, 288], [288, 669, 285], [669, 667, 285], [285, 667, 282], [667, 665, 282], [282, 665, 279], [665, 663, 279], [279, 663, 276], [663, 661, 276], [276, 661, 273], [273, 659, 269], [661, 659, 273], [269, 657, 266], [659, 657, 269], [266, 655, 264], [657, 655, 266], [264, 653, 261], [655, 653, 264], [653, 651, 261], [261, 651, 258], [651, 649, 258], [258, 649, 254], [649, 647, 254], [254, 647, 251], [647, 645, 251], [251, 645, 249], [645, 643, 249], [249, 643, 246], [643, 641, 246], [246, 641, 243], [641, 639, 243], [243, 639, 240], [639, 637, 240], [240, 637, 237], [637, 635, 237], [237, 635, 233], [635, 633, 233], [233, 633, 231], [633, 631, 231], [231, 631, 228], [631, 629, 228], [228, 629, 225], [223, 627, 219], [629, 627, 225], [225, 627, 223], [627, 625, 219], [219, 623, 216], [625, 623, 219], [216, 621, 213], [623, 621, 216], [213, 619, 210], [210, 619, 208], [621, 619, 213], [619, 618, 208], [208, 620, 212], [618, 620, 208], [212, 622, 214], [214, 622, 217], [620, 622, 212], [622, 624, 217], [217, 626, 221], [624, 626, 217], [221, 628, 224], [626, 628, 221], [224, 630, 226], [628, 630, 224], [226, 632, 229], [229, 632, 232], [630, 632, 226], [632, 634, 232], [634, 636, 232], [232, 636, 236], [236, 636, 238], [636, 638, 238], [238, 638, 241], [638, 640, 241], [241, 642, 244], [640, 642, 241], [244, 644, 247], [642, 644, 244], [247, 646, 250], [644, 646, 247], [250, 648, 253], [646, 648, 250], [253, 650, 256], [648, 650, 253], [256, 652, 260], [260, 652, 263], [650, 652, 256], [652, 654, 263], [263, 656, 265], [654, 656, 263], [265, 658, 268], [268, 658, 271], [656, 658, 265], [658, 660, 271], [271, 662, 275], [660, 662, 271], [275, 664, 277], [662, 664, 275], [277, 666, 280], [664, 666, 277], [280, 668, 283], [666, 668, 280], [283, 670, 286], [668, 670, 283], [286, 672, 290], [670, 672, 286], [290, 674, 292], [672, 674, 290], [292, 676, 295], [674, 676, 292], [295, 678, 299], [299, 678, 302], [676, 678, 295], [678, 680, 302], [302, 682, 305], [305, 682, 307], [680, 682, 302], [682, 684, 307], [684, 686, 307], [307, 686, 310], [686, 688, 310], [310, 688, 312], [688, 690, 312], [312, 690, 313], [690, 691, 313], [313, 691, 314], [691, 692, 314], [314, 692, 315], [315, 692, 316], [692, 693, 316], [693, 727, 316], [316, 727, 361], [727, 725, 361], [361, 725, 363], [725, 724, 363], [363, 724, 365], [724, 723, 365], [365, 723, 366], [723, 722, 366], [366, 722, 367], [722, 721, 367], [367, 721, 368], [368, 720, 369], [721, 720, 368], [369, 719, 344], [720, 719, 369], [437, 73, 114], [437, 416, 73], [40, 73, 412], [73, 416, 412], [40, 412, 41], [41, 412, 413], [439, 63, 413], [413, 63, 41], [63, 489, 113], [439, 489, 63], [113, 437, 114], [489, 437, 113]]} \ No newline at end of file diff --git a/docs/CAD/design/mate-connectors/circularmateconnectors.png b/docs/CAD/design/mate-connectors/circularmateconnectors.png deleted file mode 100644 index 3150a5667b..0000000000 Binary files a/docs/CAD/design/mate-connectors/circularmateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/cmp-sheet.png b/docs/CAD/design/mate-connectors/cmp-sheet.png deleted file mode 100644 index 1d67ae31ed..0000000000 Binary files a/docs/CAD/design/mate-connectors/cmp-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/connector-glyph-proposal.html b/docs/CAD/design/mate-connectors/connector-glyph-proposal.html deleted file mode 100644 index 2a8475ee24..0000000000 --- a/docs/CAD/design/mate-connectors/connector-glyph-proposal.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - -Mate connector glyph — polarity and verse - - - -

- -
-
Orca Design · assembly
-

Mate connector glyph — polarity and verse

-

- Onshape's core (disc + roll quadrant + Z arrow) is adopted unchanged because it is proven and - aligned. The addition is polarity — which connector is anchored and - which one travels — which no surveyed CAD system encodes in its glyph. -

-
- -

The three jobs of the glyph

-
-
-
- - - - -
-
Disc — the XY plane
-

Says “I am a frame, and this is the plane I sit in.” The dot is the exact origin.

-
- -
-
- - - - - -
-
Quadrant — the roll
-

- The filled sector is the +X/+Y quadrant. It steps 90° with the reorient control, so the - clocking that Fastened and Slider lock is visible before you commit. -

-
- -
-
- - - - - - - -
-
Arrow — the verse
-

- Drawn on +Z only. Nothing below the disc. A double-headed axis is what - makes people ask which way it points; a one-sided arrow cannot be misread. -

-
-
- -

Polarity — the part nobody else draws

-
-
-
- - - - - - - - -
-
Fixed — the socket
-

- Hollow head, muted colour. This body does not move. It receives. -

-
- -
-
- - - - - - - -
-
Driven — the plug
-

- Solid head, active colour. This body is the one that jumps. It inserts. -

-
- -
-
- - - - - - - - - - - - -
-
Roll undefined
-

- Hatched quadrant, dashed disc: a circular face or a seam gave no usable direction. Says - “pick a direction” without a dialog. -

-
-
- -

The pair reads as a magnet

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - fixed · receives - driven · inserts - -
-

- Two arrows nose to nose. Because a magnet's north seeks a south, “facing” is the - self-evident default — which settles open decision D1 on visual grounds instead of a - convention nobody can look up. Nothing has to be remembered: the picture is the rule. - The dashed line is what makes the two glyphs read as one object. -

-
- -

States

-
- - - - - - - - - - - - - - - - - - - - - -
StateDrawingWhy
Candidate (hover)small dot onlyOnshape draws plain white dots at every corner and midpoint. Dots propose; the full glyph commits.
Pickeddisc + quadrant + coneThe committed frame, with roll and verse both readable.
Roll undefinedhatched quadrant, dashed discTurns requirement R8 from a message nobody reads into a mark you cannot miss.
-
- -

Constraints on the drawing

-
-

- Do not make it a fourth RGB triad. The bed-centre world triad - (DesignCanvas.cpp:65) and the move gizmo are already three coloured arrows. The disc - and the quadrant are what tell a connector apart from those — keep the arms short, and consider - drawing only Z on the committed glyph, with X and Y implied by the quadrant. -

-
- roll quadrant - Z / driven - fixed - roll undefined -
-
- -
- - diff --git a/docs/CAD/design/mate-connectors/coplanar_test.py b/docs/CAD/design/mate-connectors/coplanar_test.py deleted file mode 100644 index ea02ed3c80..0000000000 --- a/docs/CAD/design/mate-connectors/coplanar_test.py +++ /dev/null @@ -1,68 +0,0 @@ -# Does the connector pair let two hosts sit COPLANAR, or does it hold them apart? -# -# The male's flat back is the plane Y=0 and all its relief rises to +Y. So Y=0 is the natural -# mating datum: everything the male adds lives on one side of it. The test below builds two dummy -# host plates that meet on that plane -- one with the male FUSED on, one with the cavity CUT in -- -# and measures whether they touch, interfere, or stand apart. -# -# It also emits the artifact that makes this work in practice: a CUTTER solid (the male grown by -# the clearance) that you subtract from any host. A standalone female block cannot keep two hosts -# coplanar, because its own floor material stands between them; a cavity can. -# -# Run: /snap/bin/freecad.cmd coplanar_test.py - -import os -import FreeCAD as App -import Part -from FreeCAD import Vector - -HERE = os.path.dirname(os.path.abspath(__file__)) -MALE = os.path.join(HERE, "bear.step") -CLEAR = 0.20 - -male = Part.Shape(); male.read(MALE); male = male.Solids[0] -bb = male.BoundBox -print(f"male relief: Y {bb.YMin:.3f} .. {bb.YMax:.3f} -> datum plane Y=0, all relief on +Y") - -# the flat back face, and proof it is the whole silhouette sitting on Y=0 -back = max((f for f in male.Faces - if abs(f.CenterOfMass.y) < 1e-6 and abs(abs(f.normalAt(0, 0).y) - 1) < 1e-6), - key=lambda f: f.Area) -print(f"back face : {back.Area:.1f} mm2 on Y=0 -- this is the contact surface") - -# ---- the cutter: the male grown by the clearance, poking 0.2 mm proud so the boolean is clean -cutter = male.makeOffsetShape(CLEAR, 1e-6, False, False, 0, 2, False).Solids[0] -cb = cutter.BoundBox -print(f"cutter : Y {cb.YMin:.3f} .. {cb.YMax:.3f}, {cutter.Volume/1000:.2f} cm3") - -# ---- two dummy hosts meeting on Y = 0 -W, H = 120.0, 100.0 -hostA = Part.makeBox(W, 10.0, H, Vector(-W/2, -10.0, -15.0)) # occupies Y -10..0 -hostB = Part.makeBox(W, 30.0, H, Vector(-W/2, 0.0, -15.0)) # occupies Y 0..30 - -partA = hostA.fuse(male) # male stands proud of A's face -partB = hostB.cut(cutter) # cavity sunk into B from its face - -print(f"\npart A (host + male) : {partA.Volume/1000:.2f} cm3") -print(f"part B (host - cutter) : {partB.Volume/1000:.2f} cm3") - -# ---- the question ------------------------------------------------------------------ -inter = partA.common(partB) -iv = inter.Volume if inter.Solids else 0.0 -gap = partA.distToShape(partB)[0] -print(f"\nRESULT interference A vs B : {iv:.6f} mm3 (0 = they do not collide)") -print(f"RESULT closest approach : {gap:.4f} mm (0 = the host faces are touching)") - -# are the two host faces actually on the same plane? -fa = [f for f in partA.Faces if abs(f.CenterOfMass.y) < 1e-9 and abs(abs(f.normalAt(0,0).y)-1) < 1e-6] -fb = [f for f in partB.Faces if abs(f.CenterOfMass.y) < 1e-9 and abs(abs(f.normalAt(0,0).y)-1) < 1e-6] -print(f"RESULT A has {len(fa)} face(s) lying exactly on Y=0, total {sum(f.Area for f in fa):.1f} mm2") -print(f"RESULT B has {len(fb)} face(s) lying exactly on Y=0, total {sum(f.Area for f in fb):.1f} mm2") -print("RESULT -> the hosts meet on Y=0: COPLANAR" if fa and fb and iv < 1e-3 - else "RESULT -> NOT coplanar") - -doc = App.newDocument("Cutter") -o = doc.addObject("Part::Feature", "BearConnector_Cutter"); o.Shape = cutter -doc.recompute() -Part.export([o], os.path.join(HERE, "BearConnector_Cutter.step")) -print(f"\nwrote BearConnector_Cutter.step -- subtract this from any host to get the socket") diff --git a/docs/CAD/design/mate-connectors/cylindricalmateconnectors.png b/docs/CAD/design/mate-connectors/cylindricalmateconnectors.png deleted file mode 100644 index e4c1cebcf9..0000000000 Binary files a/docs/CAD/design/mate-connectors/cylindricalmateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/faceted_ridge_key.scad b/docs/CAD/design/mate-connectors/faceted_ridge_key.scad deleted file mode 100644 index 3eb60064fb..0000000000 --- a/docs/CAD/design/mate-connectors/faceted_ridge_key.scad +++ /dev/null @@ -1,140 +0,0 @@ -// Faceted ridge key — asymmetric male/female alignment feature, flat facets only. -// -// 6 vertices, 7 faces, one closed manifold. Euler check: V - E + F = 6 - 11 + 7 = 2. -// No spheres, no cylinders, no splines, no fillets. -// -// THE FLANKS ARE TRIANGULATED EXPLICITLY, and that is not cosmetic. Written as quads -// [0,3,5,4] and [1,4,5,2] they are NOT planar — the base edge and the ridge edge are -// skew, so the four corners do not share a plane. A checker caught this after the first -// draft claimed the opposite. Left as quads, the tessellator picks the fold direction for -// you, which means the "flat facet" promise is broken by an unspecified crease and two -// exporters can disagree about the shape. Splitting them here fixes the crease at -// back-bottom -> front-ridge, which keeps the rear peak's triangle large and clean. -// -// FRAME CONVENTION (matches the CAD mate connector it is derived from): -// +Z the mating axis — the feature protrudes along it -// +X the roll reference — the ridge runs along it, low end forward -// +Y completes the right-handed frame -// -// WHAT BREAKS WHICH SYMMETRY -// rotational about Z ....... the ridge (elongation along X) -// 180 deg about Z .......... the ridge SLOPE: tall steep back, long shallow front -// mirror across XZ ......... deliberately NOT broken. Handedness is fixed by convention, -// so +Y is implied once Z and X are known. Breaking it would -// add a facet and buy nothing. -// -// KNOWN AMBIGUITY, stated rather than hidden: viewed exactly ALONG the ridge (+/-X, -// orthographic), the silhouette is the same isoceles triangle from front and back. Front -// and back are then distinguished by SHADING only — the long shallow front face catches -// light differently from the steep back face. If the target renderer is flat-shaded with a -// single headlight, verify this case before committing to the shape. - -// ---------------------------------------------------------------- parameters -L = 12.0; // overall length along the ridge (X) -W = 4.0; // half-width at the BACK -tf = 0.45; // front taper: front half-width = W * tf -H = 4.5; // peak height at the rear <-- the single dimension controlling asymmetry -pr = 0.22; // rear ridge position, fraction of L from the back -pf = 0.62; // front ridge position, fraction of L from the back -hf = 0.35; // front ridge height, fraction of H - -// Clearance is a PHYSICAL quantity and only means anything if this is a printed part. -// See the note at the bottom: for a viewport glyph it is meaningless. -clr = 0.20; // per-face clearance, mm -depth = 0.40; // extra pocket depth so the male never bottoms out before it seats - -Wf = W * tf; -xr0 = -L/2 + L * pr; -xr1 = -L/2 + L * pf; -Hf = H * hf; - -// ---------------------------------------------------------------- geometry -// Vertex order is fixed and referenced by the face table; do not reorder. -// 0 back-left 1 back-right 2 front-right 3 front-left -// 4 REAR PEAK (tall) 5 front ridge (low) -function ridge_pts(l, w, wf, h, hfr, x0, x1) = [ - [-l/2, -w, 0 ], // 0 - [-l/2, w, 0 ], // 1 - [ l/2, wf, 0 ], // 2 - [ l/2, -wf, 0 ], // 3 - [ x0, 0, h ], // 4 rear peak - [ x1, 0, hfr] // 5 front ridge, low -]; - -// OpenSCAD wants each face wound CLOCKWISE seen from OUTSIDE. The right-hand-rule -// outward-normal (CCW) form is given in the comment for anyone porting to STL/OCC, -// where the opposite convention is the usual one. -RIDGE_FACES = [ - [3, 2, 1, 0], // base (CCW-outward: [0,1,2,3]) planar, all z=0 - [1, 4, 0], // back (CCW-outward: [0,4,1]) steep - [5, 3, 0], // flank -Y a (CCW-outward: [0,3,5]) - [4, 5, 0], // flank -Y b (CCW-outward: [0,5,4]) - [5, 4, 1], // flank +Y a (CCW-outward: [1,4,5]) - [2, 5, 1], // flank +Y b (CCW-outward: [1,5,2]) - [5, 2, 3] // front (CCW-outward: [3,2,5]) long, shallow -]; - -module ridge_key(l = L, w = W, wf = Wf, h = H, hfr = Hf, x0 = xr0, x1 = xr1) { - polyhedron(points = ridge_pts(l, w, wf, h, hfr, x0, x1), - faces = RIDGE_FACES, - convexity = 3); -} - -// MALE: the protrusion, nominal size. -module ridge_key_male() { ridge_key(); } - -// FEMALE: the pocket. Grown by `clr` on every side and sunk `depth` deeper. -// -// HONEST LIMITATION: this grows the key by scaling its defining dimensions, which is NOT a -// true uniform surface offset — on the shallow front face the normal clearance comes out -// smaller than `clr`, because that face is far from perpendicular to every axis it is -// scaled along. A true offset needs minkowski() with a small cube, which is exact and slow, -// or an explicit per-face plane push, which is exact and fiddly. For a keying feature whose -// job is angular registration rather than a press fit, the approximation is the right trade -// — but do not quote this pocket as holding 0.2 mm everywhere, because it does not. -module ridge_key_female() { - translate([0, 0, -depth]) - ridge_key(l = L + 2*clr, - w = W + clr, - wf = Wf + clr, - h = H + clr + depth, - hfr = Hf + clr + depth, - x0 = xr0, - x1 = xr1); -} - -// ---------------------------------------------------------------- demo -// Left: the male key on its plate. Right: the plate with the pocket cut. -PLATE = [30, 18, 3]; - -module plate_with_male() { - translate([-PLATE[0]/2, -PLATE[1]/2, -PLATE[2]]) cube(PLATE); - ridge_key_male(); -} - -module plate_with_female() { - difference() { - translate([-PLATE[0]/2, -PLATE[1]/2, -PLATE[2]]) cube(PLATE); - ridge_key_female(); - } -} - -translate([-20, 0, 0]) plate_with_male(); -translate([ 20, 0, 0]) plate_with_female(); - -// ---------------------------------------------------------------- note on the two readings -// This file is written for the PHYSICAL reading: a printable alignment key, where `clr` and -// `depth` are real millimetres and flat facets genuinely help — they slice without the -// stair-stepping a tessellated curve produces, and they print without support on the -// shallow front face. -// -// If the intent is instead the VIEWPORT GLYPH for a CAD mate connector, then: -// - `clr` and `depth` are meaningless: a symbol does not mate with anything; -// - all dimensions must become SCREEN PIXELS scaled by upp = 1/zoom, because every gizmo -// in that viewport is screen-constant and must not shrink with the model; -// - "low-poly for rendering performance" is not a real reason at ~2-20 glyphs per frame. -// The real reason to keep flat facets there is LEGIBILITY: hard normals give distinct -// value steps between facets, and that is what lets a 22-px solid read as an oriented -// object instead of a grey blob. -// The vertex logic above is identical under both readings. Only the units and the clearance -// change. diff --git a/docs/CAD/design/mate-connectors/fem-0.png b/docs/CAD/design/mate-connectors/fem-0.png deleted file mode 100644 index 391881e72a..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-1.png b/docs/CAD/design/mate-connectors/fem-1.png deleted file mode 100644 index c329d20bea..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-2.png b/docs/CAD/design/mate-connectors/fem-2.png deleted file mode 100644 index a32f2ffbf1..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-2.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-3.png b/docs/CAD/design/mate-connectors/fem-3.png deleted file mode 100644 index f21ae3f98b..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-3.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-sheet.png b/docs/CAD/design/mate-connectors/fem-sheet.png deleted file mode 100644 index add56590a1..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-sheet2.png b/docs/CAD/design/mate-connectors/fem-sheet2.png deleted file mode 100644 index 879b4295fb..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-sheet2.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/female.stl b/docs/CAD/design/mate-connectors/female.stl deleted file mode 100644 index 57b0ef6d20..0000000000 --- a/docs/CAD/design/mate-connectors/female.stl +++ /dev/null @@ -1,226 +0,0 @@ -solid OpenSCAD_Model - facet normal 1 -0 0 - outer loop - vertex 15 -9 0 - vertex 15 9 -8 - vertex 15 9 0 - endloop - endfacet - facet normal 1 0 0 - outer loop - vertex 15 9 -8 - vertex 15 -9 0 - vertex 15 -9 -8 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 15 9 0 - vertex 5.3246 1.63218 0 - vertex 15 -9 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 15 9 0 - vertex -4.79494 3.42759 0 - vertex 5.3246 1.63218 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 15 9 0 - vertex -5.97725 3.87059 0 - vertex -4.79494 3.42759 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -5.97725 3.87059 0 - vertex -15 9 0 - vertex -5.97725 -3.87059 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex -15 9 0 - vertex -5.97725 3.87059 0 - vertex 15 9 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex 5.3246 -1.63218 0 - vertex 15 -9 0 - vertex 5.3246 1.63218 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex -4.79494 -3.42759 0 - vertex 15 -9 0 - vertex 5.3246 -1.63218 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex -5.97725 -3.87059 0 - vertex 15 -9 0 - vertex -4.79494 -3.42759 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -5.97725 -3.87059 0 - vertex -15 -9 0 - vertex 15 -9 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -15 -9 0 - vertex -5.97725 -3.87059 0 - vertex -15 9 0 - endloop - endfacet - facet normal 0 0 -1 - outer loop - vertex -15 -9 -8 - vertex 15 9 -8 - vertex 15 -9 -8 - endloop - endfacet - facet normal -0 0 -1 - outer loop - vertex 15 9 -8 - vertex -15 -9 -8 - vertex -15 9 -8 - endloop - endfacet - facet normal -1 0 0 - outer loop - vertex -15 -9 -8 - vertex -15 9 0 - vertex -15 9 -8 - endloop - endfacet - facet normal -1 -0 0 - outer loop - vertex -15 9 0 - vertex -15 -9 -8 - vertex -15 -9 0 - endloop - endfacet - facet normal 0 1 -0 - outer loop - vertex 15 9 -8 - vertex -15 9 0 - vertex 15 9 0 - endloop - endfacet - facet normal 0 1 0 - outer loop - vertex -15 9 0 - vertex 15 9 -8 - vertex -15 9 -8 - endloop - endfacet - facet normal 0 -1 0 - outer loop - vertex -15 -9 -8 - vertex 15 -9 0 - vertex -15 -9 0 - endloop - endfacet - facet normal 0 -1 -0 - outer loop - vertex 15 -9 0 - vertex -15 -9 -8 - vertex 15 -9 -8 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -6.2 4.2 -0.4 - vertex 6.2 -2 -0.4 - vertex 6.2 2 -0.4 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 6.2 -2 -0.4 - vertex -6.2 4.2 -0.4 - vertex -6.2 -4.2 -0.4 - endloop - endfacet - facet normal 0.873667 0 -0.486524 - outer loop - vertex -5.97725 -3.87059 0 - vertex -6.2 4.2 -0.4 - vertex -5.97725 3.87059 0 - endloop - endfacet - facet normal 0.873667 0 -0.486524 - outer loop - vertex -6.2 4.2 -0.4 - vertex -5.97725 -3.87059 0 - vertex -6.2 -4.2 -0.4 - endloop - endfacet - facet normal -0.107146 0.603912 -0.789816 - outer loop - vertex 6.2 -2 -0.4 - vertex -4.79494 -3.42759 0 - vertex 5.3246 -1.63218 0 - endloop - endfacet - facet normal -0.107147 0.603918 -0.789812 - outer loop - vertex -4.79494 -3.42759 0 - vertex 6.2 -2 -0.4 - vertex -6.2 -4.2 -0.4 - endloop - endfacet - facet normal -0.304068 0.811519 -0.498978 - outer loop - vertex -4.79494 -3.42759 0 - vertex -6.2 -4.2 -0.4 - vertex -5.97725 -3.87059 0 - endloop - endfacet - facet normal -0.304068 -0.811519 -0.498978 - outer loop - vertex -5.97725 3.87059 0 - vertex -6.2 4.2 -0.4 - vertex -4.79494 3.42759 0 - endloop - endfacet - facet normal -0.107146 -0.603912 -0.789816 - outer loop - vertex -4.79494 3.42759 0 - vertex 6.2 2 -0.4 - vertex 5.3246 1.63218 0 - endloop - endfacet - facet normal -0.107147 -0.603918 -0.789812 - outer loop - vertex 6.2 2 -0.4 - vertex -4.79494 3.42759 0 - vertex -6.2 4.2 -0.4 - endloop - endfacet - facet normal -0.415603 0 -0.909546 - outer loop - vertex 5.3246 -1.63218 0 - vertex 6.2 2 -0.4 - vertex 6.2 -2 -0.4 - endloop - endfacet - facet normal -0.415603 0 -0.909546 - outer loop - vertex 6.2 2 -0.4 - vertex 5.3246 -1.63218 0 - vertex 5.3246 1.63218 0 - endloop - endfacet -endsolid OpenSCAD_Model diff --git a/docs/CAD/design/mate-connectors/female_only.scad b/docs/CAD/design/mate-connectors/female_only.scad deleted file mode 100644 index 89f83b4655..0000000000 --- a/docs/CAD/design/mate-connectors/female_only.scad +++ /dev/null @@ -1,12 +0,0 @@ -// Female half alone, for the legibility test: is a recessed faceted pocket readable in a -// shaded view, or does a concave feature just read as a dark hole with no orientation? -use - -// The plate must be THICKER than the key is tall, or the "pocket" is a through-hole. The -// first version used 3 mm against a 4.5 mm key and cut straight through — caught only by -// rendering it. Minimum stock = H + clearance + pocket depth + a wall to print against. -PLATE = [30, 18, 8]; -difference() { - translate([-PLATE[0]/2, -PLATE[1]/2, -PLATE[2]]) cube(PLATE); - ridge_key_female(); -} diff --git a/docs/CAD/design/mate-connectors/fit_check.py b/docs/CAD/design/mate-connectors/fit_check.py deleted file mode 100644 index 5a9ee01063..0000000000 --- a/docs/CAD/design/mate-connectors/fit_check.py +++ /dev/null @@ -1,20 +0,0 @@ -# Measure the assembled fit between the supplied male and the generated female. -# This is the number that matters: the minimum gap in the seated position. -# Run: /snap/bin/freecad.cmd fit_check.py -import os -import Part - -HERE = os.path.dirname(os.path.abspath(__file__)) -male = Part.Shape(); male.read(os.path.join(HERE, "bear.step")) -fem = Part.Shape(); fem.read(os.path.join(HERE, "BearConnector_Female.step")) -male, fem = male.Solids[0], fem.Solids[0] - -d = male.distToShape(fem) -print(f"RESULT minimum gap male<->female, seated: {d[0]:.4f} mm (design clearance 0.20)") - -c = male.common(fem) -print(f"RESULT interference volume: {(c.Volume if c.Solids else 0.0):.6f} mm3") - -p = d[1][0][0] -print(f"RESULT tightest point on the male: ({p.x:.2f}, {p.y:.2f}, {p.z:.2f})") -print(f"RESULT male {male.Volume/1000:.2f} cm3 / female {fem.Volume/1000:.2f} cm3") diff --git a/docs/CAD/design/mate-connectors/glyph-preview.png b/docs/CAD/design/mate-connectors/glyph-preview.png deleted file mode 100644 index 5e62c9a17f..0000000000 Binary files a/docs/CAD/design/mate-connectors/glyph-preview.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/glyph_preview.py b/docs/CAD/design/mate-connectors/glyph_preview.py deleted file mode 100644 index e339e6bdab..0000000000 --- a/docs/CAD/design/mate-connectors/glyph_preview.py +++ /dev/null @@ -1,99 +0,0 @@ -"""Render the SIMPLIFIED glyph exactly as render_mate_face() draws it — x0kd. - -This is the panel the study was missing. simplify_study.py measured a FLAT outline and -relief_sheet.py measured the FULL 1508-facet part; neither showed the simplified glyph WITH its -relief, which is what the code actually draws and the only thing that answers "is the snout still -protruding". Same facet list, same painter order, same camera-fixed lambert as the C++. -""" -import math, os -from PIL import Image, ImageDraw - -HERE = os.path.dirname(os.path.abspath(__file__)) -T = open(os.path.join(HERE, "bear_glyph_table.h")).read() -def grab(name, n): - body = T.split(name + "[] = {")[1].split("};")[0] - body = "\n".join(l.split("//")[0] for l in body.splitlines()) - out = [] - for tok in body.replace("\n", " ").split("},"): - tok = tok.strip().lstrip("{").strip() - if not tok: continue - v = [float(x) for x in tok.replace("{", "").split(",")[:n]] - if len(v) == n: out.append(tuple(v)) - return out -OUT = grab("kBearOutline", 2) -CHIN = grab("kBearChin", 2) # NB: this table entry is the CHIN BAR, not the snout -MARKS = grab("kBearMarks", 3) -CREST = grab("kBearCrest", 3) -SBASE = grab("kBearSnoutBase", 2) -PLATE = float(T.split("kBearPlateZ = ")[1].split(";")[0]) - - -def facets(): - F = [] - n = len(OUT) - for i in range(n): # plate sides -> the grazing silhouette - a, b = OUT[i], OUT[(i+1) % n] - F.append(([(a[0],a[1],0.0),(b[0],b[1],0.0),(b[0],b[1],PLATE),(a[0],a[1],PLATE)], "body", True)) - F.append(([(x,y,PLATE) for x,y in OUT], "body", True)) # plate top - zm = PLATE + 0.004 - for cx,cy,r in MARKS: # eyes + cheek dot - F.append(([(cx+r*math.cos(2*math.pi*i/12), cy+r*math.sin(2*math.pi*i/12), zm) for i in range(12)], "mark", False)) - F.append(([(x,y,zm) for x,y in CHIN], "mark", False)) # chin bar - A, B = CREST # THE MUZZLE: base quad + crest - nl=(SBASE[0][0],SBASE[0][1],PLATE); nr=(SBASE[1][0],SBASE[1][1],PLATE) - tr=(SBASE[2][0],SBASE[2][1],PLATE); tl=(SBASE[3][0],SBASE[3][1],PLATE) - F += [([nl,tl,B,A],"body",True), # left flank - ([nr,A,B,tr],"body",True), # right flank - ([nl,A,nr],"body",True), # nose cap, sloping because the base overhangs the crest - ([tr,B,tl],"body",True)] # tail cap - return F -FACETS = facets() - -BODY=(0.42,0.46,0.52); MARK=(0.126,0.138,0.156) -def render(px, elev_deg, ss=8): - S=px*ss; a=math.radians(elev_deg); ca,sa=math.cos(a),math.sin(a) - # camera orbits down; the connector's +Z (relief) tips toward the horizon - xf=lambda p:(p[0], p[1]*sa + p[2]*ca, -p[1]*ca + p[2]*sa) - light=(-0.70,0.30,0.45) - img=Image.new("RGB",(S,S),(24,27,32)); d=ImageDraw.Draw(img) - tris=[] - for pts,kind,shade in FACETS: - q=[xf(p) for p in pts] - tris.append((sum(v[2] for v in q)/len(q), q, kind, shade)) - tris.sort(key=lambda t:t[0]) # far first - for _,q,kind,shade in tris: - (x0,y0,z0),(x1,y1,z1),(x2,y2,z2)=q[0],q[1],q[2] - ux,uy,uz=x1-x0,y1-y0,z1-z0; vx,vy,vz=x2-x0,y2-y0,z2-z0 - nx,ny,nz=uy*vz-uz*vy, uz*vx-ux*vz, ux*vy-uy*vx - nn=math.sqrt(nx*nx+ny*ny+nz*nz) or 1.0 - nx,ny,nz=nx/nn,ny/nn,nz/nn - if nz<0: nx,ny,nz=-nx,-ny,-nz - base=BODY if kind=="body" else MARK - k=(0.42+0.58*max(0.0,nx*light[0]+ny*light[1]+nz*light[2])) if shade else 1.0 - col=tuple(min(255,int(255*c*k)) for c in base) - d.polygon([(S/2+p[0]*S*0.92, S/2-p[1]*S*0.92) for p in q], fill=col) - return img.resize((px,px), Image.LANCZOS) - -SIZES=[22,32,48]; ELEVS=[(90,"flat on"),(47,"47"),(16,"16"),(6,"6")] -pad,cell=8,58 -W=pad+len(SIZES)*len(ELEVS)*cell+pad; H=pad+cell+pad -sheet=Image.new("RGB",(W,H),(24,27,32)) -for ci,(e,_) in enumerate(ELEVS): - for si,px in enumerate(SIZES): - g=render(px,e) - sheet.paste(g, (pad+(ci*len(SIZES)+si)*cell+(cell-px)//2, pad+(cell-px)//2)) -sheet.resize((W*2,H*2), Image.NEAREST).save(os.path.join(HERE,"glyph-preview.png")) - -# how much of the glyph is the snout: render with and without the tent and diff -def render_no_tent(px, elev): - global FACETS - keep=FACETS; FACETS=FACETS[:-4] - try: return render(px, elev) - finally: FACETS=keep -print(f"{'elev':>8} {'lit px@32':>10} {'snout px':>9} {'snout share':>12}") -for e,_ in ELEVS: - a=render(32,e); b=render_no_tent(32,e) - la=sum(1 for p in a.get_flattened_data() if p!=(24,27,32)) - diff=sum(1 for p,q in zip(a.get_flattened_data(), b.get_flattened_data()) if p!=q) - print(f"{e:>8} {la:>10} {diff:>9} {100.0*diff/max(1,la):>11.1f}%") -print("WROTE glyph-preview.png") diff --git a/docs/CAD/design/mate-connectors/glyph_probe.py b/docs/CAD/design/mate-connectors/glyph_probe.py deleted file mode 100644 index f4d48fdd6c..0000000000 --- a/docs/CAD/design/mate-connectors/glyph_probe.py +++ /dev/null @@ -1,143 +0,0 @@ -# Mate-connector glyph probe — built as REAL solids on REAL mechanical geometry, -# so the shape can be judged in a 3D viewport instead of in a browser mock. -# -# Four polarity treatments, side by side on one bracket: -# A Onshape baseline ...... ring + roll quadrant + three short axis arms -# B solid cone ............ ring + quadrant + one-sided Z arrow, filled head (driven) -# C hollow collar ......... ring + quadrant + one-sided Z arrow, shell head (fixed) -# D pin / cup ............. polarity by RELIEF: a raised pin vs a sunk cup -# -# D is the one that only a 3D test can settle: in a shaded viewport, solid-vs-hollow is a -# weak cue that depends on angle and lighting, while convex-vs-concave is a strong one -- -# and male/female is the mechanical language for polarity anyway. -# -# Scale note: in the real viewport gizmos are screen-constant (~15-40 px via upp = 1/zoom). -# At a zoom where a 60 mm part fills ~600 px, 40 px is about 4 mm, so R = 4.5 mm here. - -import FreeCAD as App -import FreeCADGui as Gui -import Part -from FreeCAD import Vector - -DOC = "GlyphProbe" -for d in list(App.listDocuments()): - App.closeDocument(d) -doc = App.newDocument(DOC) - -R = 4.5 # disc radius, the module everything scales from -GOLD = (0.93, 0.66, 0.09) -BLUE = (0.18, 0.44, 0.93) -GREY = (0.42, 0.46, 0.52) -RED = (0.85, 0.29, 0.24) -GREEN = (0.23, 0.65, 0.35) - -def add(name, shape, color, transparency=0): - o = doc.addObject("Part::Feature", name) - o.Shape = shape - o.ViewObject.ShapeColor = color - o.ViewObject.LineColor = color - o.ViewObject.PointColor = color - o.ViewObject.Transparency = transparency - return o - -def frame(origin, zdir, xdir): - """Right-handed placement matrix from origin + Z + X (X orthonormalised against Z).""" - z = Vector(*zdir); z.normalize() - xr = Vector(*xdir) - x = xr.sub(Vector(z).multiply(z.dot(xr))); x.normalize() - y = z.cross(x) - return App.Matrix(x.x, y.x, z.x, origin[0], - x.y, y.y, z.y, origin[1], - x.z, y.z, z.z, origin[2], - 0, 0, 0, 1) - -# ---------------------------------------------------------------- the bracket -plate = Part.makeBox(120, 46, 8) -bore = Part.makeCylinder(7, 40, Vector(96, 23, -6)) # a real bore, curved face -boss = Part.makeCylinder(11, 7, Vector(96, 23, 8)) -part = plate.fuse(boss).cut(bore) -add("Bracket", part, (0.60, 0.63, 0.66)) - -# ---------------------------------------------------------------- glyph pieces -def ring(t=None): - t = t or R * 0.10 - return Part.makeCylinder(R, t).cut(Part.makeCylinder(R * 0.84, t)) - -def quadrant(t=None): - t = t or R * 0.10 - return Part.makeCylinder(R * 0.84, t, Vector(0, 0, 0), Vector(0, 0, 1), 90) - -def stem(L=None, r=None): - return Part.makeCylinder(r or R * 0.09, L or R * 2.3) - -def solid_head(): - return Part.makeCone(R * 0.32, 0, R * 0.80, Vector(0, 0, R * 2.3)) - -def shell_head(): - outer = Part.makeCone(R * 0.32, 0, R * 0.80, Vector(0, 0, R * 2.3)) - inner = Part.makeCone(R * 0.22, 0, R * 0.62, Vector(0, 0, R * 2.3)) - return outer.cut(inner) - -def short_axis(direction, L=None): - L = L or R * 1.15 - return Part.makeCylinder(R * 0.07, L, Vector(0, 0, 0), Vector(*direction)) - -def place(shape, m): - s = shape.copy() - s.transformShape(m) - return s - -# ---------------------------------------------------------------- the variants -def variant_A(tag, origin): # Onshape baseline - m = frame(origin, (0, 0, 1), (1, 0, 0)) - add(tag + "_ring", place(ring(), m), GREY) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_x", place(short_axis((1, 0, 0)), m), RED) - add(tag + "_y", place(short_axis((0, 1, 0)), m), GREEN) - add(tag + "_z", place(short_axis((0, 0, 1), R * 1.6), m), BLUE) - -def variant_B(tag, origin, zdir=(0, 0, 1)): # solid cone = driven - m = frame(origin, zdir, (1, 0, 0)) - add(tag + "_ring", place(ring(), m), BLUE) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_body", place(stem().fuse(solid_head()), m), BLUE) - -def variant_C(tag, origin, zdir=(0, 0, 1)): # hollow collar = fixed - m = frame(origin, zdir, (1, 0, 0)) - add(tag + "_ring", place(ring(), m), GREY) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_body", place(stem().fuse(shell_head()), m), GREY) - -def variant_D_pin(tag, origin, zdir=(0, 0, 1)): # polarity by relief: raised PIN - m = frame(origin, zdir, (1, 0, 0)) - pin = Part.makeCylinder(R * 0.30, R * 1.5).fuse( - Part.makeCone(R * 0.30, 0, R * 0.55, Vector(0, 0, R * 1.5))) - add(tag + "_ring", place(ring(), m), BLUE) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_pin", place(pin, m), BLUE) - -def variant_D_cup(tag, origin, zdir=(0, 0, 1)): # polarity by relief: sunk CUP - m = frame(origin, zdir, (1, 0, 0)) - cup = Part.makeCylinder(R * 0.62, R * 0.9).cut( - Part.makeCylinder(R * 0.40, R * 0.9, Vector(0, 0, -0.01))) - add(tag + "_ring", place(ring(), m), GREY) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_cup", place(cup, m), GREY) - -# four treatments across the plate, all on the same flat face, same Z -variant_A("A", (14, 30, 8)) -variant_B("B", (40, 30, 8)) -variant_C("C", (64, 30, 8)) -variant_D_pin("Dpin", (14, 10, 8)) -variant_D_cup("Dcup", (40, 10, 8)) - -# the hard cases, which is the whole reason for doing this in 3D: -variant_B("Bore", (96, 23, 15)) # on the boss above a bore -variant_B("Edge", (64, 0, 8), (0, -0.7071, 0.7071)) # tilted, on an edge, oblique Z - -doc.recompute() - -v = Gui.activeDocument().activeView() -v.viewIsometric() -Gui.SendMsgToActiveView("ViewFit") -App.Console.PrintMessage("glyph probe built: %d objects\n" % len(doc.Objects)) diff --git a/docs/CAD/design/mate-connectors/handedness-sheet.png b/docs/CAD/design/mate-connectors/handedness-sheet.png deleted file mode 100644 index b44c370328..0000000000 Binary files a/docs/CAD/design/mate-connectors/handedness-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/handedness.py b/docs/CAD/design/mate-connectors/handedness.py deleted file mode 100644 index 68fa07bb55..0000000000 --- a/docs/CAD/design/mate-connectors/handedness.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Give the bear a handedness mark that survives rasterisation — wi3z, Tommaso's call 2. - -The study showed the left/right cue lives in sub-millimetre corner radii and is therefore invisible -at glyph size: one pixel is 2.6 mm at 32 px. Roll and verse are safe; handedness is not. - -THE MEASURE IS THE QUESTION ITSELF. Render the glyph, render its mirror image, and count how many -pixels differ. If a human is to tell left from right, the two must differ on screen; a candidate -that scores near zero is invisible however elegant it looks in CAD. Reported as a percentage of the -glyph's own lit area, so the sizes are comparable. -""" -import json, math, os -from PIL import Image, ImageDraw, ImageChops - -HERE = os.path.dirname(os.path.abspath(__file__)) -D = json.load(open(os.path.join(HERE, "bear_outline.json"))) -def unit(pts): - p = [(x, -z) for x, z in pts] - return p -outer = unit(D["outer"]); holes = [unit(h["pts"]) for h in D["holes"]] -ALL = outer + [p for h in holes for p in h] -xs=[p[0] for p in ALL]; ys=[p[1] for p in ALL] -CX,CY = (min(xs)+max(xs))/2,(min(ys)+max(ys))/2 -SPAN = max(max(xs)-min(xs), max(ys)-min(ys)) -U = lambda pts: [((x-CX)/SPAN,(y-CY)/SPAN) for x,y in pts] -OUT = U(outer) -EYES = [U(h) for h,m in zip(holes, D["holes"]) if m["d"] < 20] -MUZ = U([h for h,m in zip(holes, D["holes"]) if m["d"] >= 20][0]) - -def rdp(pts, eps): - if len(pts) < 3: return pts - ax,ay=pts[0]; bx,by=pts[-1]; dx,dy=bx-ax,by-ay - n=math.hypot(dx,dy); best,bi=-1.0,0 - for i in range(1,len(pts)-1): - px,py=pts[i] - d=abs(dx*(ay-py)-(ax-px)*dy)/n if n>1e-12 else math.hypot(px-ax,py-ay) - if d>best: best,bi=d,i - if best<=eps: return [pts[0],pts[-1]] - return rdp(pts[:bi+1],eps)[:-1]+rdp(pts[bi:],eps) -def simp(pts,eps): - r=rdp(pts+[pts[0]],eps); return r[:-1] - -BASE = simp(OUT, .030) # the 22-vertex outline the study settled on -def centroid(p): return (sum(q[0] for q in p)/len(p), sum(q[1] for q in p)/len(p)) -def circ(cx,cy,r,n=16): return [(cx+r*math.cos(2*math.pi*i/n), cy+r*math.sin(2*math.pi*i/n)) for i in range(n)] -EYE_D = [] -for e in EYES: - c=centroid(e); r=(max(p[0] for p in e)-min(p[0] for p in e))/2 - EYE_D.append((c[0],c[1],r)) -EYE_D.sort() # [0] = left (x<0), [1] = right - -TOP = max(p[1] for p in BASE) -H = TOP - min(p[1] for p in BASE) -def ear_tip(sign): - cands=[p for p in BASE if p[1] > TOP-0.18*H and (p[0]*sign) > 0] - return max(cands, key=lambda p: p[0]*sign) if cands else None -LT, RT = ear_tip(-1), ear_tip(+1) - -def notch(tip, sign, k=0.085): - """A wedge bitten out of one ear — background-filled, exactly how the eyes are already drawn.""" - x,y = tip - return [(x, y+0.02), (x - sign*k, y - k*0.55), (x + sign*k*0.15, y - k*1.05)] - -CANDS = { - "H0 none": dict(cuts=[], eyes=EYE_D), - "H1 notch R ear": dict(cuts=[notch(RT, +1)], eyes=EYE_D), - "H2 notch both": dict(cuts=[notch(RT, +1), notch(LT, -1, 0.045)], eyes=EYE_D), - "H3 cheek dot": dict(cuts=[circ(EYE_D[1][0]+0.085, EYE_D[1][1]-0.10, 0.038)], eyes=EYE_D), - "H4 uneven eyes": dict(cuts=[], eyes=[EYE_D[0], (EYE_D[1][0], EYE_D[1][1], EYE_D[1][2]*1.55)]), -} - -def render(c, px, ss=8, mirror=False): - S=px*ss; img=Image.new("L",(S,S),0); d=ImageDraw.Draw(img) - m = lambda p: (S/2 + (-p[0] if mirror else p[0])*S*0.92, S/2 - p[1]*S*0.92) - d.polygon([m(p) for p in BASE], fill=255) - d.polygon([m(p) for p in MUZ], fill=0) - for cx,cy,r in c["eyes"]: - a=m((cx-r,cy+r)); b=m((cx+r,cy-r)) - d.ellipse([min(a[0],b[0]), min(a[1],b[1]), max(a[0],b[0]), max(a[1],b[1])], fill=0) - for cut in c["cuts"]: - d.polygon([m(p) for p in cut], fill=0) - return img.resize((px,px), Image.LANCZOS) - -SIZES=[22,32,48] -print(f"{'candidate':16} " + " ".join(f"{s}px" for s in SIZES) + " (pixels differing from own mirror, % of lit area)") -print("-"*84) -scores={} -for name,c in CANDS.items(): - row=[] - for px in SIZES: - a=render(c,px); b=render(c,px,mirror=True) - diff=ImageChops.difference(a,b) - nd=sum(1 for v in diff.getdata() if v>40) - lit=sum(1 for v in a.getdata() if v>40) or 1 - row.append(100.0*nd/lit) - scores[name]=row - print(f"{name:16} " + " ".join(f"{v:5.1f}" for v in row)) - -pad,cell=8,58 -W=pad+len(SIZES)*2*cell+pad; Hh=pad+len(CANDS)*cell+pad -sheet=Image.new("RGB",(W,Hh),(24,27,32)) -for r,(name,c) in enumerate(CANDS.items()): - for mi,mir in enumerate((False,True)): - for si,px in enumerate(SIZES): - g=render(c,px,mirror=mir) - tile=Image.new("RGB",(px,px),(24,27,32)) - tile.paste(Image.new("RGB",(px,px),(237,168,23)),(0,0),g) - x=pad+(mi*len(SIZES)+si)*cell+(cell-px)//2 - y=pad+r*cell+(cell-px)//2 - sheet.paste(tile,(x,y)) -sheet.resize((W*2,Hh*2), Image.NEAREST).save(os.path.join(HERE,"handedness-sheet.png")) -print("\nleft block = as drawn, right block = mirrored. rows: " + ", ".join(CANDS)) -print("WROTE handedness-sheet.png") diff --git a/docs/CAD/design/mate-connectors/linearedgemateconnectors.png b/docs/CAD/design/mate-connectors/linearedgemateconnectors.png deleted file mode 100644 index fd5e64190d..0000000000 Binary files a/docs/CAD/design/mate-connectors/linearedgemateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/make_female.py b/docs/CAD/design/mate-connectors/make_female.py deleted file mode 100644 index ccb38426bf..0000000000 --- a/docs/CAD/design/mate-connectors/make_female.py +++ /dev/null @@ -1,135 +0,0 @@ -# Build the complementary FEMALE for BearConnector.step. -# -# Method: take the supplied male B-rep as-is, grow it by a uniform clearance, and subtract that -# from a block. Working on the real solid rather than re-modelling the bear is the whole point — -# the pocket is then exactly complementary by construction, including every deliberate asymmetry. -# -# The offset uses join=2 (Intersection), which extends the adjacent planes and meets them at a -# sharp corner. For a faceted part that is the correct join: the arc join would round every convex -# edge and blunt the very cues the design depends on. -# -# THE MALE'S NATIVE FRAME: the flat back is the plane Y=0 and the relief rises to Y=+17.27. -# X and Z carry the face (83.34 x 66.69). The frame is kept exactly as supplied so that male and -# female drop into the same assembly without anyone having to re-orient one of them. -# Insertion is therefore along +Y, and the pocket must OPEN on the Y=0 plane. -# -# A first version of this script assumed the relief ran along +Z, built the block around the wrong -# axis, and produced a sealed cavity with no way in. It passed a "male does not intersect female" -# check, because that only tests the seated position and says nothing about whether the part can -# get there. The straight-pull test below is what catches it. -# -# Run: /snap/bin/freecad.cmd make_female.py - -import os, sys, math -import FreeCAD as App -import Part - -HERE = os.path.dirname(os.path.abspath(__file__)) -MALE = os.path.join(HERE, "bear.step") -OUT_STEP = os.path.join(HERE, "BearConnector_Female.step") - -CLEAR = 0.20 # per-face clearance, mm -WALL = 4.0 # material around the pocket, mm -FLOOR = 3.0 # material behind the deepest point of the pocket, mm - -male = Part.Shape(); male.read(MALE) -if len(male.Solids) != 1: - print(f"FAIL: expected 1 solid in the male, found {len(male.Solids)}"); sys.exit(1) -male = male.Solids[0] -bb = male.BoundBox -print(f"male : {bb.XLength:.2f} (X) x {bb.YLength:.2f} (Y) x {bb.ZLength:.2f} (Z) mm, " - f"{len(male.Faces)} faces, {male.Volume/1000:.2f} cm3") -print(f" relief runs Y {bb.YMin:.2f} .. {bb.YMax:.2f} -> insertion along +Y, mouth at Y={bb.YMin:.2f}") - -# ---- 1. can the male even be withdrawn along the insertion axis? ---------------------- -# Ray-cast a grid along +Y through the tessellated male and count crossings. A straight pull is -# possible only if no ray enters the solid more than once; a second entry is an undercut. -verts, facets = male.tessellate(0.15) -V = [(v.x, v.y, v.z) for v in verts] -worst, undercut_pts = 0, 0 -NX = NZ = 90 -for i in range(NX): - x = bb.XMin + (i + 0.5) * bb.XLength / NX - for j in range(NZ): - z = bb.ZMin + (j + 0.5) * bb.ZLength / NZ - hits = 0 - for (ia, ib, ic) in facets: # ray (x, *, z) along +Y vs triangle - ax, ay, az = V[ia]; bx, by, bz = V[ib]; cx, cy, cz = V[ic] - # 2D point-in-triangle in the XZ plane - d = (bz - cz) * (ax - cx) + (cx - bx) * (az - cz) - if abs(d) < 1e-12: continue - u = ((bz - cz) * (x - cx) + (cx - bx) * (z - cz)) / d - v = ((cz - az) * (x - cx) + (ax - cx) * (z - cz)) / d - if u < 0 or v < 0 or u + v > 1: continue - hits += 1 - worst = max(worst, hits) - if hits > 2: undercut_pts += 1 -print(f"pull : max crossings along +Y = {worst}, undercut samples = {undercut_pts}/{NX*NZ}") -if undercut_pts: - print("FAIL: the male has an undercut along +Y; a straight pocket cannot release it") - sys.exit(1) -print(" no undercut -> a straight-pull pocket works") - -# ---- 2. grow the male by the clearance ----------------------------------------------- -grown = None -for join, name in ((2, "Intersection"), (1, "Tangent"), (0, "Arc")): - try: - g = male.makeOffsetShape(CLEAR, 1e-6, False, False, 0, join, False) - if g.isValid() and g.Solids: - grown = g.Solids[0]; print(f"offset: join={name}, {grown.Volume/1000:.2f} cm3"); break - except Exception as e: - print(f"offset: join={name} failed -- {e}") -if grown is None: - print("FAIL: could not offset the male; refusing to emit a zero-clearance pocket"); sys.exit(1) - -# ---- 3. the block: walls in X and Z, depth in +Y, OPEN at the Y=0 mouth --------------- -gb = grown.BoundBox -y_mouth = bb.YMin # the male's flat back plane -depth = gb.YMax - y_mouth -block = Part.makeBox(gb.XLength + 2*WALL, depth + FLOOR, gb.ZLength + 2*WALL, - App.Vector(gb.XMin - WALL, y_mouth, gb.ZMin - WALL)) -print(f"block : {gb.XLength + 2*WALL:.2f} x {depth + FLOOR:.2f} x {gb.ZLength + 2*WALL:.2f} mm, " - f"mouth on the Y={y_mouth:.2f} plane") - -female = block.cut(grown) - -# ---- 4. verify -------------------------------------------------------------------------- -ok = True -if not female.isValid(): print("FAIL: invalid shape"); ok = False -if len(female.Solids) != 1: print(f"FAIL: {len(female.Solids)} solids"); ok = False - -clash = male.common(female) -cv = clash.Volume if clash.Solids else 0.0 -print(f"check : male ∩ female = {cv:.6f} mm3 (seated fit, must be ~0)") -if cv > 1e-3: print("FAIL: male collides with female"); ok = False - -# the mouth must actually be open: the pocket has to reach the Y=y_mouth face of the block -mouth_face_area = 0.0 -for f in female.Faces: - c = f.CenterOfMass - if abs(c.y - y_mouth) < 1e-6: - mouth_face_area += f.Area -solid_mouth = (gb.XLength + 2*WALL) * (gb.ZLength + 2*WALL) -open_area = solid_mouth - mouth_face_area -print(f"check : mouth plane -- material {mouth_face_area:.1f} mm2, opening {open_area:.1f} mm2 " - f"({100*open_area/solid_mouth:.1f}% of the face)") -if open_area < 100: - print("FAIL: the pocket is sealed -- the male cannot be inserted"); ok = False - -cavity = block.Volume - female.Volume -print(f"check : cavity {cavity/1000:.2f} cm3 vs male {male.Volume/1000:.2f} cm3 " - f"-> clearance shell {(cavity-male.Volume)/1000:.2f} cm3") -if cavity < male.Volume: print("FAIL: cavity smaller than the male"); ok = False - -if not ok: - print("\nREFUSING to write the STEP"); sys.exit(1) - -doc = App.newDocument("Female") -obj = doc.addObject("Part::Feature", "BearConnector_Female") -obj.Shape = female -doc.recompute() -Part.export([obj], OUT_STEP) -fb = female.BoundBox -print(f"\nwrote {OUT_STEP}") -print(f"female: {fb.XLength:.2f} x {fb.YLength:.2f} x {fb.ZLength:.2f} mm, " - f"{len(female.Faces)} faces, {female.Volume/1000:.2f} cm3") diff --git a/docs/CAD/design/mate-connectors/mate-connector-virtual-sharp.png b/docs/CAD/design/mate-connectors/mate-connector-virtual-sharp.png deleted file mode 100644 index f9a80c1e10..0000000000 Binary files a/docs/CAD/design/mate-connectors/mate-connector-virtual-sharp.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/mateconnector-planarcentroid.png b/docs/CAD/design/mate-connectors/mateconnector-planarcentroid.png deleted file mode 100644 index 16ca1c01e6..0000000000 Binary files a/docs/CAD/design/mate-connectors/mateconnector-planarcentroid.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/mateconnector-planarpoints.png b/docs/CAD/design/mate-connectors/mateconnector-planarpoints.png deleted file mode 100644 index d952ddc1f0..0000000000 Binary files a/docs/CAD/design/mate-connectors/mateconnector-planarpoints.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/matepointiconLG.png b/docs/CAD/design/mate-connectors/matepointiconLG.png deleted file mode 100644 index 2f3022d116..0000000000 Binary files a/docs/CAD/design/mate-connectors/matepointiconLG.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/matepointreorientsecondaryaxis.png b/docs/CAD/design/mate-connectors/matepointreorientsecondaryaxis.png deleted file mode 100644 index bd65a9f40e..0000000000 Binary files a/docs/CAD/design/mate-connectors/matepointreorientsecondaryaxis.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/muzzle_variants.py b/docs/CAD/design/mate-connectors/muzzle_variants.py deleted file mode 100644 index f4c9ab33b5..0000000000 --- a/docs/CAD/design/mate-connectors/muzzle_variants.py +++ /dev/null @@ -1,71 +0,0 @@ -"""The muzzle has to READ, not just be present — wi3z. - -Faithfully scaled, the part's ridge is 11.3 mm on an 83 mm face: 13.6 % of the width. At glyph -size that is a scratch. A glyph is a symbol, not a scale model, so the question is how much -emphasis it takes before the only +Z feature actually reads. Variants, all with the same crest -geometry, differing only in width and colour. -""" -import math, os, importlib.util -from PIL import Image, ImageDraw -spec=importlib.util.spec_from_file_location("gp","glyph_preview.py") -gp=importlib.util.module_from_spec(spec); spec.loader.exec_module(gp) - -OUT, CHIN, MARKS, CREST, SBASE, PLATE = gp.OUT, gp.CHIN, gp.MARKS, gp.CREST, gp.SBASE, gp.PLATE -BODY=(0.42,0.46,0.52); MARK=(0.126,0.138,0.156); GOLD=(0.93,0.66,0.09) - -def facets(widen=1.0, muzzle_gold=False): - F=[]; n=len(OUT) - for i in range(n): - a,b=OUT[i],OUT[(i+1)%n] - F.append(([(a[0],a[1],0.0),(b[0],b[1],0.0),(b[0],b[1],PLATE),(a[0],a[1],PLATE)],BODY,True)) - F.append(([(x,y,PLATE) for x,y in OUT],BODY,True)) - zm=PLATE+0.004 - for cx,cy,r in MARKS: - F.append(([(cx+r*math.cos(2*math.pi*i/12),cy+r*math.sin(2*math.pi*i/12),zm) for i in range(12)],MARK,False)) - F.append(([(x,y,zm) for x,y in CHIN],MARK,False)) - A,B=CREST - w=lambda p:(p[0]*widen,p[1],PLATE) - nl,nr,tr,tl=(w(SBASE[0]),w(SBASE[1]),w(SBASE[2]),w(SBASE[3])) - col = GOLD if muzzle_gold else BODY - F+=[([nl,tl,B,A],col,True),([nr,A,B,tr],col,True), - ([nl,A,nr],col,True), ([tr,B,tl],col,True)] - return F - -def render(F, px, elev, ss=8): - S=px*ss; a=math.radians(elev); ca,sa=math.cos(a),math.sin(a) - xf=lambda p:(p[0],p[1]*sa+p[2]*ca,-p[1]*ca+p[2]*sa) - light=(-0.70,0.30,0.45) - img=Image.new("RGB",(S,S),(24,27,32)); d=ImageDraw.Draw(img) - tris=sorted(((sum(v[2] for v in [xf(q) for q in pts])/len(pts),[xf(q) for q in pts],c,sh) - for pts,c,sh in F), key=lambda t:t[0]) - for _,q,base,shade in tris: - (x0,y0,z0),(x1,y1,z1),(x2,y2,z2)=q[0],q[1],q[2] - ux,uy,uz=x1-x0,y1-y0,z1-z0; vx,vy,vz=x2-x0,y2-y0,z2-z0 - nx,ny,nz=uy*vz-uz*vy,uz*vx-ux*vz,ux*vy-uy*vx - L=math.sqrt(nx*nx+ny*ny+nz*nz) or 1.0; nx,ny,nz=nx/L,ny/L,nz/L - if nz<0: nx,ny,nz=-nx,-ny,-nz - k=(0.42+0.58*max(0.0,nx*light[0]+ny*light[1]+nz*light[2])) if shade else 1.0 - d.polygon([(S/2+p[0]*S*0.92,S/2-p[1]*S*0.92) for p in q], - fill=tuple(min(255,int(255*c*k)) for c in base)) - return img.resize((px,px),Image.LANCZOS) - -VAR=[("V1 faithful", 1.0, False), - ("V2 gold muzzle", 1.0, True), - ("V3 gold + 1.8x wide",1.8, True), - ("V4 body + 1.8x wide",1.8, False)] -big=Image.new("RGB",(4*250+30,4*140+30),(24,27,32)) -for r,(name,wd,gold) in enumerate(VAR): - F=facets(wd,gold) - for c,e in enumerate((90,47,16,6)): - big.paste(render(F,120,e),(15+c*250+60,15+r*140+10)) -big.save("/tmp/muzzle-variants.png") -for name,wd,gold in VAR: - F=facets(wd,gold); F0=[f for f in F][:-4] - row=[] - for e in (90,16,6): - a=render(F,32,e); b=render(F0,32,e) - la=sum(1 for p in a.get_flattened_data() if p!=(24,27,32)) - df=sum(1 for p,q in zip(a.get_flattened_data(),b.get_flattened_data()) if p!=q) - row.append(f"{100.0*df/max(1,la):5.1f}%") - print(f"{name:22} muzzle share at 90/16/6 deg: " + " ".join(row)) -print("WROTE /tmp/muzzle-variants.png") diff --git a/docs/CAD/design/mate-connectors/planarfacemateconnectors.png b/docs/CAD/design/mate-connectors/planarfacemateconnectors.png deleted file mode 100644 index 9fea27ab2b..0000000000 Binary files a/docs/CAD/design/mate-connectors/planarfacemateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/relief-sheet.png b/docs/CAD/design/mate-connectors/relief-sheet.png deleted file mode 100644 index 0c6d0d11f0..0000000000 Binary files a/docs/CAD/design/mate-connectors/relief-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/relief_sheet.py b/docs/CAD/design/mate-connectors/relief_sheet.py deleted file mode 100644 index 4b8bc6aa74..0000000000 --- a/docs/CAD/design/mate-connectors/relief_sheet.py +++ /dev/null @@ -1,99 +0,0 @@ -"""Flat glyph vs 3D relief, at the elevations that killed the disc — wi3z. - -The flat study collapsed at 16 deg because anything drawn IN the connector's plane foreshortens by -sin(elevation). This renders the SAME bear as its real relief (1508 facets off the supplied male) -with a simple lambert shade, so the silhouette does the work at a grazing angle. Two rows, same -sizes, same elevations, so the comparison is direct. -""" -import json, math, os -from PIL import Image, ImageDraw - -HERE = os.path.dirname(os.path.abspath(__file__)) -M = json.load(open(os.path.join(HERE, "bear_mesh.json"))) -V, F = M["v"], M["f"] - -# Part frame: face carried by X (right) and Z (down-negative), relief along +Y. -P = [(v[0], -v[2], v[1]) for v in V] # -> (x right, y up, z out of the face) -xs=[p[0] for p in P]; ys=[p[1] for p in P]; zs=[p[2] for p in P] -CX,CY,CZ = (min(xs)+max(xs))/2, (min(ys)+max(ys))/2, (min(zs)+max(zs))/2 -SPAN = max(max(xs)-min(xs), max(ys)-min(ys)) -P = [((x-CX)/SPAN, (y-CY)/SPAN, (z-CZ)/SPAN) for x,y,z in P] - -def shade(px, elev_deg, supersample=8): - """Camera orbits down from straight-on (90) to grazing (small). Rotate about the screen x-axis.""" - S = px*supersample - a = math.radians(elev_deg) - ca, sa = math.cos(a), math.sin(a) - # view: rotate the model so the face normal tips away from the camera - def xf(p): - x,y,z = p - return (x, y*sa + z*ca, -y*ca + z*sa) # third component = depth toward camera - Q = [xf(p) for p in P] - img = Image.new("L", (S,S), 0) - d = ImageDraw.Draw(img) - order = [] - for tri in F: - a3 = [Q[i] for i in tri] - order.append((sum(v[2] for v in a3)/3.0, tri, a3)) - order.sort(key=lambda t: t[0]) # painter: far first - light = (-0.35, 0.55, 0.76) - for _, tri, a3 in order: - (x0,y0,z0),(x1,y1,z1),(x2,y2,z2) = a3 - ux,uy,uz = x1-x0, y1-y0, z1-z0 - vx,vy,vz = x2-x0, y2-y0, z2-z0 - nx,ny,nz = uy*vz-uz*vy, uz*vx-ux*vz, ux*vy-uy*vx - n = math.sqrt(nx*nx+ny*ny+nz*nz) or 1.0 - nx,ny,nz = nx/n, ny/n, nz/n - if nz < 0: nx,ny,nz = -nx,-ny,-nz # face the camera - lam = max(0.0, nx*light[0] + ny*light[1] + nz*light[2]) - val = int(70 + 185*lam) - pts = [(S/2 + x*S*0.92, S/2 - y*S*0.92) for x,y,_ in a3] - d.polygon(pts, fill=val) - return img.resize((px,px), Image.LANCZOS) - -# flat outline, for the side-by-side -D = json.load(open(os.path.join(HERE, "bear_outline.json"))) -def unit(pts): - p=[(x,-z) for x,z in pts] - return [((x-CX)/SPAN,(y-CY)/SPAN) for x,y in p] -OUT = unit(D["outer"]) -HOLES = [unit(h["pts"]) for h in D["holes"]] - -def flat(px, elev_deg, supersample=8): - S=px*supersample - img=Image.new("L",(S,S),0); d=ImageDraw.Draw(img) - k=math.sin(math.radians(elev_deg)) - m=lambda p:(S/2+p[0]*S*0.92, S/2-p[1]*S*0.92*k) - d.polygon([m(p) for p in OUT], fill=255) - for h in HOLES: d.polygon([m(p) for p in h], fill=0) - return img.resize((px,px), Image.LANCZOS) - -SIZES=[22,32,48]; ELEVS=[(90,"flat on"),(47,"47"),(16,"16"),(6,"6")] -pad,cell=8,58 -W=pad+len(SIZES)*len(ELEVS)*cell+pad; H=pad+2*cell+pad -sheet=Image.new("RGB",(W,H),(24,27,32)) -for r,fn in enumerate((flat, shade)): - for ci,(elev,_) in enumerate(ELEVS): - for si,px in enumerate(SIZES): - g=fn(px,elev) - tile=Image.new("RGB",(px,px),(24,27,32)) - if fn is flat: - tile.paste(Image.new("RGB",(px,px),(237,168,23)),(0,0),g) - else: - gg=g.convert("L") - tile=Image.merge("RGB",(gg.point(lambda v:min(255,int(v*1.00))), - gg.point(lambda v:int(v*0.71)), - gg.point(lambda v:int(v*0.16)))) - x=pad+(ci*len(SIZES)+si)*cell+(cell-px)//2 - y=pad+r*cell+(cell-px)//2 - sheet.paste(tile,(x,y)) -sheet.resize((W*2,H*2), Image.NEAREST).save(os.path.join(HERE,"relief-sheet.png")) - -# how much ink survives — the same measure used on the disc glyph -print(f"{'elev':>6} {'flat px@32':>11} {'relief px@32':>13}") -for elev,_ in ELEVS: - f32=flat(32,elev); s32=shade(32,elev) - fi=sum(1 for v in f32.getdata() if v>40) - si=sum(1 for v in s32.getdata() if v>40) - print(f"{elev:>6} {fi:>11} {si:>13}") -print("WROTE relief-sheet.png") diff --git a/docs/CAD/design/mate-connectors/relief_test.py b/docs/CAD/design/mate-connectors/relief_test.py deleted file mode 100644 index 3fb83b2a8e..0000000000 --- a/docs/CAD/design/mate-connectors/relief_test.py +++ /dev/null @@ -1,9 +0,0 @@ -# Export the real male's relief as a triangle mesh, so the grazing test uses the actual geometry. -import os, json -import Part -HERE = os.path.dirname(os.path.abspath(__file__)) -s = Part.Shape(); s.read(os.path.join(HERE, "bear.step")) -verts, facets = s.Solids[0].tessellate(0.25) -V = [[round(p.x,4), round(p.y,4), round(p.z,4)] for p in verts] -json.dump({"v": V, "f": facets}, open(os.path.join(HERE, "bear_mesh.json"), "w")) -print(f"verts {len(V)} facets {len(facets)}") diff --git a/docs/CAD/design/mate-connectors/render_key.py b/docs/CAD/design/mate-connectors/render_key.py deleted file mode 100644 index eb4bcdbd99..0000000000 --- a/docs/CAD/design/mate-connectors/render_key.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -"""Flat-shade the faceted ridge key from several camera directions. - -The point is not a pretty picture. It is one question: does a low-poly solid, flat-shaded, -let a human read its orientation from an arbitrary viewpoint -- and specifically, is the -view ALONG the ridge ambiguous between front and back, as the geometry suggests it must be -in silhouette? - -Flat shading (one normal per facet, no smoothing) is deliberate: it is what the concept -claims to rely on, and it is what a CAD viewport with hard normals actually produces. -""" -import numpy as np -from PIL import Image, ImageDraw - -# ---- the key, same numbers as faceted_ridge_key.scad -L, W, tf, H, pr, pf, hf = 12.0, 4.0, 0.45, 4.5, 0.22, 0.62, 0.35 -Wf, xr0, xr1, Hf = W * tf, -L / 2 + L * pr, -L / 2 + L * pf, H * hf - -V = np.array([(-L/2, -W, 0), (-L/2, W, 0), (L/2, Wf, 0), (L/2, -Wf, 0), - (xr0, 0, H), (xr1, 0, Hf)], dtype=float) -F = [[0, 1, 2, 3], [0, 4, 1], [0, 3, 5], [0, 5, 4], [1, 4, 5], [1, 5, 2], [3, 2, 5]] - -LIGHT = np.array([0.35, -0.5, 0.78]) # a headlight-ish key light -LIGHT /= np.linalg.norm(LIGHT) - - -def look_at(eye, target, up=(0, 0, 1)): - f = np.array(target, float) - np.array(eye, float) - f /= np.linalg.norm(f) - up = np.array(up, float) - if abs(np.dot(f, up)) > 0.999: - up = np.array([0, 1, 0], float) - r = np.cross(f, up); r /= np.linalg.norm(r) - u = np.cross(r, f) - return r, u, f - - -def render(eye, target, path, size=(620, 460), scale=26.0, label=""): - r, u, f = look_at(eye, target) - eye = np.array(eye, float) - cam = np.stack([r, u, f]) # world -> camera rows - P = (V - eye) @ cam.T # orthographic: x,y screen, z depth - - w, h = size - img = Image.new("RGB", size, (238, 240, 243)) - d = ImageDraw.Draw(img) - - def to_px(p): - return (w / 2 + p[0] * scale, h / 2 - p[1] * scale) - - faces = [] - for face in F: - pts = V[face] - n = np.cross(pts[1] - pts[0], pts[2] - pts[0]) - n /= np.linalg.norm(n) - centre = pts.mean(axis=0) - if np.dot(n, centre - eye) > 0: # back-face cull - continue - depth = P[face][:, 2].mean() - lam = max(0.0, float(np.dot(n, LIGHT))) - shade = 0.22 + 0.78 * lam # flat: ONE value for the whole facet - col = tuple(int(255 * shade * c) for c in (0.86, 0.72, 0.35)) - faces.append((depth, [to_px(P[i]) for i in face], col)) - - for _, poly, col in sorted(faces, key=lambda t: -t[0]): # painter's algorithm - d.polygon(poly, fill=col) - - if label: - d.rectangle([8, 8, 8 + 9 * len(label), 30], fill=(255, 255, 255)) - d.text((14, 14), label, fill=(20, 20, 20)) - img.save(path) - return path - - -if __name__ == "__main__": - t = (0, 0, H * 0.35) - views = [ - ((26, -22, 20), "iso: the reference view"), - ((30, 0, 6), "ALONG +X (from the FRONT, low end)"), - ((-30, 0, 6), "ALONG -X (from the BACK, tall end)"), - ((0, 0, 34), "ALONG +Z (straight down the mating axis)"), - ((2, -32, 5), "ALONG -Y (broadside, grazing)"), - ] - for i, (eye, lab) in enumerate(views): - print(render(eye, t, f"rk-{i}.png", label=lab)) diff --git a/docs/CAD/design/mate-connectors/render_stl.py b/docs/CAD/design/mate-connectors/render_stl.py deleted file mode 100644 index 16ad0e92a9..0000000000 --- a/docs/CAD/design/mate-connectors/render_stl.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -"""Flat-shade an ASCII/binary STL from several directions. - -Used to answer one question with a picture instead of an argument: does a RECESSED faceted -pocket read as an oriented feature, or does a concave feature collapse into a dark hole? -""" -import struct -import sys -import numpy as np -from PIL import Image, ImageDraw - -LIGHT = np.array([0.35, -0.5, 0.78]); LIGHT /= np.linalg.norm(LIGHT) - - -def load_stl(path): - data = open(path, "rb").read() - if data[:5] == b"solid" and b"facet" in data[:2000]: - tris, cur = [], [] - for line in data.decode("ascii", "ignore").splitlines(): - s = line.split() - if s and s[0] == "vertex": - cur.append([float(x) for x in s[1:4]]) - if len(cur) == 3: - tris.append(cur); cur = [] - return np.array(tris, dtype=float) - n = struct.unpack(" 0.999: up = np.array([0, 1.0, 0]) - r = np.cross(f, up); r /= np.linalg.norm(r) - u = np.cross(r, f) - cam = np.stack([r, u, f]) - - w, h = size - img = Image.new("RGB", size, (238, 240, 243)); d = ImageDraw.Draw(img) - faces = [] - for t in tris: - n = np.cross(t[1] - t[0], t[2] - t[0]) - ln = np.linalg.norm(n) - if ln < 1e-12: continue - n /= ln - c = t.mean(axis=0) - if np.dot(n, c - eye) > 0: continue # cull back faces - P = (t - eye) @ cam.T - lam = max(0.0, float(np.dot(n, LIGHT))) - shade = 0.20 + 0.80 * lam - col = tuple(int(255 * shade * ch) for ch in (0.86, 0.72, 0.35)) - poly = [(w / 2 + p[0] * scale, h / 2 - p[1] * scale) for p in P] - faces.append((P[:, 2].mean(), poly, col)) - for _, poly, col in sorted(faces, key=lambda x: -x[0]): - d.polygon(poly, fill=col) - if label: - d.rectangle([8, 8, 8 + 9 * len(label), 30], fill=(255, 255, 255)) - d.text((14, 14), label, fill=(20, 20, 20)) - img.save(path) - - -if __name__ == "__main__": - tris = load_stl(sys.argv[1]) - print("triangles:", len(tris)) - views = [((26, -22, 20), "iso"), ((0, 0, 34), "straight down +Z"), - ((4, -30, 9), "grazing"), ((-28, -10, 12), "from the tall end")] - for i, (eye, lab) in enumerate(views): - render(tris, eye, (0, 0, 0), f"fem-{i}.png", label=f"FEMALE POCKET — {lab}") - print(f"fem-{i}.png") diff --git a/docs/CAD/design/mate-connectors/rk-0.png b/docs/CAD/design/mate-connectors/rk-0.png deleted file mode 100644 index 1d7208238a..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-1.png b/docs/CAD/design/mate-connectors/rk-1.png deleted file mode 100644 index 282bd0a2fe..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-2.png b/docs/CAD/design/mate-connectors/rk-2.png deleted file mode 100644 index 75d83e1402..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-2.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-3.png b/docs/CAD/design/mate-connectors/rk-3.png deleted file mode 100644 index eccdf94807..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-3.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-4.png b/docs/CAD/design/mate-connectors/rk-4.png deleted file mode 100644 index 794fd4bd97..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-4.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-back.png b/docs/CAD/design/mate-connectors/rk-back.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/CAD/design/mate-connectors/rk-front.png b/docs/CAD/design/mate-connectors/rk-front.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/CAD/design/mate-connectors/rk-iso.png b/docs/CAD/design/mate-connectors/rk-iso.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/CAD/design/mate-connectors/rk-sheet.png b/docs/CAD/design/mate-connectors/rk-sheet.png deleted file mode 100644 index e785a02839..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/simplify-sheet.png b/docs/CAD/design/mate-connectors/simplify-sheet.png deleted file mode 100644 index 9c05180c59..0000000000 Binary files a/docs/CAD/design/mate-connectors/simplify-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/simplify_study.py b/docs/CAD/design/mate-connectors/simplify_study.py deleted file mode 100644 index c0bbcf63ab..0000000000 --- a/docs/CAD/design/mate-connectors/simplify_study.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Reduce the bear face to the fewest marks that still read at glyph size — wi3z. - -Geometry comes from bear_outline.json, which extract_outline.py pulled off the supplied male -B-rep's back plate: the outer wire IS the silhouette, the inner wires are the two eyes and the -muzzle opening. Nothing here is traced by eye. - -The glyph is drawn IN the connector's plane, so a grazing view foreshortens it along one axis by -sin(elevation) — exactly what collapsed the disc's roll quadrant to 3 pixels at 10 deg. Every -candidate is therefore rendered at three elevations as well as three pixel sizes. -""" -import json, math, os -from PIL import Image, ImageDraw - -HERE = os.path.dirname(os.path.abspath(__file__)) -D = json.load(open(os.path.join(HERE, "bear_outline.json"))) - -def norm(pts): - """Part frame (X right, Z down-negative) -> glyph frame (x right, y up), centred, unit height.""" - p = [(x, -z) for x, z in pts] - return p - -outer = norm(D["outer"]) -holes = [norm(h["pts"]) for h in D["holes"]] -# the two Ø9.8 wires are the eyes; the wide one is the muzzle -eyes = [h for h, meta in zip(holes, D["holes"]) if meta["d"] < 20] -muzzle = [h for h, meta in zip(holes, D["holes"]) if meta["d"] >= 20] - -ALL = outer + [p for h in holes for p in h] -xs = [p[0] for p in ALL]; ys = [p[1] for p in ALL] -CX, CY = (min(xs)+max(xs))/2, (min(ys)+max(ys))/2 -SPAN = max(max(xs)-min(xs), max(ys)-min(ys)) -def to_unit(pts): return [((x-CX)/SPAN, (y-CY)/SPAN) for x, y in pts] - -def rdp(pts, eps): - """Douglas-Peucker. Vertex count is the honest measure of 'how simplified'.""" - if len(pts) < 3: return pts - ax, ay = pts[0]; bx, by = pts[-1] - dx, dy = bx-ax, by-ay - n = math.hypot(dx, dy) - best, bi = -1.0, 0 - for i in range(1, len(pts)-1): - px, py = pts[i] - d = abs(dx*(ay-py) - (ax-px)*dy)/n if n > 1e-12 else math.hypot(px-ax, py-ay) - if d > best: best, bi = d, i - if best <= eps: - return [pts[0], pts[-1]] - return rdp(pts[:bi+1], eps)[:-1] + rdp(pts[bi:], eps) - -def simp_closed(pts, eps): - r = rdp(pts + [pts[0]], eps) - return r[:-1] - -def centroid(pts): - return (sum(p[0] for p in pts)/len(pts), sum(p[1] for p in pts)/len(pts)) - -U_OUT = to_unit(outer) -U_EYE = [to_unit(e) for e in eyes] -U_MUZ = [to_unit(m) for m in muzzle] - -def eye_dots(scale=1.0): - out = [] - for e in U_EYE: - cx, cy = centroid(e) - r = max(max(p[0] for p in e)-min(p[0] for p in e), - max(p[1] for p in e)-min(p[1] for p in e))/2*scale - out.append((cx, cy, r)) - return out - -def muzzle_tri(): - """The muzzle reduced to one filled triangle: its two lower corners and its apex.""" - m = U_MUZ[0] - lo = min(p[1] for p in m); hi = max(p[1] for p in m) - bottom = [p for p in m if p[1] < lo + 0.06*(hi-lo)] - apex = max(m, key=lambda p: p[1]) - return [min(bottom), max(bottom), apex] - -CANDIDATES = { - "C0 full": dict(out=U_OUT, eyes=eye_dots(), muz=U_MUZ[0]), - "C1 eps .004": dict(out=simp_closed(U_OUT, .004), eyes=eye_dots(), muz=simp_closed(U_MUZ[0], .004)), - "C2 eps .012": dict(out=simp_closed(U_OUT, .012), eyes=eye_dots(), muz=muzzle_tri()), - "C3 eps .030": dict(out=simp_closed(U_OUT, .030), eyes=eye_dots(1.15), muz=muzzle_tri()), - "C4 no eyes": dict(out=simp_closed(U_OUT, .012), eyes=[], muz=muzzle_tri()), -} - -def sym_report(pts, tol=0.02): - """Trivial symmetry group is the property doing the work. If a simplification restores a - mirror or a 180 deg rotation, that simplification is wrong.""" - def match(tf): - t = [tf(p) for p in pts] - hit = 0 - for q in t: - if min(math.hypot(q[0]-p[0], q[1]-p[1]) for p in pts) <= tol: hit += 1 - return hit, len(pts) - return { - "mirror-x": match(lambda p: (-p[0], p[1])), - "mirror-y": match(lambda p: ( p[0], -p[1])), - "rot-180": match(lambda p: (-p[0], -p[1])), - } - -def render(c, px, elev_deg, supersample=8): - S = px*supersample - img = Image.new("L", (S, S), 0) - d = ImageDraw.Draw(img) - k = math.sin(math.radians(elev_deg)) - def m(p): - return (S/2 + p[0]*S*0.92, S/2 - p[1]*S*0.92*k) - d.polygon([m(p) for p in c["out"]], fill=255) - if c["muz"]: d.polygon([m(p) for p in c["muz"]], fill=0) - for cx, cy, r in c["eyes"]: - a = m((cx-r, cy+r)); b = m((cx+r, cy-r)) - d.ellipse([a[0], a[1], b[0], b[1]], fill=0) - return img.resize((px, px), Image.LANCZOS) - -print(f"{'candidate':14} {'verts':>6} {'marks':>6} symmetry (matched/total, lower is better)") -print("-"*78) -for name, c in CANDIDATES.items(): - s = sym_report(c["out"]) - marks = 1 + (1 if c["muz"] else 0) + len(c["eyes"]) - sym = " ".join(f"{k} {v[0]}/{v[1]}" for k, v in s.items()) - print(f"{name:14} {len(c['out']):6} {marks:6} {sym}") - -SIZES = [22, 32, 48] -ELEVS = [(90, "flat on"), (47, "47 deg"), (16, "16 deg"), (6, "6 deg")] -pad, cell = 8, 56 -W = pad + len(SIZES)*len(ELEVS)*cell + pad -H = pad + len(CANDIDATES)*cell + pad -sheet = Image.new("RGB", (W, H), (24, 27, 32)) -for r, (name, c) in enumerate(CANDIDATES.items()): - for ci, (elev, _) in enumerate(ELEVS): - for si, px in enumerate(SIZES): - g = render(c, px, elev) - tile = Image.new("RGB", (px, px), (24, 27, 32)) - gold = Image.new("RGB", (px, px), (237, 168, 23)) - tile.paste(gold, (0, 0), g) - x = pad + (ci*len(SIZES)+si)*cell + (cell-px)//2 - y = pad + r*cell + (cell-px)//2 - sheet.paste(tile, (x, y)) -sheet = sheet.resize((W*2, H*2), Image.NEAREST) -sheet.save(os.path.join(HERE, "simplify-sheet.png")) -print("\ncolumns: " + " | ".join(f"{e[1]} @ 22/32/48px" for e in ELEVS)) -print("rows: " + ", ".join(CANDIDATES)) -print("WROTE simplify-sheet.png") diff --git a/docs/CAD/design/mate-connectors/size-test.png b/docs/CAD/design/mate-connectors/size-test.png deleted file mode 100644 index 941f76ffb8..0000000000 Binary files a/docs/CAD/design/mate-connectors/size-test.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-22-down+Z.png b/docs/CAD/design/mate-connectors/sz-22-down+Z.png deleted file mode 100644 index 85cbf9ba4e..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-22-down+Z.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-22-grazing.png b/docs/CAD/design/mate-connectors/sz-22-grazing.png deleted file mode 100644 index 047f2c6e06..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-22-grazing.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-22-iso.png b/docs/CAD/design/mate-connectors/sz-22-iso.png deleted file mode 100644 index 55b8a13eed..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-22-iso.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-32-down+Z.png b/docs/CAD/design/mate-connectors/sz-32-down+Z.png deleted file mode 100644 index 683fc3d0aa..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-32-down+Z.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-32-grazing.png b/docs/CAD/design/mate-connectors/sz-32-grazing.png deleted file mode 100644 index 92e17ca09a..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-32-grazing.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-32-iso.png b/docs/CAD/design/mate-connectors/sz-32-iso.png deleted file mode 100644 index 1fe0ccb091..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-32-iso.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-48-down+Z.png b/docs/CAD/design/mate-connectors/sz-48-down+Z.png deleted file mode 100644 index ec451714ff..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-48-down+Z.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-48-grazing.png b/docs/CAD/design/mate-connectors/sz-48-grazing.png deleted file mode 100644 index 524c8e5343..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-48-grazing.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-48-iso.png b/docs/CAD/design/mate-connectors/sz-48-iso.png deleted file mode 100644 index e0ed208b64..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-48-iso.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+0.1-0.png b/docs/CAD/design/mate-connectors/t-+0.1-0.png deleted file mode 100644 index b0c09ef253..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+0.1-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+0.1-1.png b/docs/CAD/design/mate-connectors/t-+0.1-1.png deleted file mode 100644 index 782cd16c0d..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+0.1-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+1.6-0.png b/docs/CAD/design/mate-connectors/t-+1.6-0.png deleted file mode 100644 index f3b37f6697..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+1.6-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+1.6-1.png b/docs/CAD/design/mate-connectors/t-+1.6-1.png deleted file mode 100644 index 731e092769..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+1.6-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/trim-cmp.png b/docs/CAD/design/mate-connectors/trim-cmp.png deleted file mode 100644 index 8dcc0c973f..0000000000 Binary files a/docs/CAD/design/mate-connectors/trim-cmp.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/trim_female.py b/docs/CAD/design/mate-connectors/trim_female.py deleted file mode 100644 index 2753e4a3a8..0000000000 --- a/docs/CAD/design/mate-connectors/trim_female.py +++ /dev/null @@ -1,74 +0,0 @@ -# Trim the boxy frame off the female so its outer shape is the bear face itself. -# -# Method: take the male's flat back face (the plane Y=0 -- that face IS the bear silhouette), -# offset its OUTER wire outward in 2D, extrude the result along the insertion axis, and keep only -# the part of the female inside it. Everything outside is the block frame and goes away. -# -# NOTE ON THE NUMBER. The pocket's side walls stand at +0.20 mm from the male outline, because that -# is the clearance. A trim boundary at +0.10 mm therefore falls INSIDE them by 0.10 mm and removes -# the side wall entirely rather than leaving a thin one. The script runs the requested value and -# then measures what is actually left, so the outcome is a number rather than an opinion; it also -# emits a second variant at an offset that leaves a printable wall, for comparison. -# -# Run: /snap/bin/freecad.cmd trim_female.py - -import os, sys -import FreeCAD as App -import Part -from FreeCAD import Vector - -HERE = os.path.dirname(os.path.abspath(__file__)) -MALE = os.path.join(HERE, "bear.step") -FEMALE = os.path.join(HERE, "BearConnector_Female.step") - -REQUESTED = 0.10 # as asked -CLEARANCE = 0.20 # what the pocket was built with -SAFE_WALL = 1.60 # a wall that survives an FDM nozzle: clearance + ~1.4 mm - -male = Part.Shape(); male.read(MALE); male = male.Solids[0] -fem = Part.Shape(); fem.read(FEMALE); fem = fem.Solids[0] -print(f"female in : {fem.Volume/1000:.2f} cm3, {len(fem.Faces)} faces") - -# --- the bear silhouette: the male's flat back face at Y = 0 -back = None -for f in male.Faces: - n = f.normalAt(0, 0) - if abs(f.CenterOfMass.y) < 1e-6 and abs(abs(n.y) - 1.0) < 1e-6: - if back is None or f.Area > back.Area: - back = f -if back is None: - print("FAIL: could not find the flat back face at Y=0"); sys.exit(1) -print(f"silhouette: back face area {back.Area:.1f} mm2, {len(back.Wires)} wires " - f"(outer + {len(back.Wires)-1} holes: eyes and mouth)") - -fb = fem.BoundBox -y0, y1 = fb.YMin - 5.0, fb.YMax + 5.0 - -def trimmed(offset): - """keep only the part of the female inside the silhouette grown by `offset`""" - wire = back.OuterWire - grown = wire.makeOffset2D(offset, join=2, fill=False, openResult=False, intersection=True) - face = Part.Face(Part.Wire(grown.Edges)) - prism = face.extrude(Vector(0, y1 - y0, 0)) - prism.translate(Vector(0, y0 - face.CenterOfMass.y, 0)) - return fem.common(prism) - -for tag, off, out in (("requested", REQUESTED, "BearConnector_Female_Trimmed.step"), - ("safe wall", SAFE_WALL, "BearConnector_Female_Trimmed_wall.step")): - r = trimmed(off) - if not r.Solids: - print(f"\n{tag} (+{off:.2f} mm): NOTHING LEFT"); continue - wall = off - CLEARANCE - # is there any material left at the level of the pocket's side wall? - sec = r.section(Part.makePlane(400, 400, Vector(-200, 1.5, -200), Vector(0, 1, 0))) - perim = sum(e.Length for e in sec.Edges) - print(f"\n{tag} (+{off:.2f} mm) wall = {wall:+.2f} mm") - print(f" volume {r.Volume/1000:.2f} cm3, {len(r.Solids)} solid(s), {len(r.Faces)} faces") - print(f" section through the pocket wall at Y=1.5: {perim:.1f} mm of edge") - if wall <= 0: - print(f" -> the trim cuts {abs(wall):.2f} mm INSIDE the pocket wall: no side wall remains") - doc = App.newDocument(tag.replace(" ", "_")) - o = doc.addObject("Part::Feature", "Female") - o.Shape = r; doc.recompute() - Part.export([o], os.path.join(HERE, out)) - print(f" wrote {out}") diff --git a/docs/CAD/design/mate-connectors/verify_trimmed.py b/docs/CAD/design/mate-connectors/verify_trimmed.py deleted file mode 100644 index 81f6f3fea1..0000000000 --- a/docs/CAD/design/mate-connectors/verify_trimmed.py +++ /dev/null @@ -1,25 +0,0 @@ -# Check both trimmed females still fit the male, and export STLs for a visual comparison. -# Run: /snap/bin/freecad.cmd verify_trimmed.py -import os -import Mesh, Part - -HERE = os.path.dirname(os.path.abspath(__file__)) -male = Part.Shape(); male.read(os.path.join(HERE, "bear.step")); male = male.Solids[0] - -for name in ("BearConnector_Female_Trimmed", "BearConnector_Female_Trimmed_wall"): - p = os.path.join(HERE, name + ".step") - s = Part.Shape(); s.read(p); s = s.Solids[0] - d = male.distToShape(s)[0] - c = male.common(s) - cv = c.Volume if c.Solids else 0.0 - bb = s.BoundBox - print(f"{name}") - print(f" {bb.XLength:.2f} x {bb.YLength:.2f} x {bb.ZLength:.2f} mm, {s.Volume/1000:.2f} cm3, " - f"{len(s.Faces)} faces, valid={s.isValid()}") - print(f" gap to male {d:.4f} mm, interference {cv:.6f} mm3") - m = Mesh.Mesh(); m.addFacets([tuple(t) for t in s.tessellate(0.12)[1]] and - [(s.tessellate(0.12)[0][a], s.tessellate(0.12)[0][b], - s.tessellate(0.12)[0][c2]) - for a, b, c2 in s.tessellate(0.12)[1]]) - m.write(os.path.join(HERE, name + ".stl")) - print(f" wrote {name}.stl ({m.CountFacets} facets)") diff --git a/docs/CAD/design_tab.md b/docs/CAD/design_tab.md deleted file mode 100644 index 1be0a2ea33..0000000000 --- a/docs/CAD/design_tab.md +++ /dev/null @@ -1,333 +0,0 @@ -# The Design tab - -Object-driven parametric CAD inside the slicer. Point at geometry; the geometry offers the -verbs that apply to it. Selection comes first and the tool consumes it. Draw a sketch, -constrain it, turn it into a solid, refine it, and send it straight to Prepare — without -leaving for another application and coming back through an STL. - -The model is a **recipe**, not a mesh. Every action becomes a feature in a tree that is -replayed from the start whenever anything changes, so editing a dimension you set twenty -steps ago rebuilds everything downstream. The geometry kernel is OCCT, which the slicer -already ships for STEP import. - ---- - -## Getting started - -1. Open the **Design** tab. -2. Click a face or a reference plane in the viewport, then press `Shift+S` (Sketch). The offer - opens with the sketch tools on it. -3. Draw a closed profile, then press **✓ Confirm** in the floating action bar. -4. With the sketch selected, press `Shift+E` (Extrude). -5. Press **Commit to Plate** to hand the solid to Prepare. - -The status line under the toolbar is the thing to watch: it says what the current tool is -waiting for. When no plane is picked it reads *"Click a face or a reference plane in the -viewport, then a sketch tool"*; once one is picked it reads *"Sketching on — pick a -tool"*. It is also where a refusal explains itself. - ---- - -## Selecting - -- One left-click selects what is under the cursor. There is no click-cycling through - face → edge → body. -- A click near a corner takes the corner, not the face behind it. -- Left-drag sweeps a rubber band, and a rubber band takes the whole body. -- An open sketch line can be clicked, even where it bounds a region. -- Double-click a sketch stroke to edit it — the gesture belongs on the geometry. -- Editing a dimension's value **updates** that dimension instead of adding a second one next - to it. -- The floating chrome that belongs to a sketch leaves with the sketch when it ends. -- Sketching happens on the face you clicked, first click. -- A sketch whose entities form no wire **fails** instead of extruding a default box. A - subtraction that removes nothing is reported as an error instead of a silent success. - ---- - -## The offer - -Right-click on the geometry, released without moving the mouse (an 8 px budget — a -right-drag that orbits the camera does not open it). Left-click still only selects, so -pointing at things stays quiet. - -The offer also opens by itself the moment you press Sketch on a face or plane, showing the -sketch tools — the app hands you the tools directly. - -**Eight families, always in this fixed order:** Create, Add material, Remove, Dress-up, -Repeat, Transform, Reference, Modify. - -- A family with at least one applicable verb shows it. Several applicable verbs collapse - into a submenu under the family name. -- A family with nothing applicable is **shown greyed in place, with the reason** — e.g. - *"Create — Click a face or a reference plane in the viewport, then a sketch tool"*. It is - not hidden. A control that cannot be used still says what it is and what you would have to - do first. -- Inside a sketch the offer shows the sketch verbs; outside it shows the feature verbs. - -**Document-level actions never enter the offer**, because they act on the document and not -on a selection: Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, -Redo, Variables, Section view, Origin planes, World axes. They live in the toolbar. - ---- - -## Keyboard - -Single letters drive sketch tools **while a sketch is open**; Shift+letter drives feature -tools and single letters drive view toggles **when no sketch is open**. The two maps are -selected by the mode, not by whether a sketch session is running. - -### Sketch (while a sketch is open) - -| Key | Tool | -|---|---| -| `L` | Line — click start, then end | -| `R` | Rectangle — click two opposite corners | -| `C` | Circle — click centre, then radius | -| `A` | Arc — click start, end, then a point | -| `S` | Slot — two centreline ends, then width | -| `E` | Ellipse — centre, major end, minor point | -| `B` | Spline — click control points | -| `P` | Point — click to place | -| `G` | Polygon — click centre, then a vertex | -| `D` | Dimension — click 2 points or an entity | -| `T` | Trim — click a segment to trim it | -| `X` | Extend — click a line/arc to extend it | -| `O` | Offset — pick an entity, drag the distance | -| `M` | Mirror — pick axis, then entities | -| `F` | Fillet — pick two lines, set the radius | -| `H` | Chamfer — pick two lines, set the distance | -| `K` | Constrain — finish the live sketch and enter constrain | -| `Q` | Construction toggle — draw the next entity as construction geometry | -| `Del` | Delete the selected sketch entity | -| `Esc` | Cancel the live tool | - -### Feature (when no sketch is open) - -| Key | Tool | -|---|---| -| `Shift+S` | Sketch | -| `Shift+E` | Extrude — extrude a profile, or push/pull a picked face | -| `Shift+R` | Revolve | -| `Shift+W` | Sweep | -| `Shift+L` | Loft | -| `Shift+N` | Pattern | -| `Shift+G` | Surface Extrude | -| `Shift+J` | Surface Revolve | -| `Shift+O` | Surface Loft | -| `Shift+Q` | Surface Fill | -| `Shift+U` | Surface Offset | -| `Shift+V` | Thicken Surface | -| `Shift+P` | Plane | -| `Shift+A` | Axis | -| `Shift+C` | Coord Sys | -| `Shift+Y` | Transform | -| `Shift+Z` | Mirror | -| `Shift+B` | Boolean | -| `Shift+X` | Cut | -| `Shift+F` | Fillet / Chamfer | -| `Shift+D` | Draft | -| `Shift+K` | Shell | -| `Shift+H` | Hole | -| `Shift+T` | Thread | -| `Shift+I` | Import STEP | -| `Shift+M` | Import mesh | - -### View toggles (single letters, when no sketch is open) - -| Key | Action | -|---|---| -| `Home` | Axonometric view, fitted to the model | -| `P` | Origin planes on/off | -| `A` | World axes on/off | -| `X` | Section view on/off | - -While the section is on: `PageUp` / `PageDown` move the cut plane, `F` flips which half is -kept. With no section on, `F` is Place on Face — lay the picked face flat on the bed. - ---- - -## Sketching - -A sketch is a closed (or open) 2D profile on a plane or on a flat face of an existing body. -Press `Shift+S`, click the face or plane you want to sketch on, and draw. The toolbar and -the offer both carry the sketch tools. - -**Entities:** line, polyline, rectangle (corner / centre / oblique / rounded), circle -(centre-radius / 2-point / 3-point), arc (centre-point / 3-point / tangent), ellipse and -elliptical arc, polygon (inscribed / circumscribed), slot (straight / arc), spline, point, -and text. - -**Editing:** move, rotate, scale, trim, extend, offset, mirror, and linear or polar arrays. - -**Constraints:** coincident, horizontal, vertical, parallel, perpendicular, tangent, equal, -concentric, midpoint, symmetric, fix, plus dimensional radius, diameter, distance and angle. -The solver reports the remaining degrees of freedom and tells you when a sketch is fully -constrained — or when a constraint conflicts with one already there. - -Sketches stay editable. Selecting one in the feature tree reopens it with its dimensions -live. - ---- - -## Building solids - -Grouped in the toolbar by what they do, one concept per drawer. - -### Add material -| Tool | Shortcut | What it does | -|---|---|---| -| Extrude | `Shift+E` | Extrude a profile, or push/pull a face already on a body | -| Revolve | `Shift+R` | Revolve a profile about an axis | -| Sweep | `Shift+W` | Sweep a profile along a path — including a helix, for springs and augers | -| Loft | `Shift+L` | Skin between two or more profiles | -| Thicken | — | Offset a solid face into a thin plate as a new body | -| Rib | — | Grow a stiffening wall from an open sketch line, fused to a body | - -Extrude offers blind, symmetric, two-sided, through-all and up-to-face end conditions, plus -a draft angle on the side wall, and can add, subtract, intersect or start a new body. - -### Surface -Sheet bodies — surfaces with no thickness — for shapes that are easier to build as skins and -solidify afterwards. - -| Tool | Shortcut | -|---|---| -| Surface Extrude | `Shift+G` | -| Surface Revolve | `Shift+J` | -| Surface Loft | `Shift+O` | -| Surface Fill | `Shift+Q` | -| Surface Offset | `Shift+U` | -| Thicken Surface | `Shift+V` | - -Thicken Surface is how a sheet becomes a printable solid. - -### Dress-up -| Tool | Shortcut | -|---|---| -| Fillet / Chamfer | `Shift+F` | -| Draft (taper a face) | `Shift+D` | -| Shell | `Shift+K` | -| Delete Face | — | - -Delete Face removes faces and heals the solid — useful for stripping a feature off an -imported part. - -### Holes -**Hole** (`Shift+H`) drills simple, counterbored or countersunk holes, with an ISO/ANSI -standards table so you can ask for an M6 clearance hole instead of computing a diameter. -**Thread** (`Shift+T`) cuts a real helical thread into a bore or onto a shaft. - -### Placement -Operations that move a body without changing its shape: **Transform** (`Shift+Y`), -**Mirror** (`Shift+Z`), and **Mate** for assemblies. - -### Combining -**Boolean** (`Shift+B`) unions, subtracts or intersects two bodies. **Cut** (`Shift+X`) -splits a body with a plane. **Pattern** (`Shift+N`) repeats a body linearly, in a circle, or -along a curve. - ---- - -## Reference geometry - -Datum features carry no material; they exist to give later features something to attach to. - -- **Plane** (`Shift+P`) — offset, tilted, midplane, tangent, through two edges, or coincident -- **Axis** (`Shift+A`) — two points, a face normal, a cylinder centreline, the intersection of - two planes, or along an edge -- **Coord Sys** (`Shift+C`) — a full frame, from a world point or from a face plus a - direction edge -- **Helix** — a helical curve to sweep along -- **Project** — project a body's edges onto a plane as sketch geometry - -On the Coord Sys tool, picking a direction **edge** is worth the extra click: without one the -frame takes its X from the face's first edge, which is deterministic but not necessarily the -direction you meant. - ---- - -## Assemblies - -**Mate** aligns two coordinate systems and moves one body onto the other. Five kinds: - -| Kind | Leaves free | -|---|---| -| Fastened | nothing — 6 DOF locked | -| Planar | sliding in the plane | -| Revolute | rotation about the axis | -| Slider | sliding along the axis | -| Cylindrical | rotation *and* sliding | - -**Check interference** reports every overlapping pair of solids with the overlapping volume, -so a clash is a number rather than an impression. Bodies that merely touch enclose no volume -and are not reported. - ---- - -## Variables and expressions - -Define named variables and drive dimensions from them. Any numeric field accepts an -expression — `width/2`, `wall*3` — and everything re-evaluates on recompute. Change one -variable and the whole model follows. - ---- - -## Import and export - -**Import STEP** brings in a real B-rep solid, not a mesh: its faces and edges can be filleted, -shelled and cut like anything modelled here. - -**Import mesh** (STL/OBJ) converts triangles to a B-rep body and tells you honestly what it -got — whether the result is a closed solid or an open shell, with the boundary and -non-manifold edge counts. A large mesh becomes a large number of faces, which is slow to -edit; the importer warns before you commit to it. - -**Export STEP** writes the model out for another CAD tool. - -**Commit to Plate** sends the solid to Prepare for slicing. The whole feature recipe is saved -inside the 3MF, so reopening the project restores the editable model rather than a frozen -mesh. - ---- - -## View controls - -**Section view** (`X`) hides half the model so you can see inside — `PageUp`/`PageDown` move -the plane, `F` flips which half is kept. **Place on Face** (`F`, when section is off) lays a -picked face flat on the bed. Origin planes (`P`) and world axes (`A`) can be toggled on while -you orient yourself. - ---- - -## Known limitations - -Being straight about the edges, so nobody discovers them the hard way: - -- **Rib** needs a sketch containing an explicit open line. A parametric rectangle sketch - carries no individual entities, so Rib cannot use one. -- **Surface Loft** and **Surface Fill** have kernel tests but have not been exercised by hand. -- Card wiring for 9 of the 16 late-wired tools has never been click-tested. -- Mate resolves by composing transforms directly. There is no 3D assembly solver, so mates - are applied in order rather than solved simultaneously, and mate limits are not implemented. -- Move-face and replace-face are not implemented — OCCT offers no clean primitive for them. -- There is no automated GUI test in CI. Every behaviour above is traced to code and to a - hand pass, not to a synthetic click. - ---- - -## Where the code lives - -| Path | Role | -|---|---| -| `src/libslic3r/CAD/CadDocument.*` | the feature recipe and its replay | -| `src/libslic3r/CAD/GeometryEngine.*` | OCCT wrapper — faces, edges, booleans, healing | -| `src/libslic3r/CAD/SketchEngine.*` | profile → wire → solid | -| `src/libslic3r/CAD/SketchSolver.*` | constraint solving, over the vendored solver | -| `src/libslic3r/slvs/` | vendored 2D constraint solver (GPLv3) | -| `src/slic3r/GUI/CAD/DesignPanel.*` | the tab: toolbar, cards, feature tree | -| `src/slic3r/GUI/CAD/DesignCanvas.*` | viewport integration | -| `src/slic3r/GUI/CAD/DesignSketchTool.*` | in-canvas sketching | - -Build with `-DSLIC3R_CAD=ON` (the default). With it OFF the tab is not compiled and the deps -prefix matches upstream exactly — see [cad_dependency_weight.md](cad_dependency_weight.md). diff --git a/docs/CAD/design_tab_pr_description.md b/docs/CAD/design_tab_pr_description.md deleted file mode 100644 index a6d67f0e7c..0000000000 --- a/docs/CAD/design_tab_pr_description.md +++ /dev/null @@ -1,73 +0,0 @@ -# Design (CAD) tab — upstream pull request - -## What this adds - -A sketch-first parametric CAD tab inside the slicer. The workflow is direct: -sketch → constrain → solid features → commit to plate. The whole feature recipe is -persisted inside the 3MF, so reopening restores an editable model rather than a frozen mesh. - -- Kernel: OCCT, which upstream already links for STEP import — see - [cad_dependency_weight.md](docs/cad_dependency_weight.md) -- Constraint solver: vendored SolveSpace `libslvs` subset -- Interaction model: object-driven — point at geometry, the geometry offers the verbs that - apply to it; see [cad_ux_guidelines.md](docs/cad_ux_guidelines.md) -- Full user-facing documentation: [design_tab.md](docs/design_tab.md) - -## Why it belongs in the slicer - -Every round trip through an external CAD tool costs a file export, a re-import, and the -design intent that both steps discard. A part modified after slicing should return to its -feature history, not to a mesh. Keeping the CAD model inside the slicer preserves that -loop — the nozzle diameter, the build volume and the material are known at design time. - -For the integration case in full: [design_tab_upstream_portability.md](docs/design_tab_upstream_portability.md). - -## How it is built - -The `SLIC3R_CAD` CMake flag (default ON) gates the entire tab. With it OFF the tab is not -compiled and the deps prefix matches upstream exactly — the dependency diff is one line in -OCCT's CMake: `BUILD_MODULE_ModelingAlgorithms=OFF → ON`. - -Measured cost table: [cad_dependency_weight.md](docs/cad_dependency_weight.md). - -## Diff shape - - - -Against merge-base `d6cb667b894f`: - - 306 files changed, 83032 insertions(+), 777 deletions(-) - -350 commits, of which 284 are new files and 37 modify upstream files. 99.3 % of the diff -is new code. The negotiable surface is the 37 modified files. - -## Tests - -205 `TEST_CASE` blocks across 6 new test source files. This counts assertions written, not -assertions passed — a run needs a build. - -`scripts/CAD/run-kernel-tests.sh` is the headless verification contract: it builds only -`libslic3r_tests` (not the GUI app), needs no display, and exit 0 means the CAD suite -passed. It now runs with **no exclusions** — both cases that used to be quarantined (the -circle-line tangency solver abort and the internal-thread reference) are fixed. - -## Licensing - -The vendored solver in `src/libslic3r/slvs/` is **GPL-3.0** (see `src/libslic3r/slvs/LICENSE`), -not LGPL. The combined work is distributable under AGPL-3.0. See the Licensing section of -[design_tab_upstream_portability.md](docs/design_tab_upstream_portability.md) for the -AGPLv3/GPLv3 compatibility argument; this point should be confirmed with upstream explicitly. - -## Not verified - -- Card wiring for 9 of the 16 late-wired tools was never click-tested. -- There is no automated GUI test in CI. A green kernel run says nothing about the GUI — - synthetic clicks never drift, so the test suite and the viewport are two separate realities. -- The click-test defect rate has **not converged**: a second pass found no new defects, but - four further days of work found five more. The earlier pass is not evidence of stability. - -## Reviewer's map - -See the [Where the code lives](docs/design_tab.md#where-the-code-lives) table in the user -doc for the file-to-role mapping, and [docs/ux/tool_atlas.json](docs/ux/tool_atlas.json) as -the generated-from source of `src/slic3r/GUI/CAD/DesignOffer.hpp`. diff --git a/docs/CAD/design_tab_upstream_portability.md b/docs/CAD/design_tab_upstream_portability.md deleted file mode 100644 index a7e9cd84ed..0000000000 --- a/docs/CAD/design_tab_upstream_portability.md +++ /dev/null @@ -1,162 +0,0 @@ -# Design (CAD) tab — upstream integration brief - -**Question:** can the Design tab (sketch-first parametric CAD: sketch → constrain → -extrude/revolve/fillet/hole/thread/shell, multi-body, undo, 3MF persistence) land in -mainline OrcaSlicer? - -**Answer: yes, and the ask is far smaller than previously believed.** OCCT is *already* -an OrcaSlicer dependency. We are not asking upstream to adopt a new library; we are -asking it to widen one it already builds, at a measured cost of **3.77 MiB on Windows**. - -> ### Corrections to the 2026-06-21 assessment -> That revision was written before the persistence work landed and got two load-bearing -> facts wrong. Both are corrected here from direct measurement of the branch: -> -> 1. **"The real blocker: OCCT … a dependency mainline OrcaSlicer has never carried."** -> **False.** `deps/OCCT/` exists at the merge-base and upstream links it from -> `Format/STEP.cpp`, `Format/svg.cpp`, and `Shape/TextShape.cpp`. Our entire -> dependency diff is **one line**: `BUILD_MODULE_ModelingAlgorithms=OFF → ON`. -> 2. **"vendored SolveSpace solver … LGPL."** **False.** `src/libslic3r/slvs/LICENSE` is -> **GPL-3.0**, not LGPL. This is fine (see Licensing) but must not be misstated. -> -> It also claimed "no changes to Model" — no longer true; 3MF recipe persistence adds one -> `std::string` to `Model`. - -## Measured shape of the change - -Against merge-base `449a4cf9fc` (34 commits ahead): - -| | files | lines | -|---|---:|---:| -| **New files** | 138 | +61,720 | -| **Modified upstream files** | 23 | +457 / −75 | -| **Deleted upstream files** | 0 | — | - -The 62 kLOC headline is inflated by localization. The feature itself: - -| area | LOC | files | -|---|---:|---:| -| kernel (`src/libslic3r/`) | 15,828 | 37 | -| GUI (`src/slic3r/`) | 19,544 | 14 | -| tests (Catch2) | 2,567 | 6 | -| i18n (unrelated; strip from the CAD PR) | 23,438 | 77 | - -**99.3 % of the diff is new files.** The negotiable surface is 457 added lines across 23 -files, and nothing upstream is deleted. The largest single hook is `GLCanvas3D.cpp` -(+110/−2): an `m_design_sketch_tool` member plus render/mouse/key hooks, **every one -already null-guarded** — which is why the compile-time gate below is cheap. - -No changes to the slicing pipeline (Print/PrintObject/Layer/GCode), Tab, or the -printer-profile/config system. - -## The dependency ask, precisely - -Not "adopt OCCT" — **widen the existing OCCT build**: - -```diff -- -DBUILD_MODULE_ModelingAlgorithms=OFF -+ -DBUILD_MODULE_ModelingAlgorithms=ON -``` - -Cost, measured from the shipped Windows artifact (42 OCCT DLLs, 45.43 MiB total): - -| toolkit | size | note | -|---|---:|---| -| `TKFillet.dll` | 2.02 MiB | only exists with the flag ON | -| `TKOffset.dll` | 1.75 MiB | only exists with the flag ON | -| **delta** | **3.77 MiB** | Windows only (OCCT is Shared on Win, Static elsewhere) | - -`TKBool` is *not* part of the delta — upstream's `DataExchange` already pulls it in -transitively. On macOS/Linux OCCT links statically, so the cost is only the code actually -referenced, not a 3.77 MiB floor. - -**Unmeasured, and we should measure before the call:** clean-deps build-time delta with -the flag ON vs OFF, and the resulting CI runner-minute cost. Do not guess these at him. - -## Licensing - -- Vendored solver `src/libslic3r/slvs/` — **GPL-3.0**, 9,339 LOC, © Jonathan Westhues, - a self-contained subset of SolveSpace (`libslvs`). No external dependencies. -- OrcaSlicer — **AGPL-3.0** (`LICENSE.txt`). - -GPLv3 §13 expressly permits combining a GPLv3 work with an AGPLv3 work; AGPLv3 §13 grants -the converse. The combined work is distributable under AGPL-3.0 with the solver's GPLv3 -terms preserved. This is a favourable direction (GPLv3 → into an AGPLv3 project), but it -is a point to **confirm explicitly with upstream**, not to assert unilaterally. - -Open question for SoftFever: keep the solver **vendored** (current: pinned, no submodule, -no external build) or move it to `deps/` as a fetched external? Vendoring costs us -upstream-sync burden; `deps/` costs build complexity. - -## The one irreversible decision: the 3MF format - -Persistence adds an **optional** archive entry and one field: - -```cpp -// Model.hpp -std::string cad_recipe; // empty for non-CAD projects -``` - -``` -Metadata/orca_cad.bin // written only when cad_recipe is non-empty -``` - -Readers that do not know the entry ignore it; writers skip it entirely when empty. So -existing projects are bit-identical and old readers are unaffected. Good. - -**But the moment upstream ships this, it owns forward-compatibility forever.** Three -things should be settled *before* the first release, because none can be changed after: - -1. **Name.** Renamed to `Metadata/orca_cad.bin`. -2. **Encoding.** The recipe is an opaque **cereal `PortableBinaryArchive`** blob whose - layout is the field order of `CadFeature::serialize`. Portable across endianness and - word size — *not* across a field reorder. Append-only is currently a convention held by - discipline, not by any check. -3. **Embedded BRep.** `Import` features embed OCCT's ASCII BRep for the imported solid, - which couples saved project files to an OCCT BRep revision. Alternative: re-import from - the source STEP and store only a reference. Worth deciding deliberately. - -**Concrete gap we should close before the call.** `test_caddocument.cpp` covers the -in-memory round-trip and correctly refuses a version-999 blob — but there is **no -checked-in v1 fixture on disk**. A reordered field in `CadFeature::serialize` would pass -the entire suite while silently breaking every previously-saved project. Ship a golden -`.bin` fixture generated today plus a test that loads it; that is the only thing that will -hold the format still once real users have files. - -## Proposed PR decomposition - -35 kLOC in one PR is not reviewable. Behind the flag, slices 1–4 are behaviour-neutral for -existing users: - -1. **Build gate + OCCT flag + Windows packaging guard.** `-DSLIC3R_CAD=ON/OFF`, default - **OFF**. Flips `ModelingAlgorithms=ON`. Includes the guard that asserts every linked - OCCT toolkit has a shipped DLL (already on both forks: `546cef5f42`). ← *this is what - makes SoftFever's "parallel build" a one-line CI matrix entry.* -2. **Vendored `slvs` solver** + its Catch2 tests. No GUI, no OCCT. -3. **CAD kernel** (`CadDocument`, `SketchEngine`, `GeometryEngine`, `Sketch*`) + kernel - tests. Headless, no GUI. -4. **3MF recipe persistence** + golden-fixture regression test. -5. **GUI Design tab** (`DesignPanel`, `DesignCanvas`, `DesignSketchTool`, `GLGizmoSketch`) - + the 23 upstream hooks. - -## Agenda for the call - -Questions only SoftFever can answer: - -- Does OrcaSlicer *want* to be a CAD-integrated slicer? (Strategic; everything else is mechanical.) -- Default of `SLIC3R_CAD` at merge time, and when it flips ON. -- Vendored solver vs `deps/` external; and confirmation of the GPLv3/AGPLv3 combination. -- Project-file format: neutral name, encoding, embedded-BRep policy, and who owns v1 forward-compat. -- Undo/redo: the Design tab has its own stack; integrate with Orca's snapshot system or keep separate? -- Does he want the i18n work (Romanian, +23 kLOC) as a wholly separate PR? (Yes, almost certainly.) - -## Verdict - -Portability **high**. The prior "does upstream want OCCT" framing was wrong — OCCT is -already there. What remains is a 3.77 MiB dependency widening, a compile-time gate that -the existing null-guards make cheap, and one file-format decision that must be made before -the first release rather than after. - ---- -*Revised 2026-07-10 from direct measurement of `cad-mainline` @ `546cef5f42` vs upstream -merge-base `449a4cf9fc`. Supersedes the 2026-06-21 read-only assessment.* diff --git a/docs/CAD/ux/interaction-model.md b/docs/CAD/ux/interaction-model.md deleted file mode 100644 index 2041978ea0..0000000000 --- a/docs/CAD/ux/interaction-model.md +++ /dev/null @@ -1,144 +0,0 @@ -# Design tab — interaction model - -The contract for Esc, the right mouse button, and the states between them. Code that changes any -of the three changes this file in the same commit. - -## 1. The state machine - -`src/slic3r/GUI/CAD/DesignInteraction.hpp` — a four-level LIFO stack. The enum value *is* the -depth, so "which level does this press belong to" is a comparison rather than a chain of -special cases spread over three files. - -```cpp -enum class CadLevel : int { - Idle = 0, // nothing transient is up: Esc clears the selection - Tool = 1, // a feature card / armed sketch tool / constrain session: Esc exits it - Gesture = 2, // an uncommitted delta (entity being drawn, body being dragged): Esc reverts it - Transient = 3, // a value field or a popup menu: Esc closes just that -}; - -struct CadInteractionState { // the four bits routing actually needs - bool value_field_open{false}; - bool gesture_active{false}; - bool tool_armed{false}; - bool has_selection{false}; -}; - -constexpr CadLevel cad_escape_level(const CadInteractionState& s) -{ - if (s.value_field_open) return CadLevel::Transient; - if (s.gesture_active) return CadLevel::Gesture; - if (s.tool_armed) return CadLevel::Tool; - return CadLevel::Idle; -} -``` - -The rule is a `constexpr` free function over a POD, not a method on the panel, so the ordering -that is the entire contract is checkable without a window, a GL context or an event loop. Five -`static_assert`s in the header do exactly that, at compile time. - -**Strict invariant.** No level of Esc deletes a feature, discards a sketch that holds geometry, -or rolls history back. Destroying work needs a gesture that says so: - -| To destroy | Gesture | -|---|---| -| a feature | Delete / Backspace on an explicit selection | -| a drawn sketch | the ribbon's ✗ Cancel, which asks first | -| the last committed change | Ctrl+Z | - -## 2. Event routing - -**`OnKeyDown(WXK_ESCAPE)`** — `DesignPanel`'s `wxEVT_CHAR_HOOK`, one line: - -```cpp -if (key == WXK_ESCAPE) { escape(); return; } -``` - -Every Esc in the tab goes through it, whatever holds focus. `DesignPanel::escape_level()` answers -the four questions of `CadInteractionState` about this panel; `DesignPanel::escape()` acts on the -one level that answer names, and on no other: - -| Level | What one press does | What it must not touch | -|---|---|---| -| `Transient` | close the value field (`cancel_value` / `inline_cancel`) | the tool, which stays armed | -| `Gesture` | drop the clicks of the entity being drawn, or put a moved body back at the pose it had when the gizmo appeared | everything already committed | -| `Tool` | discard a feature card's *candidate*; drop an armed sketch tool to Select; end Constrain | committed features; entities already drawn | -| `Idle` | clear the selection (model and sketch); leave a sketch session **only if it is empty** | a sketch holding geometry — it is left through Finish or Cancel | - -A sketch *session* is deliberately not a `Tool`. It is the environment the Idle level lives in, -which is what makes the destructive path unrepresentable rather than merely unlikely. - -**`OnRightDown` / `OnRightUp`** — `DesignCanvas::set_on_context_menu`, bound after `GLCanvas3D`'s -own handlers so it can consume the event before them: - -```cpp -RIGHT_DOWN: remember the press position and the clock, then Skip() // the canvas still seeds the orbit - -RIGHT_UP: terminated = sketch_tool.take_right_consumed(); // read-and-clear, always - is_click = drift <= 3 px && dt <= 200 ms; // both budgets, or it was navigation - if (callback && !terminated && !inline_busy && is_click) { - select_at_screen(press.x, press.y); // raycast at the PRESS, not the release - on_context_menu(ClientToScreen(press)); - return; // consumed - } - Skip(); // orbit / pan / the handlers underneath -``` - -Two independent budgets because the two failure modes are independent: drift alone still popped a -menu at the end of a slow, careful orbit. `take_right_consumed()` is how a right-click that -already meant something to the armed sketch tool (terminate a chain, drop an edit-op) declines to -also mean "open a menu". - -## 3. Transition table - -`sel` = something is picked. Blank = the input does nothing at that state. - -| State | Left-click | Right-click | Esc | Enter | -|---|---|---|---|---| -| **Idle — model view** | pick / escalate the pick | offer menu for what is under the cursor | clear the selection | — | -| **Idle — sketch, empty** | pick | sketch offer menu | leave the session (nothing to lose) | Finish sketch | -| **Idle — sketch, drawn** | pick | sketch offer menu | clear the selection; status says the sketch is kept | Finish sketch | -| **Tool — feature card** | pick the card's next reference | offer menu | discard the candidate, close the card | commit the feature | -| **Tool — sketch tool armed** | place the first point | drop the tool to Select | drop the tool to Select | — | -| **Tool — constrain** | pick an entity | offer menu | end the session | apply | -| **Gesture — drawing** | place the next point | terminate the chain (keep what is drawn) | drop the in-progress entity, tool stays armed | commit the entity as drawn | -| **Gesture — moving a body** | drop the body here | end the move | revert to the pose at move-start | keep the placement | -| **Transient — value field** | — | — | close the field, tool stays armed | commit the value, advance the chain | -| **Transient — popup menu** | run the entry | — | close the menu | run the highlighted entry | -| **any** | — | — | *never* deletes, discards or rolls back | — | - -Right-hold-and-drag is not in the table on purpose: past 3 px or 200 ms it is navigation, and -navigation does not transition the state machine. - -## 4. Visual scaffolding - -Entering a sketch changes three things at once, so the state is legible from across the room: - -- **Banner.** A teal strip across the top of the viewport: `Editing: Sketch N · N = look normal to - the plane · Finish or Cancel in the toolbar`. Indicator only — Confirm and Cancel stay on the one - ribbon action bar, per the Design UX contract. It is a sibling above the canvas, not a floating - child over it: a child window over a `wxGLCanvas` is a native window on GTK and does not reliably - stack over GL, and this banner's job is to be unmissable rather than clever. -- **The printer bed is muted.** A plate grid and a sketch grid are the same visual language, and - reading one as the other is how a sketch gets drawn against the wrong reference. The view - checkbox remains the stored preference and is restored on the way out; ticking it mid-sketch - still shows the bed, because that is a deliberate act and this is only a default. -- **`N` looks normal to the plane**, keeping the current zoom, with the plane's own y axis as up. - Sketch key map only — in Feature mode the navigator orb owns orientation. - -## 5. Context menu content - -The offer is generated from `docs/CAD/ux/tool_atlas.json`; its 8-row shape and permanent row -indices are ratified and are not changed here. Checked against the per-context vocabularies asked -for in the 2026-09-05 interaction brief, the atlas already carries all of them except two, both on -a planar face: - -| Asked for | Status | -|---|---| -| Revolve on a planar face | **not offered, and should not be**: `revolve` accepts `sk_loop` only, because the kernel takes a sketch profile — a face is not one | -| Offset Face | offered as **Thicken** (`thicken`, accepts `face_planar`); `surf_offset` is the sheet-body verb and accepts `body_sheet` | - -View and document actions — Zoom to Fit, View Isometric, Clear Selection, Finish Sketch, Normal to -Sketch — stay in chrome by the atlas's own rule: the offer describes verbs that consume a -*selection*, and these act on the document or the camera. Esc covers Clear Selection, `N` covers -Normal to Sketch, and the ribbon covers Finish. diff --git a/docs/CAD/ux/mockups/cmp_12__edge_str.svg b/docs/CAD/ux/mockups/cmp_12__edge_str.svg deleted file mode 100644 index 3e641e90ec..0000000000 --- a/docs/CAD/ux/mockups/cmp_12__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 12 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_12__face_planar.svg b/docs/CAD/ux/mockups/cmp_12__face_planar.svg deleted file mode 100644 index 85809d5bf6..0000000000 --- a/docs/CAD/ux/mockups/cmp_12__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_12__sk_line.svg b/docs/CAD/ux/mockups/cmp_12__sk_line.svg deleted file mode 100644 index 6535c9fe77..0000000000 --- a/docs/CAD/ux/mockups/cmp_12__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_8__edge_str.svg b/docs/CAD/ux/mockups/cmp_8__edge_str.svg deleted file mode 100644 index 2c41ce74fc..0000000000 --- a/docs/CAD/ux/mockups/cmp_8__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_8__face_planar.svg b/docs/CAD/ux/mockups/cmp_8__face_planar.svg deleted file mode 100644 index 5a58e2fb72..0000000000 --- a/docs/CAD/ux/mockups/cmp_8__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_8__sk_line.svg b/docs/CAD/ux/mockups/cmp_8__sk_line.svg deleted file mode 100644 index 4ca4000d59..0000000000 --- a/docs/CAD/ux/mockups/cmp_8__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__art.svg b/docs/CAD/ux/mockups/fresh__art.svg deleted file mode 100644 index a54dd49b43..0000000000 --- a/docs/CAD/ux/mockups/fresh__art.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetText / imported art selected — pick what to do with itFresh document · 8 slotsABCModify2Text / imported art \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__art__modify.svg b/docs/CAD/ux/mockups/fresh__art__modify.svg deleted file mode 100644 index 184611c682..0000000000 --- a/docs/CAD/ux/mockups/fresh__art__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsABCDeleteDelEditText / imported art · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__bodies_2.svg b/docs/CAD/ux/mockups/fresh__bodies_2.svg deleted file mode 100644 index f282bef03a..0000000000 --- a/docs/CAD/ux/mockups/fresh__bodies_2.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetTwo bodies selected — pick what to do with itFresh document · 8 slotsMeasureDeleteDelTwo bodies \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_sheet.svg b/docs/CAD/ux/mockups/fresh__body_sheet.svg deleted file mode 100644 index 635b2f6aa6..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_sheet.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSheet body selected — pick what to do with itFresh document · 8 slotsMeasureModify2Sheet body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_sheet__modify.svg b/docs/CAD/ux/mockups/fresh__body_sheet__modify.svg deleted file mode 100644 index 0cd330046d..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_sheet__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditSheet body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_solid.svg b/docs/CAD/ux/mockups/fresh__body_solid.svg deleted file mode 100644 index ef21e2b8e2..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_solid.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSolid body selected — pick what to do with itFresh document · 8 slotsMeasureModify2Solid body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_solid__modify.svg b/docs/CAD/ux/mockups/fresh__body_solid__modify.svg deleted file mode 100644 index 8b5d1485a0..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_solid__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditSolid body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__coordsys.svg b/docs/CAD/ux/mockups/fresh__coordsys.svg deleted file mode 100644 index e20d08d000..0000000000 --- a/docs/CAD/ux/mockups/fresh__coordsys.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCoordinate system selected — pick what to do with itFresh document · 8 slotsModify2Coordinate system \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__coordsys__modify.svg b/docs/CAD/ux/mockups/fresh__coordsys__modify.svg deleted file mode 100644 index b6b4871d16..0000000000 --- a/docs/CAD/ux/mockups/fresh__coordsys__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditCoordinate system · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_axis.svg b/docs/CAD/ux/mockups/fresh__datum_axis.svg deleted file mode 100644 index 8174807ceb..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_axis.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDatum axis selected — pick what to do with itFresh document · 8 slotsModify2Datum axis \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_axis__modify.svg b/docs/CAD/ux/mockups/fresh__datum_axis__modify.svg deleted file mode 100644 index cba7005358..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_axis__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditDatum axis · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_plane.svg b/docs/CAD/ux/mockups/fresh__datum_plane.svg deleted file mode 100644 index ffabd59969..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_plane.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDatum plane selected — pick what to do with itFresh document · 8 slotsSketchShift+SReference2Modify2Datum plane \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_plane__modify.svg b/docs/CAD/ux/mockups/fresh__datum_plane__modify.svg deleted file mode 100644 index 9ac26e4ce1..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_plane__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditDatum plane · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_plane__reference.svg b/docs/CAD/ux/mockups/fresh__datum_plane__reference.svg deleted file mode 100644 index b42479441a..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_plane__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsPlaneShift+PHelixDatum plane · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__edge_circ.svg b/docs/CAD/ux/mockups/fresh__edge_circ.svg deleted file mode 100644 index 3e72544c04..0000000000 --- a/docs/CAD/ux/mockups/fresh__edge_circ.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCircular edge selected — pick what to do with itFresh document · 8 slotsMeasureCircular edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__edge_str.svg b/docs/CAD/ux/mockups/fresh__edge_str.svg deleted file mode 100644 index c4e54d5335..0000000000 --- a/docs/CAD/ux/mockups/fresh__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetStraight edge selected — pick what to do with itFresh document · 8 slotsReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__edge_str__reference.svg b/docs/CAD/ux/mockups/fresh__edge_str__reference.svg deleted file mode 100644 index 80dd7a877a..0000000000 --- a/docs/CAD/ux/mockups/fresh__edge_str__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsMeasurePlaneShift+PAxisShift+AStraight edge · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_cyl.svg b/docs/CAD/ux/mockups/fresh__face_cyl.svg deleted file mode 100644 index d2335e4177..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_cyl.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCylindrical face selected — pick what to do with itFresh document · 8 slotsReference3EditCylindrical face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_cyl__reference.svg b/docs/CAD/ux/mockups/fresh__face_cyl__reference.svg deleted file mode 100644 index 7cb83afb56..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_cyl__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsMeasureAxisShift+AHelixCylindrical face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_other.svg b/docs/CAD/ux/mockups/fresh__face_other.svg deleted file mode 100644 index d8dcfb96ab..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_other.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCurved face selected — pick what to do with itFresh document · 8 slotsMeasureEditCurved face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_planar.svg b/docs/CAD/ux/mockups/fresh__face_planar.svg deleted file mode 100644 index a66268fc9a..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetPlanar face selected — pick what to do with itFresh document · 8 slotsSketchShift+SExtrudeShift+EReference4EditPlanar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_planar__reference.svg b/docs/CAD/ux/mockups/fresh__face_planar__reference.svg deleted file mode 100644 index 9aa608a5e7..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_planar__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+APlanar face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__none.svg b/docs/CAD/ux/mockups/fresh__none.svg deleted file mode 100644 index 56ac028b74..0000000000 --- a/docs/CAD/ux/mockups/fresh__none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__none__reference.svg b/docs/CAD/ux/mockups/fresh__none__reference.svg deleted file mode 100644 index 0492aa6de0..0000000000 --- a/docs/CAD/ux/mockups/fresh__none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CHelixPlaneShift+PAxisShift+ANothing selected · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent.svg b/docs/CAD/ux/mockups/fresh__sk_2ent.svg deleted file mode 100644 index dd02122149..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetTwo sketch entities selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__create.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__create.svg deleted file mode 100644 index 98e984bff2..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Two sketch entities · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__dressup.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__dressup.svg deleted file mode 100644 index 926594bb86..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDress-up — pick oneFresh document · 8 slotsFilletFChamferHTwo sketch entities · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__modify.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__modify.svg deleted file mode 100644 index 242332967e..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXTwo sketch entities · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__reference.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__reference.svg deleted file mode 100644 index aa105c3a9e..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKTwo sketch entities · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc.svg b/docs/CAD/ux/mockups/fresh__sk_arc.svg deleted file mode 100644 index 0712508411..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch arc or circle selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc__create.svg b/docs/CAD/ux/mockups/fresh__sk_arc__create.svg deleted file mode 100644 index d22d916e60..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch arc or circle · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc__modify.svg b/docs/CAD/ux/mockups/fresh__sk_arc__modify.svg deleted file mode 100644 index cf3fc2450f..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXSketch arc or circle · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc__reference.svg b/docs/CAD/ux/mockups/fresh__sk_arc__reference.svg deleted file mode 100644 index cfbe0a1042..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKSketch arc or circle · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line.svg b/docs/CAD/ux/mockups/fresh__sk_line.svg deleted file mode 100644 index e40d823e13..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch line selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__create.svg b/docs/CAD/ux/mockups/fresh__sk_line__create.svg deleted file mode 100644 index 1a6f7b561c..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch line · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__dressup.svg b/docs/CAD/ux/mockups/fresh__sk_line__dressup.svg deleted file mode 100644 index 3fce662ba1..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDress-up — pick oneFresh document · 8 slotsFilletFChamferHSketch line · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__modify.svg b/docs/CAD/ux/mockups/fresh__sk_line__modify.svg deleted file mode 100644 index 26318535ef..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXSketch line · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__reference.svg b/docs/CAD/ux/mockups/fresh__sk_line__reference.svg deleted file mode 100644 index 2abc91fc99..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKSketch line · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_loop.svg b/docs/CAD/ux/mockups/fresh__sk_loop.svg deleted file mode 100644 index 58eaa9e4fb..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_loop.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetClosed sketch loop selected — pick what to do with itFresh document · 8 slotsAdd material5Modify2Closed sketch loop \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_loop__add.svg b/docs/CAD/ux/mockups/fresh__sk_loop__add.svg deleted file mode 100644 index c6e6c90701..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_loop__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetAdd material — pick oneFresh document · 8 slotsExtrudeShift+ERevolveShift+RSurface ExtrudeShift+GSurface RevolveSurface FillClosed sketch loop · Add material \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_loop__modify.svg b/docs/CAD/ux/mockups/fresh__sk_loop__modify.svg deleted file mode 100644 index 416e62d7cd..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_loop__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditClosed sketch loop · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_none.svg b/docs/CAD/ux/mockups/fresh__sk_none.svg deleted file mode 100644 index ce7604c47d..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch, nothing picked selected — pick what to do with itFresh document · 8 slotsCreate9Reference2Sketch, nothing picked \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_none__create.svg b/docs/CAD/ux/mockups/fresh__sk_none__create.svg deleted file mode 100644 index 06994f9517..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_none__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_none__reference.svg b/docs/CAD/ux/mockups/fresh__sk_none__reference.svg deleted file mode 100644 index e4e558bbd9..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsDimensionDConstructionQSketch, nothing picked · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_point.svg b/docs/CAD/ux/mockups/fresh__sk_point.svg deleted file mode 100644 index 65acf94ac7..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_point.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch point selected — pick what to do with itFresh document · 8 slotsCreate9MoveReference2DeleteDelSketch point \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_point__create.svg b/docs/CAD/ux/mockups/fresh__sk_point__create.svg deleted file mode 100644 index fbe094d147..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_point__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch point · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_point__reference.svg b/docs/CAD/ux/mockups/fresh__sk_point__reference.svg deleted file mode 100644 index 8b02eba29f..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_point__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsDimensionDConstrainKSketch point · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__vertex.svg b/docs/CAD/ux/mockups/fresh__vertex.svg deleted file mode 100644 index 1e1661d6aa..0000000000 --- a/docs/CAD/ux/mockups/fresh__vertex.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetVertex selected — pick what to do with itFresh document · 8 slotsReference4Vertex \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__vertex__reference.svg b/docs/CAD/ux/mockups/fresh__vertex__reference.svg deleted file mode 100644 index aad3d46b6e..0000000000 --- a/docs/CAD/ux/mockups/fresh__vertex__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+AVertex · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/gen_offer_mockups.py b/docs/CAD/ux/mockups/gen_offer_mockups.py deleted file mode 100644 index 6ddd4caae4..0000000000 --- a/docs/CAD/ux/mockups/gen_offer_mockups.py +++ /dev/null @@ -1,884 +0,0 @@ -#!/usr/bin/env python3 -"""Render the object-driven tool offer from docs/ux/tool_atlas.json. - -Fork-neutral on purpose: this file and everything it emits name no product, so the -two forks carry byte-identical copies (the charter itself is the only doc that -substitutes the product name). - -Every mockup in docs/ux/mockups/ and the review page docs/ux/offer_atlas.html are -generated by this script. Nothing is hand-drawn: the point of the offer is that a -tool's address never changes, and a human drawing 40-odd states by hand is exactly -how an address quietly changes. - - python3 docs/ux/mockups/gen_offer_mockups.py - -It fails loudly rather than rendering a broken map: an unknown slot, an unknown -selection id in `accepts`, or one address holding two different verbs for the same -selection is an error, not a warning. - -SVG on purpose. There is no rsvg/inkscape/cairosvg on the build box and -ImageMagick would rasterise through its own weak internal renderer; SVG renders -exactly in a browser at any zoom and stays diffable in git. Rasterise later if -slides need it. -""" - -import json -import re -import math -import os -import sys -from collections import defaultdict - -HERE = os.path.dirname(os.path.abspath(__file__)) -UX = os.path.dirname(HERE) -ATLAS = os.path.join(UX, "tool_atlas.json") - -# The reach target from the charter (L11 / 6.1): if the ring plus a real part do not -# fit here, the design has failed before it is built. -W, H = 1366, 768 - -C = { - "app": "#1a1d21", "chrome": "#23272d", "panel": "#20242a", "line": "#31363d", - "vp0": "#2f353d", "vp1": "#242930", "grid": "#333a43", - "text": "#e7ecf1", "muted": "#8e9aa7", "dim": "#5f6a76", - "top": "#93a1b1", "left": "#6f7b89", "right": "#5a6472", "edge": "#39414b", - "hi": "#f5a623", "hi_soft": "#f5a62333", "sheet": "#7fa8c9", - "ring": "#171a1e", "chip": "#2e343c", "chip_line": "#3c444e", - "key": "#454f5b", "accent": "#4f9bd9", "empty": "#2a2f36", -} - - -# ---------------------------------------------------------------- glyphs -# Each glyph draws inside a 24x24 box centred on (0,0) — i.e. -12..12. -def _g(body): - return body - - -GLYPHS = { - # model - "sketch": '', - "extrude": '', - "revolve": '', - "sweep": '', - "loft": '', - "thicken": '', - "rib": '', - "boolean": '', - "hole": '', - "thread": '', - "shell": '', - "cut": '', - "split": '', - "fillet": '', - "chamfer": '', - "draft": '', - "surf_off": '', - "pattern": '', - "mirror": '', - "pat_curve": '', - "move": '', - "mate": '', - "align": '', - "plane": '', - "axis": '', - "csys": '', - "helix": '', - "project": '', - "measure": '', - "mass": '', - "interfere": '', - "edit": '', - "del_face": '', - "colour": '', - "delete": '', - # sketch primitives - "sk_line": '', - "sk_rect": '', - "sk_circle": '', - "sk_arc": '', - "sk_slot": '', - "sk_ell": '', - "sk_spline": '', - "sk_poly": '', - "sk_point": '', - "sk_offset": '', - "sk_trim": '', - "sk_ext": '', - "sk_mir": '', - "sk_move": '', - "sk_dim": '', - "sk_lock": '', - "sk_constr": '', - # families (used when a slot holds more than one verb) - "fam_create": '', - "fam_add": '', - "fam_remove": '', - "fam_dressup": '', - "fam_repeat": '', - "fam_transform": '', - "fam_reference": '', - # Deliberately NOT the bare pencil: create/sketch already owns that shape and the two slots - # are adjacent (N and NW). A pencil over a solid reads as "change the thing that exists". - "fam_modify": '' - '', -} - -VERB_GLYPH = { - "sketch": "sketch", "extrude": "extrude", "revolve": "revolve", "sweep": "sweep", - "loft": "loft", "thicken": "thicken", "rib": "rib", "boolean": "boolean", - "surf_extrude": "extrude", "surf_revolve": "revolve", "surf_loft": "loft", - "surf_fill": "surf_off", "thicken_surf": "thicken", "hole": "hole", "thread": "thread", - "shell": "shell", "cut": "cut", "split": "split", "fillet": "fillet", - "chamfer": "chamfer", "draft": "draft", "surf_offset": "surf_off", - "pattern": "pattern", "mirror": "mirror", "pat_curve": "pat_curve", - "transform": "move", "mate": "mate", "align": "align", "plane": "plane", - "axis": "axis", "coordsys_v": "csys", "helix": "helix", "project": "project", - "measure": "measure", "mass_props": "mass", "interference": "interfere", - "edit_feature": "edit", "delete_face": "del_face", "colour": "colour", "delete": "delete", - "sk_line_t": "sk_line", "sk_rect": "sk_rect", "sk_circle": "sk_circle", - "sk_arc_t": "sk_arc", "sk_slot": "sk_slot", "sk_ellipse": "sk_ell", - "sk_spline": "sk_spline", "sk_polygon": "sk_poly", "sk_point_t": "sk_point", - "sk_offset": "sk_offset", "sk_trim": "sk_trim", "sk_fillet": "fillet", - "sk_chamfer": "chamfer", "sk_mirror": "sk_mir", "sk_move": "sk_move", - "sk_dimension": "sk_dim", "sk_constrain": "sk_lock", "sk_construct": "sk_constr", - "sk_extend": "sk_ext", "sk_delete": "delete", -} - - -def glyph(name, cx, cy, colour, scale=1.0, sw=1.6): - body = GLYPHS.get(name, '') - return (f'{body}') - - -# ---------------------------------------------------------------- iso scene -COS30, SIN30 = math.cos(math.radians(30)), math.sin(math.radians(30)) - - -def iso(x, y, z, ox, oy, s=1.0): - return (ox + (x - y) * COS30 * s, oy + (x + y) * SIN30 * s - z * s) - - -def poly(pts, fill, stroke=None, extra=""): - d = " ".join(f"{x:.1f},{y:.1f}" for x, y in pts) - # Only emit our own stroke-width when the caller has not supplied one: a duplicate - # attribute is last-one-wins in a browser but invalid markup, and it is exactly the - # kind of thing a stricter renderer refuses outright. - if stroke: - st = f' stroke="{stroke}"' + ("" if "stroke-width" in extra else ' stroke-width="1"') - else: - st = ' stroke="none"' - return f'' - - -def box(ox, oy, w=150, d=105, h=52, s=1.0, hi=None): - """Three visible faces of a box. `hi` names the face/edge to highlight.""" - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - top = [P(0, 0, h), P(w, 0, h), P(w, d, h), P(0, d, h)] - left = [P(0, d, h), P(w, d, h), P(w, d, 0), P(0, d, 0)] - right = [P(w, 0, h), P(w, d, h), P(w, d, 0), P(w, 0, 0)] - out = [ - poly(left, C["left"], C["edge"]), - poly(right, C["right"], C["edge"]), - poly(top, C["hi"] if hi == "top" else C["top"], C["edge"]), - ] - if hi == "top": - out.append(poly(top, "none", "#ffd07a", ' stroke-width="2.5"')) - if hi == "front_edge": - a, b = P(0, d, h), P(w, d, h) - out.append(f'') - if hi == "vertex": - v = P(w, d, h) - out.append(f'') - if hi == "whole": - out.append(poly(top, "none", "#ffd07a", ' stroke-width="2.5"')) - out.append(poly(left, "none", "#ffd07a", ' stroke-width="2.5"')) - out.append(poly(right, "none", "#ffd07a", ' stroke-width="2.5"')) - return "".join(out), P - - -def bore(P, cx, cy, h, r=22, s=1.0, hi=False): - """A cylindrical bore through the top face, drawn as ellipse + wall.""" - c = P(cx, cy, h) - rx, ry = r * COS30 * 2 * s, r * SIN30 * 2 * s - col = C["hi"] if hi else "#20252b" - wall = C["hi"] if hi == "wall" else "#3b434d" - return (f'' - f'' - + (f'' if hi else "")), c - - -def scene(kind, ox, oy): - """Return (svg, anchor) for a selection kind. Anchor = where the ring centres.""" - s = 1.0 - if kind == "origin": - # A document with nothing in it: the three origin planes are all there is to click. - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g = poly([P(-70, -70, 0), P(70, -70, 0), P(70, 70, 0), P(-70, 70, 0)], - "#4f9bd91f", "#4f9bd977", ' stroke-width="1.5" stroke-dasharray="6 4"') - g += poly([P(-70, 0, -70), P(70, 0, -70), P(70, 0, 70), P(-70, 0, 70)], - "#e05c5c14", "#e05c5c66", ' stroke-width="1.5" stroke-dasharray="6 4"') - g += poly([P(0, -70, -70), P(0, 70, -70), P(0, 70, 70), P(0, -70, 70)], - "#5ce07a14", "#5ce07a66", ' stroke-width="1.5" stroke-dasharray="6 4"') - return g, P(0, 0, 0) - if kind == "empty": - g, P = box(ox, oy, s=s) - return g, P(75, 52, 26) - if kind == "box_top": - g, P = box(ox, oy, s=s, hi="top") - return g, P(75, 52, 52) - if kind == "box_whole": - g, P = box(ox, oy, s=s, hi="whole") - return g, P(75, 52, 26) - if kind == "box_edge": - g, P = box(ox, oy, s=s, hi="front_edge") - return g, P(75, 105, 52) - if kind == "box_vertex": - g, P = box(ox, oy, s=s, hi="vertex") - return g, P(150, 105, 52) - if kind in ("box_bore", "box_bore_rim"): - g, P = box(ox, oy, s=s) - b, c = bore(P, 75, 52, 52, hi=("wall" if kind == "box_bore" else True)) - return g + b, c - if kind == "box_fillet_face": - g, P = box(ox, oy, s=s) - a, b = P(0, 0, 52), P(0, 105, 52) - g += (f'') - return g, P(0, 52, 52) - if kind == "sheet": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - pts = [P(0, 0, 40), P(150, 0, 55), P(150, 105, 30), P(0, 105, 18)] - return (poly(pts, C["sheet"], "#ffd07a", ' stroke-width="2.5" opacity="0.85"'), - P(75, 52, 36)) - if kind == "two_boxes": - g1, P1 = box(ox - 60, oy - 10, w=110, d=80, h=44, hi="whole") - g2, P2 = box(ox + 70, oy + 26, w=95, d=70, h=60, hi="whole") - return g1 + g2, (ox + 42, oy + 6) - if kind == "datum": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - pts = [P(-25, -25, 70), P(175, -25, 70), P(175, 130, 70), P(-25, 130, 70)] - g += poly(pts, "#4f9bd933", C["hi"], ' stroke-width="2.5" stroke-dasharray="6 4"') - return g, P(75, 52, 70) - if kind == "axis": - g, P = box(ox, oy, s=s) - a, b = P(-30, 52, 52), P(180, 52, 52) - g += (f'') - return g, P(75, 52, 52) - if kind == "csys": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - o = P(0, 0, 52) - for tgt, col in ((P(60, 0, 52), "#e05c5c"), (P(0, 60, 52), "#5ce07a"), (P(0, 0, 112), "#5c9ce0")): - g += (f'') - g += f'' - return g, o - if kind == "art": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - c = P(75, 52, 52) - g += (f'' - f'ABC') - return g, c - if kind == "loop": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - pts = [P(28, 22, 52), P(122, 22, 52), P(122, 83, 52), P(28, 83, 52)] - g += poly(pts, C["hi_soft"], C["hi"], ' stroke-width="3"') - return g, P(75, 52, 52) - # --- sketch mode: flat, camera normal to the plane - gx, gy = ox - 30, oy - 10 - grid = "".join( - f'' - for i in range(11)) + "".join( - f'' - for i in range(16)) - if kind == "sk_empty": - return grid, (gx, gy) - if kind == "sk_line": - return (grid + f'' - f'' - f'', (gx, gy + 10)) - if kind == "sk_arc": - return (grid + f'', (gx, gy)) - if kind == "sk_point": - return (grid + f'', (gx, gy)) - if kind == "sk_two": - return (grid + f'' - f'', (gx, gy + 5)) - return grid, (gx, gy) - - -# ---------------------------------------------------------------- app chrome -def chrome(title, status, mode="model", empty_doc=False): - tabs = ["Prepare", "Preview", "Design"] - g = [f'', - f'' - f'' - f'', - f'', - f''] - x = 24 - for t in tabs: - on = (t == "Design") - g.append(f'{t}') - if on: - g.append(f'') - x += len(t) * 9 + 34 - # toolbar - g.append(f'' - f'') - fams = (["sketch", "extrude", "hole", "fillet", "pattern", "boolean", "plane", "move", "measure"] - if mode == "model" else - ["sk_line", "sk_rect", "sk_circle", "sk_arc", "sk_slot", "sk_spline", "sk_dim", "sk_trim", "sk_lock"]) - for i, gl in enumerate(fams): - cx = 40 + i * 46 - g.append(f'') - g.append(glyph(gl, cx, 68, C["muted"], 0.62, 1.7)) - # left rail - g.append(f'' - f'') - g.append(f'FEATURES') - # A "fresh document" mockup that shows six existing features is a lie, and it is the one - # state the group will look at hardest — it is the first-run picture (B5). - tree = ([] if empty_doc else - [("Sketch1", 0), ("Extrude1", 0), ("Hole1", 1), ("Fillet1", 1), ("Sketch2", 0), ("Extrude2", 0)]) - if empty_doc: - g.append(f'nothing yet') - for i, (n, ind) in enumerate(tree): - yy = 150 + i * 26 - g.append(glyph("sketch" if n.startswith("Sketch") else "extrude", 30 + ind * 14, yy - 4, C["dim"], 0.42, 1.8)) - g.append(f'{n}') - # status bar - g.append(f'' - f'{status}') - g.append(f'{title}') - return "".join(g) - - -# ---------------------------------------------------------------- the ring -def ring(cx, cy, items, capacity, sel_name, radius=134): - """items: dict angle_index -> (glyph, label, key, count) or None for an empty slot.""" - # The scrim is deliberately faint. §4.1: the offer "never blocks the view of what it acts - # on" — at 0.55 the disc swallowed the very face the ring was opened on, which is the rule - # failing in its own mockup. - g = [f'', - f'', - f''] - step = 360.0 / capacity - for i in range(capacity): - ang = math.radians(-90 + i * step) - px, py = cx + radius * math.cos(ang), cy + radius * math.sin(ang) - it = items.get(i) - if not it: - g.append(f'') - continue - gl, label, key, count = it - g.append(f'') - g.append(glyph(gl, px, py - 2, C["text"], 0.92, 1.7)) - g.append(f'{label}') - if key: - kw = 13 + len(key) * 6.6 - g.append(f'' - f'{key}') - if count and count > 1: - g.append(f'' - f'{count}') - # The selection name sits on the LOWER rim of the centre hole, not above it: above, it - # landed on top of the north slot's shortcut chip and hid it. Below, the pick stays - # visible through the hole and the pill is clear of the south chip at cy+104. - w = 13 + len(sel_name) * 6.9 - g.append(f'' - f'{sel_name}') - return "".join(g) - - -# ---------------------------------------------------------------- enumeration -def load(): - with open(ATLAS, encoding="utf-8") as f: - return json.load(f) - - -def validate(A): - slot_ids = {s["id"] for s in A["slots"]} - sel_ids = {s["id"] for s in A["selections"]} - errs = [] - seen = {} - for v in A["verbs"]: - if v["slot"] not in slot_ids: - errs.append(f'{v["id"]}: unknown slot {v["slot"]!r}') - for a in v["accepts"]: - if a not in sel_ids: - errs.append(f'{v["id"]}: accepts unknown selection {a!r}') - if v["id"] in seen: - errs.append(f'{v["id"]}: duplicate verb id') - seen[v["id"]] = v["slot"] - if errs: - sys.exit("tool_atlas.json is inconsistent:\n " + "\n ".join(errs)) - return slot_ids, sel_ids - - -def eligible(A, sel_id, doc): - sel = next(s for s in A["selections"] if s["id"] == sel_id) - out = [] - for v in A["verbs"]: - if v.get("mode", "model") != sel["mode"]: - continue - if sel_id not in v["accepts"]: - continue - n = v.get("needs") or {} - if n.get("bodies", 0) > doc["bodies"]: - continue - if n.get("sketches", 0) > doc["sketches"]: - continue - if n.get("sheet") and not doc["sheet"]: - continue - out.append(v) - return out - - -def by_slot(A, verbs): - order = [s["id"] for s in A["slots"]] - d = defaultdict(list) - for v in verbs: - d[v["slot"]].append(v) - return {k: d[k] for k in order if d[k]} - - -def ring_items(A, grouped): - order = [s["id"] for s in A["slots"]] - slot_label = {s["id"]: s["label"] for s in A["slots"]} - items = {} - for i, sid in enumerate(order): - vs = grouped.get(sid) - if not vs: - continue - if len(vs) == 1: - v = vs[0] - items[i] = (VERB_GLYPH.get(v["id"], "fam_" + sid), v["name"], v.get("key"), 1) - else: - items[i] = ("fam_" + sid, slot_label[sid], None, len(vs)) - return items - - -# ---------------------------------------------------------------- rendering -def menu(cx, cy, header, rows, submenu=None, sub_at=None): - """Vertical list form of the offer. rows: (glyph, name, key, count, enabled, reason). - - The invariant is unchanged — a verb has one permanent row index, and rows that do not - apply are DISABLED IN PLACE, never removed. What changes against the ring is what an - unavailable slot can say: an empty circle says nothing, a greyed row says its own name - and the reason it is grey, in the words the product already ships. - """ - RW, RH, HD = 324, 34, 38 - # The reason line is the whole point of a disabled row, so it must FIT: at 10px italic a - # glyph is ~4.9px, and anything past the box edge is a promise the layout does not keep. - fit = int((RW - 62) / 4.9) - x, y = cx + 26, cy - 30 - h = HD + len(rows) * RH + 10 - if y + h > H - 44: - y = max(100, H - 44 - h) - g = [f'', - f'', - f'{header.upper()}', - f''] - # a leader from the pick point to the menu, so the list is visibly ABOUT that geometry - g.insert(0, f'') - g.insert(0, f'') - for i, (gl, name, key, count, on, reason) in enumerate(rows): - ry = y + HD + i * RH - op = "1" if on else "0.34" - if on and i == 0: - g.append(f'') - g.append(f'') - g.append(glyph(gl, x + 26, ry + RH / 2, C["text"], 0.72, 1.7)) - g.append(f'{name}') - if key: - kw = 13 + len(key) * 6.6 - g.append(f'' - f'{key}') - elif count and count > 1: - g.append(f'') - g.append(f'{count}') - g.append('') - if not on and reason: - r = reason if len(reason) <= fit else reason[:fit - 1].rstrip(" ,—-") + "…" - g.append(f'{r}') - if submenu: - sy = y + HD + (sub_at or 0) * RH - 6 - sh = 12 + len(submenu) * RH - sx = x + RW + 8 - g.append(f'') - g.append(f'') - for i, (gl, name, key, _c, on, _r) in enumerate(submenu): - ry = sy + 6 + i * RH - g.append(f'') - g.append(glyph(gl, sx + 24, ry + RH / 2, C["text"], 0.72, 1.7)) - g.append(f'{name}') - if key: - kw = 13 + len(key) * 6.6 - g.append(f'' - f'{key}') - g.append('') - return "".join(g) - - -OVERFLOWS = [] # (selection, doc state, family, verbs that did not fit the sub-ring) - - -def svg_doc(inner): - return (f'{inner}') - - -def render_list_state(A, sel, doc, expand=None): - """The vertical-list form: every family row always present, in the same order, with the - ones that do not apply disabled and carrying their reason.""" - verbs = eligible(A, sel["id"], doc) - grouped = by_slot(A, verbs) - fresh = doc["bodies"] == 0 and doc["sketches"] == 0 - shape = "origin" if (fresh and sel["shape"] == "empty") else sel["shape"] - art, (ax, ay) = scene(shape, 620, 360) - rows, sub, sub_at = [], None, None - for idx, s in enumerate(A["slots"]): - vs = grouped.get(s["id"], []) - if len(vs) == 1: - v = vs[0] - rows.append((VERB_GLYPH.get(v["id"], "fam_" + s["id"]), v["name"], v.get("key"), 1, True, None)) - elif len(vs) > 1: - rows.append(("fam_" + s["id"], s["label"], None, len(vs), True, None)) - if expand == s["id"]: - sub_at = idx - sub = [(VERB_GLYPH.get(v["id"], "fam_" + s["id"]), v["name"], v.get("key"), 1, True, None) - for v in vs] - else: - # Disabled in place, with the product's own refusal text — the thing an empty - # slot in the ring could never say. - cands = [v for v in A["verbs"] - if v["slot"] == s["id"] and v.get("mode", "model") == sel["mode"]] - why = next((v["refusal"] for v in cands if v.get("refusal")), None) - rows.append(("fam_" + s["id"], s["label"], None, 0, False, why)) - status = ("Right-click the geometry to see what you can do with it" if not expand - else f'{sel["name"]} — pick one') - inner = chrome(f'{doc["name"]} · vertical list', status, sel["mode"], empty_doc=fresh) - inner += art - inner += menu(ax, ay, sel["name"], rows, sub, sub_at) - return svg_doc(inner) - - -def render_state(A, sel, doc, capacity=8, secondary=None): - verbs = eligible(A, sel["id"], doc) - grouped = by_slot(A, verbs) - anchor_x, anchor_y = 810, 400 - fresh = doc["bodies"] == 0 and doc["sketches"] == 0 - shape = "origin" if (fresh and sel["shape"] == "empty") else sel["shape"] - art, (ax, ay) = scene(shape, anchor_x - 90, anchor_y - 40) - if secondary: - vs = grouped[secondary] - # A sub-ring ANCHORS ON ITS PARENT'S DIRECTION. Fanning from north instead put Extrude - # at N — Create's address in the primary map — so the second level contradicted the - # first. Anchored, an address is two consistent strokes: Add material is NE, and the - # first verb of Add material is NE again. - base = [s["id"] for s in A["slots"]].index(secondary) - overflow = [] - if len(vs) > capacity: - # Do NOT wrap: (base+i) % capacity would quietly put verb 9 on top of verb 1, which - # is the invariant failing silently — the one outcome worse than an ugly ring. Show - # what fits, mark the rest, and report it. - overflow = vs[capacity - 1:] - vs = vs[:capacity - 1] - items = {(base + i) % capacity: - (VERB_GLYPH.get(v["id"], "fam_" + secondary), v["name"], v.get("key"), 1) - for i, v in enumerate(vs)} - if overflow: - items[(base + capacity - 1) % capacity] = ("fam_" + secondary, "More", None, len(overflow)) - OVERFLOWS.append((sel["name"], doc["id"], secondary, [v["name"] for v in overflow])) - label = next(s["label"] for s in A["slots"] if s["id"] == secondary) - sel_name = f'{sel["name"]} · {label}' - status = f'{label} — pick one' - else: - items = ring_items(A, grouped) - sel_name = sel["name"] - status = ("Click a face or a reference plane, then a tool" - if sel["id"] == "none" else f'{sel["name"]} selected — pick what to do with it') - inner = chrome(f'{doc["name"]} · {capacity} slots', status, sel["mode"], empty_doc=fresh) - inner += art - inner += ring(ax, ay, items, capacity, sel_name) - return svg_doc(inner), verbs, grouped - - -def main(): - A = load() - validate(A) - docs = {d["id"]: d for d in A["doc_states"]} - outdir = HERE - rows, files = [], [] - total_primary = total_secondary = 0 - fill_sum = fill_n = 0 - - for d in A["doc_states"]: - for sel in A["selections"]: - svg, verbs, grouped = render_state(A, sel, d) - name = f'{d["id"]}__{sel["id"]}.svg' - with open(os.path.join(outdir, name), "w", encoding="utf-8") as f: - f.write(svg) - files.append((name, f'{sel["name"]} — {d["name"]}')) - total_primary += 1 - fill_sum += len(grouped) - fill_n += 1 - secondaries = [] - for sid, vs in grouped.items(): - if len(vs) > 1: - s2, _, _ = render_state(A, sel, d, secondary=sid) - n2 = f'{d["id"]}__{sel["id"]}__{sid}.svg' - with open(os.path.join(outdir, n2), "w", encoding="utf-8") as f: - f.write(s2) - label = next(s["label"] for s in A["slots"] if s["id"] == sid) - files.append((n2, f'{sel["name"]} — {label} ring')) - secondaries.append(sid) - total_secondary += 1 - rows.append({ - "doc": d["name"], "sel": sel["name"], "mode": sel["mode"], - "verbs": len(verbs), "slots": len(grouped), - "second": len(secondaries), - "detail": {sid: [v["name"] for v in vs] for sid, vs in grouped.items()}, - }) - - # Form-factor comparison: the SAME state as a ring and as a vertical list. - for sid in ("face_planar", "edge_str", "body_solid", "sk_line", "none"): - sel = next(s for s in A["selections"] if s["id"] == sid) - d = docs["fresh"] if sid == "none" else docs["rich"] - with open(os.path.join(outdir, f"list__{sid}.svg"), "w", encoding="utf-8") as f: - f.write(render_list_state(A, sel, d)) - for sid, fam in (("face_planar", "add"), ("sk_none", "create")): - sel = next(s for s in A["selections"] if s["id"] == sid) - with open(os.path.join(outdir, f"list__{sid}__{fam}.svg"), "w", encoding="utf-8") as f: - f.write(render_list_state(A, sel, docs["rich"], expand=fam)) - - # comparison sheet: 8 vs 12 slots on the same three selections - for cap in (8, 12): - for sid in ("face_planar", "edge_str", "sk_line"): - sel = next(s for s in A["selections"] if s["id"] == sid) - svg, _, _ = render_state(A, sel, docs["rich"], capacity=cap) - n = f'cmp_{cap}__{sid}.svg' - with open(os.path.join(outdir, n), "w", encoding="utf-8") as f: - f.write(svg) - - write_atlas(A, rows, files, total_primary, total_secondary, - fill_sum / max(1, fill_n)) - print(f"{total_primary} primary + {total_secondary} secondary = " - f"{total_primary+total_secondary} offer states rendered") - print(f"mean populated slots per primary ring: {fill_sum/max(1,fill_n):.2f} of 8") - if OVERFLOWS: - seen = {(f, tuple(v)) for _, _, f, v in OVERFLOWS} - print(f"OVERFLOW: {len(OVERFLOWS)} sub-rings did not fit 8 slots — " - f"{len(seen)} distinct case(s):") - for f, v in sorted(seen): - print(f" {f}: {', '.join(v)} pushed behind 'More'") - - -def write_atlas(A, rows, files, n_prim, n_sec, mean_fill): - gui_missing = [v["name"] for v in A["verbs"] if not v.get("gui", True)] - esc = lambda s: (s.replace("&", "&").replace("<", "<").replace(">", ">")) - cards = "".join( - f'
{esc(t)}
{esc(t)}
' - for n, t in files) - cmp8 = "".join(f'
' - f'
8 slots — {s}
' - for s in ("face_planar", "edge_str", "sk_line")) - cmp12 = "".join(f'
' - f'
12 slots — {s}
' - for s in ("face_planar", "edge_str", "sk_line")) - if OVERFLOWS: - cases = sorted({(f, tuple(v)) for _, _, f, v in OVERFLOWS}) - over_html = ("Measured, not predicted: " + "; ".join( - f'the {esc(f)} sub-ring needs {8 + len(v)} addresses, so ' - f'{esc(", ".join(v))} {"is" if len(v) == 1 else "are"} pushed behind a “More” slot' - for f, v in cases) + - ". This is the decision the ring size actually turns on — either a verb moves to " - "another family, or the tail goes to a third level, or the ring is not eight. " - "It affects sketch mode only; every model-mode family fits.") - else: - over_html = "No sub-ring exceeds the ring capacity. Eight slots is sufficient everywhere." - trs = "".join( - f'{esc(r["sel"])}{esc(r["doc"])}{r["verbs"]}' - f'{r["slots"]}/8{r["second"]}' - f'{esc(" · ".join(k + ": " + ", ".join(v) for k, v in r["detail"].items()))}' - for r in rows) - html = f"""Design tab — offer atlas - -
-

The offer — atlas of every state

-

Every state of the object-driven tool offer, generated from - docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that - address is the same in every selection where it appears, and slots that do not apply are drawn - empty rather than compacted.

-
-
{len(A["verbs"])}verbs mapped
-
{len(A["selections"])}selection kinds
-
{n_prim}primary rings
-
{n_sec}secondary rings
-
{n_prim+n_sec}states total
-
{mean_fill:.1f}/8mean slots filled
-
{len(gui_missing)}verbs with no GUI yet
-
-
-
-

Decision 0 — ring or vertical list

-

The live question. Both forms carry the SAME map and the same invariant — fixed order, never - re-sorted, nothing compacted; only the geometry differs. Left-click selects; right-click opens the - offer. What the list buys: a disabled row can state its own reason in the words the product - already ships, where an empty slot in a ring is mute; nine sketch primitives fit without an - overflow; shortcuts line up in a readable column; long translated names fit; and it is navigable - by arrow key and by screen reader, which a radial is not. What it costs: no equidistant flick - gesture, and travel to the last row is longer than to the nearest direction. Pairs below — - list first, the same state as a ring second.

- -

Decision 1 — ring capacity

-

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is - the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses - for more verbs at 30° spacing and positions that stop being nameable.

-
{cmp8}
-
{cmp12}
- -

Decision 2 — one map or one per mode

-

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, - so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode - states below against the model-mode ones — if a verb that exists in both modes ever appears at two - addresses, the shared map has failed and the split map is the answer.

- -

The matrix — every selection, every document state

-
- - {trs} -
SelectionDocumentVerbsSlots2nd ringsWhat lands where
- -

Overflow — the one place eight slots is not enough

-

{over_html}

- -

Not in the offer

-

{esc(", ".join(A["chrome_only"]["items"]))} — these act on the document, not on a selection, - so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: - {esc(", ".join(gui_missing))}.

- -

All states

-
{cards}
-
-""" - with open(os.path.join(UX, "offer_atlas.html"), "w", encoding="utf-8") as f: - f.write(html) - - # A second, SELF-CONTAINED copy for review outside the repo: the artifact host blocks - # every external request, so relative would silently show nothing. Curated - # rather than all 113 states — the whole set inlined is 1.5 MB, which is a poor thing to - # send to the low-end machine this design is meant to serve (6.1). - def inline(name): - p = os.path.join(HERE, name) - if not os.path.exists(p): - return "" - s = open(p, encoding="utf-8").read() - return s.replace("{inline(n)}
{esc(t)}
' - for n, t in picks if inline(n)) - head, _, tail = html.partition('

All states

') - # The comparison grids in the head use , which resolves to nothing - # once the page is served on its own. Inline those too rather than shipping empty frames. - head = re.sub(r']*>', - lambda m: inline(m.group(1)), head) - inline_html = head + '

The states

\n
' + figs + '
\n' - with open(os.path.join(UX, "offer_atlas_inline.html"), "w", encoding="utf-8") as f: - f.write(inline_html) - - -if __name__ == "__main__": - main() diff --git a/docs/CAD/ux/mockups/list__body_solid.svg b/docs/CAD/ux/mockups/list__body_solid.svg deleted file mode 100644 index ec3b3a84f4..0000000000 --- a/docs/CAD/ux/mockups/list__body_solid.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSOLID BODYCreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemove3Dress-up2Repeat3MoveShift+YReference3Modify3 \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__edge_str.svg b/docs/CAD/ux/mockups/list__edge_str.svg deleted file mode 100644 index 3942000d25..0000000000 --- a/docs/CAD/ux/mockups/list__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSTRAIGHT EDGECreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-up2Pattern on CurveTransformTransform needs a body — add or import one firstReference3ModifyDelete Face needs a body — add or import one first \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__face_planar.svg b/docs/CAD/ux/mockups/list__face_planar.svg deleted file mode 100644 index 5ff6892902..0000000000 --- a/docs/CAD/ux/mockups/list__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2 \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__face_planar__add.svg b/docs/CAD/ux/mockups/list__face_planar__add.svg deleted file mode 100644 index fb80f2a5c7..0000000000 --- a/docs/CAD/ux/mockups/list__face_planar__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face — pick oneWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2ExtrudeShift+EThicken \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__none.svg b/docs/CAD/ux/mockups/list__none.svg deleted file mode 100644 index 1e68606383..0000000000 --- a/docs/CAD/ux/mockups/list__none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetRight-click the geometry to see what you can do with itFresh document · vertical listNOTHING SELECTEDSketchShift+SAdd materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-upPick an edge to roundRepeatCreate a solid body to pattern firstTransformTransform needs a body — add or import one firstReference4ModifyDelete Face needs a body — add or import one first \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__sk_line.svg b/docs/CAD/ux/mockups/list__sk_line.svg deleted file mode 100644 index 1b1c2e9cd2..0000000000 --- a/docs/CAD/ux/mockups/list__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSKETCH LINECreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2 \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__sk_none__create.svg b/docs/CAD/ux/mockups/list__sk_none__create.svg deleted file mode 100644 index 0b41268fa6..0000000000 --- a/docs/CAD/ux/mockups/list__sk_none__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked — pick oneWorking document · vertical listSKETCH, NOTHING PICKEDCreate9Add materialRemoveDress-upRepeatTransformReference2ModifyLineLRectangleRCircleCArcASlotSEllipseESplineBPolygonGPointP \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__art.svg b/docs/CAD/ux/mockups/rich__art.svg deleted file mode 100644 index e835ed1ce0..0000000000 --- a/docs/CAD/ux/mockups/rich__art.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Text / imported art selected — pick what to do with itWorking document · 8 slotsABCPatternShift+NMoveShift+YModify2Text / imported art \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__art__modify.svg b/docs/CAD/ux/mockups/rich__art__modify.svg deleted file mode 100644 index 4c8cdef2b5..0000000000 --- a/docs/CAD/ux/mockups/rich__art__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsABCDeleteDelEditText / imported art · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__bodies_2.svg b/docs/CAD/ux/mockups/rich__bodies_2.svg deleted file mode 100644 index a977b7f1de..0000000000 --- a/docs/CAD/ux/mockups/rich__bodies_2.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two bodies selected — pick what to do with itWorking document · 8 slotsCombineShift+BMateReference2DeleteDelTwo bodies \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__bodies_2__reference.svg b/docs/CAD/ux/mockups/rich__bodies_2__reference.svg deleted file mode 100644 index 1bfbac0db0..0000000000 --- a/docs/CAD/ux/mockups/rich__bodies_2__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasureInterferenceTwo bodies · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_sheet.svg b/docs/CAD/ux/mockups/rich__body_sheet.svg deleted file mode 100644 index a1cc27808d..0000000000 --- a/docs/CAD/ux/mockups/rich__body_sheet.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sheet body selected — pick what to do with itWorking document · 8 slotsThicken SurfaceSurface OffsetMoveShift+YMeasureModify3Sheet body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_sheet__modify.svg b/docs/CAD/ux/mockups/rich__body_sheet__modify.svg deleted file mode 100644 index 7ce8dbee54..0000000000 --- a/docs/CAD/ux/mockups/rich__body_sheet__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsColourDeleteDelEditSheet body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid.svg b/docs/CAD/ux/mockups/rich__body_solid.svg deleted file mode 100644 index e958532347..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Solid body selected — pick what to do with itWorking document · 8 slotsRemove3Dress-up2Repeat3MoveShift+YReference3Modify3Solid body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__dressup.svg b/docs/CAD/ux/mockups/rich__body_solid__dressup.svg deleted file mode 100644 index 7a9ceed334..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferSolid body · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__modify.svg b/docs/CAD/ux/mockups/rich__body_solid__modify.svg deleted file mode 100644 index 7a6340d40f..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsColourDeleteDelEditSolid body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__reference.svg b/docs/CAD/ux/mockups/rich__body_solid__reference.svg deleted file mode 100644 index 27639836c6..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMassProjectMeasureSolid body · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__remove.svg b/docs/CAD/ux/mockups/rich__body_solid__remove.svg deleted file mode 100644 index edbddb7115..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__remove.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsShellShift+KCutShift+XSplitSolid body · Remove \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__repeat.svg b/docs/CAD/ux/mockups/rich__body_solid__repeat.svg deleted file mode 100644 index 74dd67c7de..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__repeat.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Repeat — pick oneWorking document · 8 slotsPatternShift+NMirrorShift+ZPattern on CurveSolid body · Repeat \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__coordsys.svg b/docs/CAD/ux/mockups/rich__coordsys.svg deleted file mode 100644 index 8cef106106..0000000000 --- a/docs/CAD/ux/mockups/rich__coordsys.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Coordinate system selected — pick what to do with itWorking document · 8 slotsMateModify2Coordinate system \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__coordsys__modify.svg b/docs/CAD/ux/mockups/rich__coordsys__modify.svg deleted file mode 100644 index 92eb28d3dc..0000000000 --- a/docs/CAD/ux/mockups/rich__coordsys__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditCoordinate system · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_axis.svg b/docs/CAD/ux/mockups/rich__datum_axis.svg deleted file mode 100644 index c9da648ab7..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_axis.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum axis selected — pick what to do with itWorking document · 8 slotsModify2Datum axis \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_axis__modify.svg b/docs/CAD/ux/mockups/rich__datum_axis__modify.svg deleted file mode 100644 index fd0ae80c52..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_axis__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditDatum axis · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane.svg b/docs/CAD/ux/mockups/rich__datum_plane.svg deleted file mode 100644 index 8ef88bd9a3..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum plane selected — pick what to do with itWorking document · 8 slotsSketchShift+SRemove2MirrorShift+ZReference3Modify2Datum plane \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane__modify.svg b/docs/CAD/ux/mockups/rich__datum_plane__modify.svg deleted file mode 100644 index 39e5cad41e..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditDatum plane · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane__reference.svg b/docs/CAD/ux/mockups/rich__datum_plane__reference.svg deleted file mode 100644 index bae3119b6b..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsProjectPlaneShift+PHelixDatum plane · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane__remove.svg b/docs/CAD/ux/mockups/rich__datum_plane__remove.svg deleted file mode 100644 index c98b33ad31..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane__remove.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsHoleShift+HCutShift+XDatum plane · Remove \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_circ.svg b/docs/CAD/ux/mockups/rich__edge_circ.svg deleted file mode 100644 index 1d07291623..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_circ.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Circular edge selected — pick what to do with itWorking document · 8 slotsThreadShift+TDress-up2MeasureCircular edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_circ__dressup.svg b/docs/CAD/ux/mockups/rich__edge_circ__dressup.svg deleted file mode 100644 index b315fc2e22..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_circ__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferCircular edge · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_str.svg b/docs/CAD/ux/mockups/rich__edge_str.svg deleted file mode 100644 index 2c41ce74fc..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_str__dressup.svg b/docs/CAD/ux/mockups/rich__edge_str__dressup.svg deleted file mode 100644 index 8e674c044f..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_str__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferStraight edge · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_str__reference.svg b/docs/CAD/ux/mockups/rich__edge_str__reference.svg deleted file mode 100644 index bc99ca6a13..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_str__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasurePlaneShift+PAxisShift+AStraight edge · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_cyl.svg b/docs/CAD/ux/mockups/rich__face_cyl.svg deleted file mode 100644 index 3c2860373f..0000000000 --- a/docs/CAD/ux/mockups/rich__face_cyl.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Cylindrical face selected — pick what to do with itWorking document · 8 slotsThreadShift+TReference3Modify2Cylindrical face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_cyl__modify.svg b/docs/CAD/ux/mockups/rich__face_cyl__modify.svg deleted file mode 100644 index 9f573682ad..0000000000 --- a/docs/CAD/ux/mockups/rich__face_cyl__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditCylindrical face · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_cyl__reference.svg b/docs/CAD/ux/mockups/rich__face_cyl__reference.svg deleted file mode 100644 index a62be81de8..0000000000 --- a/docs/CAD/ux/mockups/rich__face_cyl__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasureAxisShift+AHelixCylindrical face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_other.svg b/docs/CAD/ux/mockups/rich__face_other.svg deleted file mode 100644 index e5cff4eee5..0000000000 --- a/docs/CAD/ux/mockups/rich__face_other.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Curved face selected — pick what to do with itWorking document · 8 slotsThickenDraftShift+DMeasureModify2Curved face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_other__modify.svg b/docs/CAD/ux/mockups/rich__face_other__modify.svg deleted file mode 100644 index 8b5fcfd63f..0000000000 --- a/docs/CAD/ux/mockups/rich__face_other__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditCurved face · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar.svg b/docs/CAD/ux/mockups/rich__face_planar.svg deleted file mode 100644 index 5a58e2fb72..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__add.svg b/docs/CAD/ux/mockups/rich__face_planar__add.svg deleted file mode 100644 index 82acc85038..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__dressup.svg b/docs/CAD/ux/mockups/rich__face_planar__dressup.svg deleted file mode 100644 index 8d32b9f212..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferDraftShift+DPlanar face · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__modify.svg b/docs/CAD/ux/mockups/rich__face_planar__modify.svg deleted file mode 100644 index bffd218131..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditPlanar face · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__reference.svg b/docs/CAD/ux/mockups/rich__face_planar__reference.svg deleted file mode 100644 index 4682f1e7b1..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CProjectMeasurePlaneShift+PAxisShift+APlanar face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__remove.svg b/docs/CAD/ux/mockups/rich__face_planar__remove.svg deleted file mode 100644 index b77a5a0c50..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__remove.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsHoleShift+HShellShift+KPlanar face · Remove \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__transform.svg b/docs/CAD/ux/mockups/rich__face_planar__transform.svg deleted file mode 100644 index 2e27983c8b..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__transform.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Transform — pick oneWorking document · 8 slotsMateAlign toPlanar face · Transform \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__none.svg b/docs/CAD/ux/mockups/rich__none.svg deleted file mode 100644 index 4e8a9dc640..0000000000 --- a/docs/CAD/ux/mockups/rich__none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Click a face or a reference plane, then a toolWorking document · 8 slotsSketchShift+SReference4Nothing selected \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__none__reference.svg b/docs/CAD/ux/mockups/rich__none__reference.svg deleted file mode 100644 index 14c47c4b27..0000000000 --- a/docs/CAD/ux/mockups/rich__none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CHelixPlaneShift+PAxisShift+ANothing selected · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent.svg b/docs/CAD/ux/mockups/rich__sk_2ent.svg deleted file mode 100644 index 738b01ecf2..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two sketch entities selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__create.svg b/docs/CAD/ux/mockups/rich__sk_2ent__create.svg deleted file mode 100644 index 6d27ffa34a..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Two sketch entities · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__dressup.svg b/docs/CAD/ux/mockups/rich__sk_2ent__dressup.svg deleted file mode 100644 index 929520b8d2..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletFChamferHTwo sketch entities · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__modify.svg b/docs/CAD/ux/mockups/rich__sk_2ent__modify.svg deleted file mode 100644 index d8be7c2d4f..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXTwo sketch entities · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__reference.svg b/docs/CAD/ux/mockups/rich__sk_2ent__reference.svg deleted file mode 100644 index 9ffc2592a8..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKTwo sketch entities · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc.svg b/docs/CAD/ux/mockups/rich__sk_arc.svg deleted file mode 100644 index d470369f1a..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch arc or circle selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc__create.svg b/docs/CAD/ux/mockups/rich__sk_arc__create.svg deleted file mode 100644 index 1f901596ec..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch arc or circle · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc__modify.svg b/docs/CAD/ux/mockups/rich__sk_arc__modify.svg deleted file mode 100644 index 52f9d7d3e5..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXSketch arc or circle · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc__reference.svg b/docs/CAD/ux/mockups/rich__sk_arc__reference.svg deleted file mode 100644 index 53e949c184..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKSketch arc or circle · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line.svg b/docs/CAD/ux/mockups/rich__sk_line.svg deleted file mode 100644 index 4ca4000d59..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__create.svg b/docs/CAD/ux/mockups/rich__sk_line__create.svg deleted file mode 100644 index c37f2d0e45..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch line · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__dressup.svg b/docs/CAD/ux/mockups/rich__sk_line__dressup.svg deleted file mode 100644 index 29e86762d2..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletFChamferHSketch line · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__modify.svg b/docs/CAD/ux/mockups/rich__sk_line__modify.svg deleted file mode 100644 index b9775b7d94..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXSketch line · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__reference.svg b/docs/CAD/ux/mockups/rich__sk_line__reference.svg deleted file mode 100644 index 6eb1ef621f..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKSketch line · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_loop.svg b/docs/CAD/ux/mockups/rich__sk_loop.svg deleted file mode 100644 index c07d1c09c3..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_loop.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Closed sketch loop selected — pick what to do with itWorking document · 8 slotsAdd material8PatternShift+NModify2Closed sketch loop \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_loop__add.svg b/docs/CAD/ux/mockups/rich__sk_loop__add.svg deleted file mode 100644 index bf9f429b81..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_loop__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsSurface FillExtrudeShift+ERevolveShift+RSweepShift+WLoftShift+LSurface ExtrudeShift+GSurface RevolveSurface LoftClosed sketch loop · Add material \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_loop__modify.svg b/docs/CAD/ux/mockups/rich__sk_loop__modify.svg deleted file mode 100644 index c466379c9e..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_loop__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditClosed sketch loop · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_none.svg b/docs/CAD/ux/mockups/rich__sk_none.svg deleted file mode 100644 index ffe49ab9a0..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked selected — pick what to do with itWorking document · 8 slotsCreate9Reference2Sketch, nothing picked \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_none__create.svg b/docs/CAD/ux/mockups/rich__sk_none__create.svg deleted file mode 100644 index c9a2bc698d..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_none__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_none__reference.svg b/docs/CAD/ux/mockups/rich__sk_none__reference.svg deleted file mode 100644 index cc9d465fa4..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsDimensionDConstructionQSketch, nothing picked · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_point.svg b/docs/CAD/ux/mockups/rich__sk_point.svg deleted file mode 100644 index f089787bca..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_point.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch point selected — pick what to do with itWorking document · 8 slotsCreate9MoveReference2DeleteDelSketch point \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_point__create.svg b/docs/CAD/ux/mockups/rich__sk_point__create.svg deleted file mode 100644 index 5d2070a6c5..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_point__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch point · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_point__reference.svg b/docs/CAD/ux/mockups/rich__sk_point__reference.svg deleted file mode 100644 index e090382a24..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_point__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsDimensionDConstrainKSketch point · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__vertex.svg b/docs/CAD/ux/mockups/rich__vertex.svg deleted file mode 100644 index f37bbd7d47..0000000000 --- a/docs/CAD/ux/mockups/rich__vertex.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Vertex selected — pick what to do with itWorking document · 8 slotsReference4Vertex \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__vertex__reference.svg b/docs/CAD/ux/mockups/rich__vertex__reference.svg deleted file mode 100644 index ceabba032e..0000000000 --- a/docs/CAD/ux/mockups/rich__vertex__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+AVertex · Reference \ No newline at end of file diff --git a/docs/CAD/ux/offer_atlas.html b/docs/CAD/ux/offer_atlas.html deleted file mode 100644 index 35c4f5860c..0000000000 --- a/docs/CAD/ux/offer_atlas.html +++ /dev/null @@ -1,78 +0,0 @@ -Design tab — offer atlas - -
-

The offer — atlas of every state

-

Every state of the object-driven tool offer, generated from - docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that - address is the same in every selection where it appears, and slots that do not apply are drawn - empty rather than compacted.

-
-
60verbs mapped
-
20selection kinds
-
40primary rings
-
73secondary rings
-
113states total
-
3.5/8mean slots filled
-
5verbs with no GUI yet
-
-
-
-

Decision 0 — ring or vertical list

-

The live question. Both forms carry the SAME map and the same invariant — fixed order, never - re-sorted, nothing compacted; only the geometry differs. Left-click selects; right-click opens the - offer. What the list buys: a disabled row can state its own reason in the words the product - already ships, where an empty slot in a ring is mute; nine sketch primitives fit without an - overflow; shortcuts line up in a readable column; long translated names fit; and it is navigable - by arrow key and by screen reader, which a radial is not. What it costs: no equidistant flick - gesture, and travel to the last row is longer than to the nearest direction. Pairs below — - list first, the same state as a ring second.

- -

Decision 1 — ring capacity

-

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is - the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses - for more verbs at 30° spacing and positions that stop being nameable.

-
8 slots — face_planar
8 slots — edge_str
8 slots — sk_line
-
12 slots — face_planar
12 slots — edge_str
12 slots — sk_line
- -

Decision 2 — one map or one per mode

-

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, - so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode - states below against the model-mode ones — if a verb that exists in both modes ever appears at two - addresses, the shared map has failed and the split map is the answer.

- -

The matrix — every selection, every document state

-
- - -
SelectionDocumentVerbsSlots2nd ringsWhat lands where
Nothing selectedWorking document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceWorking document188/86create: Sketch · add: Extrude, Thicken · remove: Hole, Shell · dressup: Fillet, Chamfer, Draft · repeat: Pattern · transform: Mate, Align to · reference: Plane, Axis, Coord Sys, Project, Measure · modify: Edit, Delete Face
Cylindrical faceWorking document63/82remove: Thread · reference: Axis, Helix, Measure · modify: Edit, Delete Face
Curved faceWorking document54/81add: Thicken · dressup: Draft · reference: Measure · modify: Edit, Delete Face
Straight edgeWorking document63/82dressup: Fillet, Chamfer · repeat: Pattern on Curve · reference: Plane, Axis, Measure
Circular edgeWorking document43/81remove: Thread · dressup: Fillet, Chamfer · reference: Measure
VertexWorking document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyWorking document156/85remove: Shell, Cut, Split · dressup: Fillet, Chamfer · repeat: Pattern, Mirror, Pattern on Curve · transform: Move · reference: Project, Measure, Mass · modify: Edit, Colour, Delete
Sheet bodyWorking document75/81add: Thicken Surface · dressup: Surface Offset · transform: Move · reference: Measure · modify: Edit, Colour, Delete
Two bodiesWorking document54/81add: Combine · transform: Mate · reference: Measure, Interference · modify: Delete
Datum planeWorking document95/83create: Sketch · remove: Hole, Cut · repeat: Mirror · reference: Plane, Helix, Project · modify: Edit, Delete
Datum axisWorking document21/81modify: Edit, Delete
Coordinate systemWorking document32/81transform: Mate · modify: Edit, Delete
Text / imported artWorking document43/81repeat: Pattern · transform: Move · modify: Edit, Delete
Closed sketch loopWorking document113/82add: Extrude, Revolve, Sweep, Loft, Surface Extrude, Surface Revolve, Surface Loft, Surface Fill · repeat: Pattern · modify: Edit, Delete
Sketch, nothing pickedWorking document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleWorking document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointWorking document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Nothing selectedFresh document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceFresh document74/81create: Sketch · add: Extrude · reference: Plane, Axis, Coord Sys, Measure · modify: Edit
Cylindrical faceFresh document42/81reference: Axis, Helix, Measure · modify: Edit
Curved faceFresh document22/80reference: Measure · modify: Edit
Straight edgeFresh document31/81reference: Plane, Axis, Measure
Circular edgeFresh document11/80reference: Measure
VertexFresh document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyFresh document32/81reference: Measure · modify: Edit, Delete
Sheet bodyFresh document32/81reference: Measure · modify: Edit, Delete
Two bodiesFresh document22/80reference: Measure · modify: Delete
Datum planeFresh document53/82create: Sketch · reference: Plane, Helix · modify: Edit, Delete
Datum axisFresh document21/81modify: Edit, Delete
Coordinate systemFresh document21/81modify: Edit, Delete
Text / imported artFresh document21/81modify: Edit, Delete
Closed sketch loopFresh document72/82add: Extrude, Revolve, Surface Extrude, Surface Revolve, Surface Fill · modify: Edit, Delete
Sketch, nothing pickedFresh document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleFresh document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointFresh document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
- -

Overflow — the one place eight slots is not enough

-

Measured, not predicted: the create sub-ring needs 10 addresses, so Polygon, Point are pushed behind a “More” slot. This is the decision the ring size actually turns on — either a verb moves to another family, or the tail goes to a third level, or the ring is not eight. It affects sketch mode only; every model-mode family fits.

- -

Not in the offer

-

Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, Redo, Variables, Section view, Origin planes, World axes — these act on the document, not on a selection, - so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: - Split, Pattern on Curve, Align to, Measure, Interference.

- -

All states

-
Nothing selected — Working document
Nothing selected — Working document
Nothing selected — Reference ring
Nothing selected — Reference ring
Planar face — Working document
Planar face — Working document
Planar face — Add material ring
Planar face — Add material ring
Planar face — Remove ring
Planar face — Remove ring
Planar face — Dress-up ring
Planar face — Dress-up ring
Planar face — Transform ring
Planar face — Transform ring
Planar face — Reference ring
Planar face — Reference ring
Planar face — Modify ring
Planar face — Modify ring
Cylindrical face — Working document
Cylindrical face — Working document
Cylindrical face — Reference ring
Cylindrical face — Reference ring
Cylindrical face — Modify ring
Cylindrical face — Modify ring
Curved face — Working document
Curved face — Working document
Curved face — Modify ring
Curved face — Modify ring
Straight edge — Working document
Straight edge — Working document
Straight edge — Dress-up ring
Straight edge — Dress-up ring
Straight edge — Reference ring
Straight edge — Reference ring
Circular edge — Working document
Circular edge — Working document
Circular edge — Dress-up ring
Circular edge — Dress-up ring
Vertex — Working document
Vertex — Working document
Vertex — Reference ring
Vertex — Reference ring
Solid body — Working document
Solid body — Working document
Solid body — Remove ring
Solid body — Remove ring
Solid body — Dress-up ring
Solid body — Dress-up ring
Solid body — Repeat ring
Solid body — Repeat ring
Solid body — Reference ring
Solid body — Reference ring
Solid body — Modify ring
Solid body — Modify ring
Sheet body — Working document
Sheet body — Working document
Sheet body — Modify ring
Sheet body — Modify ring
Two bodies — Working document
Two bodies — Working document
Two bodies — Reference ring
Two bodies — Reference ring
Datum plane — Working document
Datum plane — Working document
Datum plane — Remove ring
Datum plane — Remove ring
Datum plane — Reference ring
Datum plane — Reference ring
Datum plane — Modify ring
Datum plane — Modify ring
Datum axis — Working document
Datum axis — Working document
Datum axis — Modify ring
Datum axis — Modify ring
Coordinate system — Working document
Coordinate system — Working document
Coordinate system — Modify ring
Coordinate system — Modify ring
Text / imported art — Working document
Text / imported art — Working document
Text / imported art — Modify ring
Text / imported art — Modify ring
Closed sketch loop — Working document
Closed sketch loop — Working document
Closed sketch loop — Add material ring
Closed sketch loop — Add material ring
Closed sketch loop — Modify ring
Closed sketch loop — Modify ring
Sketch, nothing picked — Working document
Sketch, nothing picked — Working document
Sketch, nothing picked — Create ring
Sketch, nothing picked — Create ring
Sketch, nothing picked — Reference ring
Sketch, nothing picked — Reference ring
Sketch line — Working document
Sketch line — Working document
Sketch line — Create ring
Sketch line — Create ring
Sketch line — Dress-up ring
Sketch line — Dress-up ring
Sketch line — Reference ring
Sketch line — Reference ring
Sketch line — Modify ring
Sketch line — Modify ring
Sketch arc or circle — Working document
Sketch arc or circle — Working document
Sketch arc or circle — Create ring
Sketch arc or circle — Create ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Modify ring
Sketch arc or circle — Modify ring
Sketch point — Working document
Sketch point — Working document
Sketch point — Create ring
Sketch point — Create ring
Sketch point — Reference ring
Sketch point — Reference ring
Two sketch entities — Working document
Two sketch entities — Working document
Two sketch entities — Create ring
Two sketch entities — Create ring
Two sketch entities — Dress-up ring
Two sketch entities — Dress-up ring
Two sketch entities — Reference ring
Two sketch entities — Reference ring
Two sketch entities — Modify ring
Two sketch entities — Modify ring
Nothing selected — Fresh document
Nothing selected — Fresh document
Nothing selected — Reference ring
Nothing selected — Reference ring
Planar face — Fresh document
Planar face — Fresh document
Planar face — Reference ring
Planar face — Reference ring
Cylindrical face — Fresh document
Cylindrical face — Fresh document
Cylindrical face — Reference ring
Cylindrical face — Reference ring
Curved face — Fresh document
Curved face — Fresh document
Straight edge — Fresh document
Straight edge — Fresh document
Straight edge — Reference ring
Straight edge — Reference ring
Circular edge — Fresh document
Circular edge — Fresh document
Vertex — Fresh document
Vertex — Fresh document
Vertex — Reference ring
Vertex — Reference ring
Solid body — Fresh document
Solid body — Fresh document
Solid body — Modify ring
Solid body — Modify ring
Sheet body — Fresh document
Sheet body — Fresh document
Sheet body — Modify ring
Sheet body — Modify ring
Two bodies — Fresh document
Two bodies — Fresh document
Datum plane — Fresh document
Datum plane — Fresh document
Datum plane — Reference ring
Datum plane — Reference ring
Datum plane — Modify ring
Datum plane — Modify ring
Datum axis — Fresh document
Datum axis — Fresh document
Datum axis — Modify ring
Datum axis — Modify ring
Coordinate system — Fresh document
Coordinate system — Fresh document
Coordinate system — Modify ring
Coordinate system — Modify ring
Text / imported art — Fresh document
Text / imported art — Fresh document
Text / imported art — Modify ring
Text / imported art — Modify ring
Closed sketch loop — Fresh document
Closed sketch loop — Fresh document
Closed sketch loop — Add material ring
Closed sketch loop — Add material ring
Closed sketch loop — Modify ring
Closed sketch loop — Modify ring
Sketch, nothing picked — Fresh document
Sketch, nothing picked — Fresh document
Sketch, nothing picked — Create ring
Sketch, nothing picked — Create ring
Sketch, nothing picked — Reference ring
Sketch, nothing picked — Reference ring
Sketch line — Fresh document
Sketch line — Fresh document
Sketch line — Create ring
Sketch line — Create ring
Sketch line — Dress-up ring
Sketch line — Dress-up ring
Sketch line — Reference ring
Sketch line — Reference ring
Sketch line — Modify ring
Sketch line — Modify ring
Sketch arc or circle — Fresh document
Sketch arc or circle — Fresh document
Sketch arc or circle — Create ring
Sketch arc or circle — Create ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Modify ring
Sketch arc or circle — Modify ring
Sketch point — Fresh document
Sketch point — Fresh document
Sketch point — Create ring
Sketch point — Create ring
Sketch point — Reference ring
Sketch point — Reference ring
Two sketch entities — Fresh document
Two sketch entities — Fresh document
Two sketch entities — Create ring
Two sketch entities — Create ring
Two sketch entities — Dress-up ring
Two sketch entities — Dress-up ring
Two sketch entities — Reference ring
Two sketch entities — Reference ring
Two sketch entities — Modify ring
Two sketch entities — Modify ring
-
diff --git a/docs/CAD/ux/offer_atlas_inline.html b/docs/CAD/ux/offer_atlas_inline.html deleted file mode 100644 index 3bbfb1b303..0000000000 --- a/docs/CAD/ux/offer_atlas_inline.html +++ /dev/null @@ -1,77 +0,0 @@ -Design tab — offer atlas - -
-

The offer — atlas of every state

-

Every state of the object-driven tool offer, generated from - docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that - address is the same in every selection where it appears, and slots that do not apply are drawn - empty rather than compacted.

-
-
60verbs mapped
-
20selection kinds
-
40primary rings
-
73secondary rings
-
113states total
-
3.5/8mean slots filled
-
5verbs with no GUI yet
-
-
-
-

Decision 0 — ring or vertical list

-

The live question. Both forms carry the SAME map and the same invariant — fixed order, never - re-sorted, nothing compacted; only the geometry differs. Left-click selects; right-click opens the - offer. What the list buys: a disabled row can state its own reason in the words the product - already ships, where an empty slot in a ring is mute; nine sketch primitives fit without an - overflow; shortcuts line up in a readable column; long translated names fit; and it is navigable - by arrow key and by screen reader, which a radial is not. What it costs: no equidistant flick - gesture, and travel to the last row is longer than to the nearest direction. Pairs below — - list first, the same state as a ring second.

- -

Decision 1 — ring capacity

-

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is - the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses - for more verbs at 30° spacing and positions that stop being nameable.

-
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
8 slots — face_planar
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge
8 slots — edge_str
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
8 slots — sk_line
-
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
12 slots — face_planar
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 12 slotsDress-up2Pattern on CurveReference3Straight edge
12 slots — edge_str
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
12 slots — sk_line
- -

Decision 2 — one map or one per mode

-

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, - so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode - states below against the model-mode ones — if a verb that exists in both modes ever appears at two - addresses, the shared map has failed and the split map is the answer.

- -

The matrix — every selection, every document state

-
- - -
SelectionDocumentVerbsSlots2nd ringsWhat lands where
Nothing selectedWorking document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceWorking document188/86create: Sketch · add: Extrude, Thicken · remove: Hole, Shell · dressup: Fillet, Chamfer, Draft · repeat: Pattern · transform: Mate, Align to · reference: Plane, Axis, Coord Sys, Project, Measure · modify: Edit, Delete Face
Cylindrical faceWorking document63/82remove: Thread · reference: Axis, Helix, Measure · modify: Edit, Delete Face
Curved faceWorking document54/81add: Thicken · dressup: Draft · reference: Measure · modify: Edit, Delete Face
Straight edgeWorking document63/82dressup: Fillet, Chamfer · repeat: Pattern on Curve · reference: Plane, Axis, Measure
Circular edgeWorking document43/81remove: Thread · dressup: Fillet, Chamfer · reference: Measure
VertexWorking document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyWorking document156/85remove: Shell, Cut, Split · dressup: Fillet, Chamfer · repeat: Pattern, Mirror, Pattern on Curve · transform: Move · reference: Project, Measure, Mass · modify: Edit, Colour, Delete
Sheet bodyWorking document75/81add: Thicken Surface · dressup: Surface Offset · transform: Move · reference: Measure · modify: Edit, Colour, Delete
Two bodiesWorking document54/81add: Combine · transform: Mate · reference: Measure, Interference · modify: Delete
Datum planeWorking document95/83create: Sketch · remove: Hole, Cut · repeat: Mirror · reference: Plane, Helix, Project · modify: Edit, Delete
Datum axisWorking document21/81modify: Edit, Delete
Coordinate systemWorking document32/81transform: Mate · modify: Edit, Delete
Text / imported artWorking document43/81repeat: Pattern · transform: Move · modify: Edit, Delete
Closed sketch loopWorking document113/82add: Extrude, Revolve, Sweep, Loft, Surface Extrude, Surface Revolve, Surface Loft, Surface Fill · repeat: Pattern · modify: Edit, Delete
Sketch, nothing pickedWorking document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleWorking document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointWorking document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Nothing selectedFresh document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceFresh document74/81create: Sketch · add: Extrude · reference: Plane, Axis, Coord Sys, Measure · modify: Edit
Cylindrical faceFresh document42/81reference: Axis, Helix, Measure · modify: Edit
Curved faceFresh document22/80reference: Measure · modify: Edit
Straight edgeFresh document31/81reference: Plane, Axis, Measure
Circular edgeFresh document11/80reference: Measure
VertexFresh document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyFresh document32/81reference: Measure · modify: Edit, Delete
Sheet bodyFresh document32/81reference: Measure · modify: Edit, Delete
Two bodiesFresh document22/80reference: Measure · modify: Delete
Datum planeFresh document53/82create: Sketch · reference: Plane, Helix · modify: Edit, Delete
Datum axisFresh document21/81modify: Edit, Delete
Coordinate systemFresh document21/81modify: Edit, Delete
Text / imported artFresh document21/81modify: Edit, Delete
Closed sketch loopFresh document72/82add: Extrude, Revolve, Surface Extrude, Surface Revolve, Surface Fill · modify: Edit, Delete
Sketch, nothing pickedFresh document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleFresh document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointFresh document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
- -

Overflow — the one place eight slots is not enough

-

Measured, not predicted: the create sub-ring needs 10 addresses, so Polygon, Point are pushed behind a “More” slot. This is the decision the ring size actually turns on — either a verb moves to another family, or the tail goes to a third level, or the ring is not eight. It affects sketch mode only; every model-mode family fits.

- -

Not in the offer

-

Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, Redo, Variables, Section view, Origin planes, World axes — these act on the document, not on a selection, - so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: - Split, Pattern on Curve, Align to, Measure, Interference.

- -

The states

-
PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected
Fresh document, nothing selected — the first-run picture
PreparePreviewDesignFEATURESnothing yetRight-click the geometry to see what you can do with itFresh document · vertical listNOTHING SELECTEDSketchShift+SAdd materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-upPick an edge to roundRepeatCreate a solid body to pattern firstTransformTransform needs a body — add or import one firstReference4ModifyDelete Face needs a body — add or import one first
LIST · fresh document — every family present, the unavailable ones say why
PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected
RING · the same state — an empty slot cannot say anything
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2
LIST · planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
RING · planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked — pick oneWorking document · vertical listSKETCH, NOTHING PICKEDCreate9Add materialRemoveDress-upRepeatTransformReference2ModifyLineLRectangleRCircleCArcASlotSEllipseESplineBPolygonGPointP
LIST · sketch Create submenu — all 9 primitives fit, no overflow
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create
RING · the same submenu — 2 verbs pushed behind “More”
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face — pick oneWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2ExtrudeShift+EThicken
LIST · planar face, Add material submenu
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material
RING · planar face, Add material sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSOLID BODYCreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemove3Dress-up2Repeat3MoveShift+YReference3Modify3
LIST · solid body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSTRAIGHT EDGECreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-up2Pattern on CurveTransformTransform needs a body — add or import one firstReference3ModifyDelete Face needs a body — add or import one first
LIST · straight edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSKETCH LINECreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2
LIST · sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Click a face or a reference plane, then a toolWorking document · 8 slotsSketchShift+SReference4Nothing selected
RING · Nothing selected
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
RING · Planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Cylindrical face selected — pick what to do with itWorking document · 8 slotsThreadShift+TReference3Modify2Cylindrical face
RING · Cylindrical face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Curved face selected — pick what to do with itWorking document · 8 slotsThickenDraftShift+DMeasureModify2Curved face
RING · Curved face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge
RING · Straight edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Circular edge selected — pick what to do with itWorking document · 8 slotsThreadShift+TDress-up2MeasureCircular edge
RING · Circular edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Vertex selected — pick what to do with itWorking document · 8 slotsReference4Vertex
RING · Vertex
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Solid body selected — pick what to do with itWorking document · 8 slotsRemove3Dress-up2Repeat3MoveShift+YReference3Modify3Solid body
RING · Solid body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sheet body selected — pick what to do with itWorking document · 8 slotsThicken SurfaceSurface OffsetMoveShift+YMeasureModify3Sheet body
RING · Sheet body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two bodies selected — pick what to do with itWorking document · 8 slotsCombineShift+BMateReference2DeleteDelTwo bodies
RING · Two bodies
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum plane selected — pick what to do with itWorking document · 8 slotsSketchShift+SRemove2MirrorShift+ZReference3Modify2Datum plane
RING · Datum plane
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum axis selected — pick what to do with itWorking document · 8 slotsModify2Datum axis
RING · Datum axis
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Coordinate system selected — pick what to do with itWorking document · 8 slotsMateModify2Coordinate system
RING · Coordinate system
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Text / imported art selected — pick what to do with itWorking document · 8 slotsABCPatternShift+NMoveShift+YModify2Text / imported art
RING · Text / imported art
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Closed sketch loop selected — pick what to do with itWorking document · 8 slotsAdd material8PatternShift+NModify2Closed sketch loop
RING · Closed sketch loop
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked selected — pick what to do with itWorking document · 8 slotsCreate9Reference2Sketch, nothing picked
RING · Sketch, nothing picked
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
RING · Sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch arc or circle selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle
RING · Sketch arc or circle
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch point selected — pick what to do with itWorking document · 8 slotsCreate9MoveReference2DeleteDelSketch point
RING · Sketch point
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two sketch entities selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities
RING · Two sketch entities
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material
Planar face · Add material sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CProjectMeasurePlaneShift+PAxisShift+APlanar face · Reference
Planar face · Reference sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create
Sketch · Create sub-ring (the overflow case)
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsShellShift+KCutShift+XSplitSolid body · Remove
Solid body · Remove sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
8 slots — planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
12 slots — planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
8 slots — sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
12 slots — sketch line
diff --git a/docs/HLSD/design-tab.md b/docs/HLSD/design-tab.md new file mode 100644 index 0000000000..67589be328 --- /dev/null +++ b/docs/HLSD/design-tab.md @@ -0,0 +1,213 @@ +# Design tab — High Level Design + +## Purpose and scope + +The Design tab is a parametric CAD environment inside the slicer: sketch, constrain, build +solid features, commit the result to the plate. It exists because the alternative is a round +trip through an external CAD application, and that round trip discards design intent at both +ends — a part edited after slicing comes back as a mesh rather than as the feature history +that produced it. Keeping the model in the project means a dimension can be changed after the +part has been sliced, with the nozzle diameter, the build volume and the material already +known. + +Its coupling to the rest of the application is deliberately narrow. It adds no stage to the +slicing pipeline and touches neither the preset system nor `Tab`. It reaches the rest of Orca +in two places: **Commit to Plate**, which hands finished solids to Prepare as ordinary model +objects, and one optional 3MF archive entry that carries the recipe. Everything else is +contained in `src/libslic3r/CAD/` and `src/slic3r/GUI/CAD/`. + +The user-facing manual lives in the wiki +([Design Tab](https://www.orcaslicer.com/wiki/design_tab)), not here. This document covers the +parts of the design that the code does not make evident. + +## The model is a recipe + +`CadDocument` holds an ordered list of `CadFeature` and nothing else that matters. Bodies, +meshes and display geometry are **derived**: `recompute()` replays the feature list from the +start and rebuilds them. Editing a dimension set twenty features ago is therefore an ordinary +edit — everything downstream is rebuilt by the same replay that built it the first time. + +Two consequences follow from deriving rather than storing: + +- **Undo is a snapshot of `features` alone.** The caller calls `checkpoint()` before the + mutations that make up one user action; undo restores that snapshot and recomputes. Because + everything else is derived, one checkpoint is exactly one `Ctrl+Z` step and the restored + state is exact rather than approximately reconstructed. The tab keeps this stack itself; it + is not Orca's project snapshot system, which operates on `Model` objects the Design tab does + not own until Commit. +- **Face and edge ids are session-scoped.** They are indices into `TopExp::MapShapes`, so a + rebuild invalidates every one of them. `CadDocument::topo_generation` is bumped on every + rebuild so a holder of an id can discover that it is stale instead of silently addressing a + different edge. The counter is deliberately not serialized: an id means nothing outside the + run that produced it. + +## Geometry kernel and dependency surface + +The kernel is OCCT, which OrcaSlicer **already** links — `Format/STEP.cpp`, `Format/svg.cpp` +and `Shape/TextShape.cpp` use it upstream. The Design tab adds no third-party dependency; it +widens the existing OCCT build by one module flag in `deps/OCCT/OCCT.cmake`: + +```cmake +-DBUILD_MODULE_ModelingAlgorithms=${SLIC3R_CAD} +``` + +Most of that module's twelve toolkits were already being built, because `DataExchange` — the +STEP path upstream ships — depends on them. The delta is `TKFillet` (used through +`BRepFilletAPI`), `TKOffset` (`BRepOffsetAPI`) and `TKFeat`, which nothing here references but +which the module flag builds anyway, because OCCT's module flags are all-or-nothing. On macOS +and Linux OCCT links statically, so an unreferenced toolkit costs build time and no shipped +bytes; on Windows OCCT builds shared, so the cost there is real DLL bytes. That Windows figure +has not been measured, and `OCCT.cmake` says so rather than carrying a number that was derived +from an incomplete toolkit list. + +On Windows the packaging step asserts that every linked OCCT toolkit has a shipped DLL and +fails the configure with the name of any that is missing, because the alternative failure — a +deps prefix built with a different `SLIC3R_CAD` setting than the app — otherwise surfaces as a +missing DLL at first launch. + +## The sketch constraint solver + +`src/libslic3r/slvs/` is a vendored subset of SolveSpace's `libslvs`: self-contained, no +external dependencies, **GPL-3.0**, with its `LICENSE` preserved verbatim in the directory. +`SketchSolver.cpp` is its only consumer and drives every sketch constraint in the tab. + +OrcaSlicer is AGPL-3.0. GPLv3 §13 permits combining a GPLv3 work with an AGPLv3 work and +AGPLv3 §13 grants the converse, so the combined work is distributable under AGPL-3.0 with the +solver's GPLv3 terms preserved. The solver is vendored rather than fetched as a dependency +because it is a pinned subset with no build system of its own; the cost of that choice is +upstream-sync burden, paid deliberately to keep `deps/` unchanged. + +## The SLIC3R_CAD gate + +`SLIC3R_CAD` (default ON) compiles the tab and selects the OCCT module flag above. With it OFF +the tab is not built and the deps prefix matches upstream exactly. The gate is cheap because +the hooks the Design tab adds to shared GUI code — chiefly the `m_design_sketch_tool` member +and the render, mouse and key hooks in `GLCanvas3D` — are null-guarded on the path they extend, +so removing the tab removes behaviour rather than requiring the host code to be rewritten. + +The flag has to agree between the dependencies and the application; that is what the DLL +assertion above is checking. + +## Project persistence + +A project stores the recipe as one optional archive entry, `Metadata/orca_cad.bin`, backed by +a single `std::string cad_recipe` on `Model`. The entry is written only when the string is +non-empty, and readers that do not know it ignore it, so projects that contain no CAD model are +byte-identical to what upstream would have written and older readers are unaffected. + +The blob is a cereal binary archive whose layout is the field order of `CadFeature`'s +save/load. That makes the format the one irreversible decision in the subsystem, and the rules +that keep it survivable are: + +- **Append only, never reorder.** Enums serialize positionally as their underlying integer, so + inserting a value in the middle of `SketchConstraintType` or `CadFeatureType` reinterprets + every constraint in every saved project. New fields go at the end. +- **Features are length-framed.** Since v5 each feature is a length-prefixed, self-contained + cereal stream, so a reader can skip a feature written by a newer build and stop cleanly on an + older one. This is what makes appending a field a non-breaking change from here on. v4 and + earlier still open through the pre-framing flat path; v1 is deliberately not loadable and has + no migration path. +- **A newer stamp is refused, not guessed at.** `deserialize_recipe` rejects a blob whose + version exceeds `ORCA_CAD_RECIPE_VERSION` with a message naming both versions. +- **The rules are held by fixtures, not by discipline.** `tests/data/cad_recipe_v{3,4,5}.bin` + are checked-in blobs from the builds that wrote them, and the tests that load them fail if a + field is reordered — which the in-memory round-trip test cannot detect. A regeneration test + (`[.regen]`, not run by default) produces a fresh fixture when a new version is stamped. + +`Import` features embed the imported solid as an OCCT BRep string inside the recipe rather than +referencing the source file, so a project opens without the STEP or mesh it was built from. +The cost is that saved projects are coupled to an OCCT BRep revision. + +## The interaction contract + +Three inputs carry the whole modelling loop — left click, right click and `Esc` — and the +contract between them is stated in code rather than spread across handlers. + +`DesignInteraction.hpp` defines a four-level LIFO stack whose enum value *is* the depth, so +"which level does this press belong to" is a comparison: + +| Level | Holds | One `Esc` press | +| --- | --- | --- | +| `Transient` | a value field or a popup menu | closes it; the tool stays armed | +| `Gesture` | an uncommitted delta — an entity being drawn, a body being dragged | reverts it; committed work is untouched | +| `Tool` | a feature card, an armed sketch tool, a constrain session | exits it; drawn entities survive | +| `Idle` | nothing transient | clears the selection; leaves a sketch session only if it is empty | + +`cad_escape_level()` is a `constexpr` free function over a POD of four booleans rather than a +method on the panel, so the ordering that is the entire contract is checkable without a window, +a GL context or an event loop — five `static_assert`s in the header do exactly that at compile +time. + +**The strict invariant: no level of `Esc` deletes a feature, discards a sketch that holds +geometry, or rolls history back.** Destroying work needs a gesture that says so — `Del` on an +explicit selection, the sketch ribbon's Cancel, which asks first, or `Ctrl+Z`. A sketch +*session* is deliberately not a `Tool` level; it is the environment the `Idle` level lives in, +which makes the destructive path unrepresentable rather than merely unlikely. + +Right-click is read at button-up against two independent budgets — 3 px of drift and 200 ms — +because drift alone still popped a menu at the end of a slow, careful orbit. The raycast uses +the press position, not the release. An armed sketch tool that already consumed the right +button (to terminate a chain, say) declines to also open a menu, through a read-and-clear flag. +Past either budget the event is navigation, and navigation does not transition the state +machine. + +Entering a sketch changes three things at once so the mode is legible: a banner above the +canvas (a sibling of the canvas, not a child over it — on GTK a child window over a +`wxGLCanvas` is a native window and does not reliably stack over GL), the printer bed muted so +a plate grid is never read as a sketch grid, and `N` to look normal to the plane. Code that +changes any of the three belongs with a change to this section. + +## The offer is generated, not hand-written + +Right-clicking geometry opens the *offer*: eight families in a fixed order, each verb at a +permanent row index, verbs that do not apply shown disabled **in place with their reason** +rather than removed. The invariant is that a verb's row index is identical in every selection +where it appears and that adding a verb never moves an existing one — the hand learns the +position, so the menu is never re-sorted, compacted or adaptively ordered. + +An invariant across 92 verbs and 20 selection kinds does not survive by review, so the map +exists once, as data: `scripts/CAD/tool_atlas.json` carries every verb with its row, key, icon, +accepted selections, preconditions and refusal string, and `scripts/CAD/gen_offer_table.py` +emits `src/slic3r/GUI/CAD/DesignOffer.hpp` from it. The header is checked in and never +hand-edited; `scripts/CAD/run-all-checks.sh` runs the generator with `--check` as its first +rung, which is what makes "GENERATED — DO NOT EDIT" a fact rather than a request. The generator +also refuses an atlas with a duplicate verb id, since `mcp_run_verb` resolves a verb by id and +would make the second one unreachable. + +The atlas and its generator sit in `scripts/CAD/` rather than in `docs/`: they are build inputs +for a checked-in header, not documentation. + +## Automation surface + +`McpControl` exposes the document over JSON-RPC when `ORCA_CAD_MCP` is set in the environment, +with `tools/orca_cad_mcp_bridge.py` as the client side. It describes the scene, queries +topology, measures, and runs the same verbs the offer does — it re-implements nothing, so a +scripted action and a clicked one cannot diverge. It is off unless the variable is set. + +## Where the code lives + +| Path | Role | +| --- | --- | +| `src/libslic3r/CAD/CadDocument.*` | the feature recipe, its replay, undo and serialization | +| `src/libslic3r/CAD/GeometryEngine.*` | OCCT wrapper — faces, edges, booleans, healing | +| `src/libslic3r/CAD/SketchEngine.*` | profile → wire → solid | +| `src/libslic3r/CAD/SketchSolver.*` | constraint solving, over the vendored solver | +| `src/libslic3r/slvs/` | vendored 2D constraint solver (GPLv3) | +| `src/slic3r/GUI/CAD/DesignPanel.*` | the tab: toolbar, feature cards, tree, key maps | +| `src/slic3r/GUI/CAD/DesignCanvas.*` | viewport integration | +| `src/slic3r/GUI/CAD/DesignSketchTool.*` | in-canvas sketching | +| `src/slic3r/GUI/CAD/DesignInteraction.hpp` | the Esc level contract | +| `src/slic3r/GUI/CAD/DesignOffer.hpp` | generated offer table | +| `scripts/CAD/tool_atlas.json` | source of truth for the offer | + +## Verification + +The kernel is covered by Catch2 suites in `tests/libslic3r/` (`test_caddocument`, +`test_sketchconstraints`, `test_sketchedit`, `test_sketchimport`, `test_sketchinference`, +`test_sketchprofile`, `test_slvs_constraints`), which need no display; +`scripts/CAD/run-kernel-tests.sh` builds only `libslic3r_tests` and runs them headless. + +The GUI half is not covered by CI, which has no OpenGL canvas or synthetic input: the ladders +in `scripts/CAD/` drive a running application in a local rig instead, and +`scripts/CAD/run-all-checks.sh` is the gate that runs all of them. A green kernel run says +nothing about the viewport, so the two are reported separately rather than as one number. diff --git a/docs/HLSD/multiline-infill.md b/docs/HLSD/multiline-infill.md index d644b197eb..2f68fe3ef9 100644 --- a/docs/HLSD/multiline-infill.md +++ b/docs/HLSD/multiline-infill.md @@ -40,6 +40,12 @@ The pattern is phased on fixed positions, so it lines up across layers and across the regions of one layer. Rounding the corners with `sparse_infill_smooth_factor` happens before `multiline_fill()`. +Each region builds only the rows over its bounding box in that frame, and +outlines only the centerlines within `d1 / 2` of it, the ones whose outlines +reach it. Every row is monotone along its direction, so each outline is started +on the cap at the first end of its centerline, outside the region, and clipping +to the region cuts it only where it crosses the boundary. + ## Cubic Single-line Cubic draws the three families at the same spacing `h` and shifts diff --git a/docs/HLSD/precise-seam.md b/docs/HLSD/precise-seam.md new file mode 100644 index 0000000000..2976e8c7c2 --- /dev/null +++ b/docs/HLSD/precise-seam.md @@ -0,0 +1,239 @@ +# Precise Seam — High Level Design + +## Purpose and scope + +Precise Seam places the seam where a helper volume intersects the external +wall. The user attaches a mesh to an object as a Precise Seam modifier, and on +every layer the seam placer reads the modifier's slice to decide where the seam +of each external perimeter may, must or must not go. The same mesh keeps +working after the model changes, so the seam does not have to be repainted +after every design revision, and a swept helper body can guide the seam along +any path. + +The modifier is non-printing geometry. It does not take part in slicing, region +assignment, filament selection or brim adhesion. It affects only seam +placement, which runs during G-code export. + +## Volume types and priority + +Precise Seam adds six `ModelVolumeType` values after `SUPPORT_ENFORCER`. The +strong types come first and the weak types follow. `is_precise_seam()`, +`is_precise_seam_strong()` and `is_precise_seam_weak()` are range checks that +depend on this order. + +| Type | Group | Effect on the perimeter | +| --- | --- | --- | +| `PRECISE_SEAM_CENTER` | strong | seam at the arc-length midpoint of the intersection | +| `PRECISE_SEAM_LEFT` | strong | seam at the first point of the intersection | +| `PRECISE_SEAM_RIGHT` | strong | seam at the last point of the intersection | +| `PRECISE_SEAM_ENFORCED` | weak | intersection marked as enforced | +| `PRECISE_SEAM_BLOCKED` | weak | intersection marked as blocked | +| `PRECISE_SEAM_NEUTRAL` | weak | intersection reset to neutral | + +A strong modifier fixes one point. A weak modifier only changes the +enforced/blocked type of seam candidates, and the configured seam position then +chooses among them. First and last are taken along the perimeter made +counter-clockwise seen from above. On an outer wall seen from outside, Left is +the left end of the intersection. On the wall of a hole seen from inside the +hole, the two ends are swapped. + +The order of volumes in the object is the priority order, highest first. +`ModelObject::sort_volumes()` keeps every strong modifier before every weak one +and preserves the user's order within each group. The object list lets the user +drag a modifier only within its own group. A type change that crosses a group +boundary moves the volume to the end of its new group, where it has the lowest +priority. Strong modifiers are tried in this order, and the first one that +yields a seam on a perimeter wins. Weak modifiers are applied from the lowest +priority to the highest, so the highest one overwrites any overlapping zone. + +## Model storage and 3MF compatibility + +Projects must stay readable by earlier releases, and the modifier must not +change a print there. Both 3MF writers therefore store a Precise Seam volume as +an ordinary parameter modifier: `modifier_part` in the Bambu-format part +subtype, and `ParameterModifier` together with the legacy `modifier` flag in +the Prusa-format volume metadata. The seam mode is written separately under +`precise_seam_type`, using the names from `ModelVolume::type_to_string()` +(`precise_seam_center` and so on). + +On load, the mode applies after all other volume metadata, regardless of XML +key order, and only when the base type is a modifier. Missing or unknown modes +leave an ordinary modifier. Seam metadata on any other base type is ignored. +Files that stored the seam mode directly as the volume type still load. + +A Precise Seam volume keeps any per-volume settings it had as a part or +modifier, but they are inactive and the object list shows no settings item for +it. The writers prefix these keys with `precise_seam_config:`, so an earlier +reader drops them as unknown options. The volume therefore loads there as a +modifier without settings and has no effect on the print. The current reader +restores the keys only when the volume ends up as a Precise Seam type, so the +settings return when the user changes the type back. Configuration values are +XML-escaped in both writers, for every volume type. + +## Print invalidation + +`Print::apply()` compares the Precise Seam volumes of each object by type, ID +and transformation. Adding, removing, moving, reordering or retyping one +cancels background processing and invalidates only `psGCodeExport`; the sliced +layers are kept. `model_volume_list_update_supports_and_seams()` then brings +the support and Precise Seam volumes of the print's model copy in line with the +new model in one pass. A volume may switch between the two families, since +neither affects slicing. A conversion to or from a part or ordinary modifier +changes the solid and modifier volume lists and reslices as before. + +## Modifier slices + +`SeamPlacer::init()` collects the Precise Seam volumes of each object once: +strong ones in priority order and weak ones reversed. It slices each volume +separately with `PrintObject::slice_single_volume()`, which shares +`slice_modifier_volumes()` with support blockers and enforcers but does not +merge volumes, so each keeps its own priority. The result is cached per volume +and indexed by object layer; `Layer::id()` includes raft layers, which are +subtracted. Seam candidates are then gathered in parallel over the layers and +read the cache without locking. + +Objects without Precise Seam volumes follow the unchanged seam placement path. +For objects that have them, perimeter extraction also removes consecutive +duplicate points and the repeated closing point of each extrusion loop. +Zero-length edges at path junctions would otherwise prevent point insertion +there. Distinct visits to one point of a self-touching contour are kept. + +## Finding the wall segment + +The seam placer works on the external perimeter loops of each layer, both +outer contours and holes, each made counter-clockwise. For every modifier +polygon on the layer that overlaps the perimeter's bounding box, the region +enclosed by the perimeter is clipped against the modifier polygon. The boundary +of each intersection polygon alternates between runs that follow the perimeter +and runs that follow the modifier outline. The wall segment is the longest +continuous run of intersection vertices that lie on the perimeter, measured in +vertices. + +The fast path first finds an intersection vertex that exactly matches a +perimeter vertex. It then walks forward and backward, expecting the adjacent +perimeter vertex and falling back to projection when Clipper has merged or +split collinear edges. A vertex counts as on the perimeter when its projection +is within about 1.6 nm, which covers Clipper's rounding. If no vertex matches +exactly, or every vertex lies on the perimeter, the general path projects all +vertices. When every vertex is on the perimeter, the edge midpoints are checked +instead: a modifier chord can join two perimeter vertices directly, and the +chords split the vertex ring into runs. If no edge leaves the perimeter, the +perimeter lies entirely inside the modifier. + +`Polygon::point_projection()` optionally reports the edge that holds the +projection, and every point of the segment keeps the index of its perimeter +edge. New points are inserted on that edge. A point within 1 µm of an existing +vertex snaps to that vertex instead. + +## Strong modifiers + +For a strong modifier, the target is the first point, the last point or the +arc-length midpoint of the segment. The midpoint is projected back onto the +original perimeter, because Clipper may have merged several perimeter edges +into one segment edge. The target is inserted into the perimeter, and a helper +point is inserted 1 µm before and after it. Strong modifiers are tried in +priority order, the first valid intersection decides the seam, and weak +modifiers are not processed for that perimeter. + +When candidates are built, the inserted point is the only enforced candidate +and becomes the central enforcer; every other candidate is blocked. The seam +position modes then pick that point: Aligned and Aligned Back prefer the central +enforcer, while Back, Random and Nearest rank enforced candidates above blocked +ones. Alignment and random placement can still move the final position along an +edge. After alignment, `restore_precise_seam_positions()` writes the exact point +and its index back into every perimeter that has a strong seam. Inner walls take +their seam from the external seam as usual, including staggering. + +## Weak modifiers + +Weak modifiers produce one segment per intersection polygon, so one modifier can +mark several zones on one perimeter. All segment boundaries are inserted into +the perimeter in order of decreasing arc length. Each insertion then leaves the +indices of the pending, shorter ones unchanged; a point on the closing edge is +appended rather than inserted at index zero. A helper point is added 1 µm +outside each boundary. Random placement picks a position along the edge that +follows a candidate. These helpers keep that edge 1 µm long at each boundary, so +a zone cannot extend or intrude further than that. Boundaries that coincide +share their helper points. + +The zone types are then resolved in priority order, and the edges of enforced +zones are subdivided into steps of at most +`SeamPlacer::enforcer_oversampling_distance` (0.2 mm). The middle candidate of +the longest enforced patch is therefore close to the geometric middle of the +zone. That patch is measured in candidates, across the closing edge, regardless +of where the contour starts; the same rule applies to painted seams. + +Candidates first receive their type from seam painting. The weak zones then +overwrite it, lowest priority first. Blocked and Enforced zones therefore take +precedence over painting, and Neutral clears painting inside its zone. + +## Unsupported geometry and warnings + +Some modifier shapes cannot be resolved to one seam or one zone per crossing. +They are detected cheaply and reported rather than guessed: + +- A strong modifier that crosses a perimeter in more than one place uses only + its first valid segment. The other crossings are ignored. +- A modifier that crosses the whole region enclosed by the perimeter is + detected when the modifier outline minus that region leaves more than one + piece, none of them a hole. Its intersection holds two wall runs, and only + one of them is used. +- A modifier whose slice has a hole on a layer, found as a clockwise polygon in + the flattened slice, is skipped on that layer. The flattened slice no longer + records which hole belongs to which contour. +- A perimeter that lies entirely inside a modifier is ignored by that modifier. + +The conditions are atomic flags shared by all layers and objects. After all +objects are processed, `SeamPlacer::init()` issues at most one non-critical +warning with the ID `SlicingPreciseSeamWarning`. The warning is a single line +that lists every cause found, because the export warnings dialog shows only the +first line of each warning. Repeated warning events replace this notification +instead of appending text to it. + +## User interface + +- *Add Precise Seam* in the object menu creates a Center modifier from a + primitive or a loaded mesh. Text and SVG volumes cannot become Precise Seam + modifiers: the menu does not offer them, and `ObjectList::set_volume_type()` + refuses the change. +- *Change Type* has a single *Precise Seam* entry. It converts other volumes to + Center and keeps the mode of volumes that are already Precise Seam. The + *Precise Seam Type* submenu appears only when every selected item is a + Precise Seam volume, including settings rows that resolve to one. It sets the + chosen mode on all selected volumes. +- Each mode has its own icon in the object list and its own color in the 3D + view, at 60% opacity: warm oranges for the strong modes, and green, red and + gray for Enforced, Blocked and Neutral. +- Object list drops map visible rows to volume indices while skipping hidden + cut connectors, and they refresh the row-to-volume map of the object. +- Precise Seam volumes have no filament, block pasting into SLA, and are exposed + to Python plugins as `ModelVolumeType` values plus the `is_precise_seam*()` + methods. + +## Implementation and verification + +- [PreciseSeam.cpp](../../src/libslic3r/GCode/PreciseSeam.cpp) implements segment + detection, point insertion, weak-zone resolution and position restoration. + [SeamPlacer.cpp](../../src/libslic3r/GCode/SeamPlacer.cpp) integrates it into + candidate gathering and issues the warning. +- [Model.hpp](../../src/libslic3r/Model.hpp) defines the types and their order, + [PrintApply.cpp](../../src/libslic3r/PrintApply.cpp) handles invalidation, and + [PrintObjectSlice.cpp](../../src/libslic3r/PrintObjectSlice.cpp) slices the + modifiers. [bbs_3mf.cpp](../../src/libslic3r/Format/bbs_3mf.cpp) and + [3mf.cpp](../../src/libslic3r/Format/3mf.cpp) store them. +- [GUI_Factories.cpp](../../src/slic3r/GUI/GUI_Factories.cpp) and + [GUI_ObjectList.cpp](../../src/slic3r/GUI/GUI_ObjectList.cpp) provide the menus, + type changes and ordering. +- [Precise Seam tests](../../tests/fff_print/test_precise_seam.cpp) cover the + strong positions, including a midpoint on an existing vertex or the closing + edge. They also cover shared and coincident weak boundaries, every warning, + and the priority order. +- [Seam placer tests](../../tests/fff_print/test_seam_placer.cpp) cover + enforced-patch selection independent of the contour start, fully painted + contours, duplicate removal, and `Print::apply()` synchronization through + type changes and restored model snapshots. +- [3MF tests](../../tests/libslic3r/test_precise_seam_3mf.cpp) cover the round + trip of every mode and of inactive settings, attribute escaping, and which + metadata combinations restore a seam mode. + [Plugin tests](../../tests/slic3rutils/test_precise_seam_plugin.cpp) cover the + Python bindings. diff --git a/docs/HLSD/preset-cache.md b/docs/HLSD/preset-cache.md index 666e452f1e..aa39d522a0 100644 --- a/docs/HLSD/preset-cache.md +++ b/docs/HLSD/preset-cache.md @@ -28,8 +28,8 @@ Per-vendor granularity is what makes the system practical: - A vendor whose profile is bumped invalidates only its own cache. The other 60-odd vendors keep theirs — even when the bumped vendor is the shared Orca filament library everyone else inherits from. -- The setup wizard, which loads vendors one at a time, gets the same speedup as - startup without a second code path. +- The setup wizard loads its vendors through the same routine as startup, so it + gets the same speedup without a second code path. - A vendor with no cache, or a broken one, costs only that vendor a parse. A cache holds *system* presets only. User presets, project settings and modified @@ -162,15 +162,20 @@ cache nothing can invalidate is worse than no cache. Vendors load in a fixed order, because filament inheritance crosses exactly one boundary: any vendor's filament may inherit from the shared Orca filament library, -and nothing else reaches across vendors — an `include` is always vendor-local. The -library therefore goes first, alone; every other vendor follows in parallel, resolving -against it; and the results are merged in a stable order: +and nothing else reaches across vendors — an `include` is always vendor-local. Only +installing a vendor's presets crosses it; reading the vendor, from its cache or its +JSONs, needs nothing from the library. So every other vendor is read while the library +loads, each is installed against it as soon as both are done, and the results are +merged in a stable order: ```mermaid flowchart LR - lib["1 · OrcaFilamentLibrary
loaded first, synchronously"] --> par["2 · every other vendor in parallel,
each into its own bundle, filaments
resolving against the loaded library"] --> merge["3 · bundles merged into one,
sequentially, in stable vendor order"] + lib["1 · OrcaFilamentLibrary loaded;
meanwhile every other vendor read
from its cache or its JSONs"] --> par["2 · every other vendor installed
in parallel, each into its own bundle,
filaments resolving against the library"] --> merge["3 · bundles merged into one,
in one pass per collection,
in stable vendor order"] ``` +`PresetBundle::load_vendors` runs these steps for startup and for the setup wizard, +which hand it the vendors to load and the directory each is installed in. + Whether a vendor comes from its cache or from a parse changes nothing in that order — both produce the same bundle, so cached and parsed vendors mix freely in one startup. @@ -211,11 +216,12 @@ shipped cache answered first, so the profile in `/system/` was never p and its cache was never written back. Serving from a cache is not a memory-image restore. The entries are deserialized and -then installed one by one — inheritance resolved against the presets installed before -them and the currently loaded filament library, includes layered in, configs flattened -onto the collection defaults, validated and registered — by the same function the JSON -path calls straight after parsing a sub-file. An `include` layers what the included -base states, between the parent and the preset's own keys: the base's diff against the +then installed by `install_vendor`, the routine the JSON path hands the vendor's entries +to once it has parsed the sub-files: inheritance resolved against the presets installed +before them and the currently loaded filament library, includes layered in, configs +flattened onto the collection defaults, validated and registered. An `include` layers +what the included base states, between the parent and the preset's own keys: the base's +diff against the default, taken when the base itself was installed and before the per-variant padding `inherits` sees, so only what a template sets reaches the presets including it. The two paths share everything below the parse, which is what makes a cache-loaded bundle @@ -223,6 +229,16 @@ indistinguishable from a JSON-loaded one by construction rather than by test cov Installation also rebuilds each preset's file path from the local data directory, so a shipped cache never carries the generating machine's paths. +Installing an entry is split in two. `resolve_vendor_preset` flattens it, reading only +what is registered under the names it inherits and includes, and `commit_vendor_preset` +registers it, the only step that writes anything shared. Entries resolve across threads +in runs and commit in the order the vendor lists them. A run ends before an entry that +inherits or includes one already in it, since that one's commit registers what the +entry resolves against, so no entry in a run reads what another in it registers. An +entry's parse messages are held until it commits. The bundle, the log's parse and +install messages and the error count therefore come out as parsing and installing one +entry at a time would leave them, whatever the listing order. + App upgrades work because a cache normally survives one. Only a deliberate `CACHE_VERSION` bump makes an installed cache unreadable, and that is handled at install time rather than at load: a vendor whose cache this build cannot read counts @@ -254,17 +270,20 @@ the wizard caches the *derived JSON*, not another form of the inputs: open, the wizard computes the current stamps (one version peek per vendor) and, when they match, serves the catalog from the file — no bundle built, no preset installed. Caching bundle inputs instead was tried and measured: rebuilding the bundle from -per-vendor caches costs ~2 s of preset installation whatever feeds it, so only -skipping the rebuild entirely wins. +per-vendor caches costs over a second of preset installation whatever feeds it, so +only skipping the rebuild entirely wins. Any change to the set — a vendor added, removed or updated, or its cache-only `.opc` replaced by a newer one — changes the stamps and retires the whole file; -the wizard then rebuilds the bundle vendor by vendor (per-vendor caches serving where -they cover) and writes the catalog back. Selections, region and per-open decorations -are applied downstream of the cache either way, so a served catalog is -indistinguishable from a rebuilt one. Nothing ships this file and the updater never -touches it; it is a locally written artifact, re-derived whenever stale, written -through a temp file and rename so half a cache is never readable. +the wizard then rebuilds the bundle with `PresetBundle::load_vendors`, the load +startup uses (per-vendor caches serving where they cover), and writes the catalog +back. When a vendor fails to load, the filament library included, that open falls +back to the wizard's own scan of the vendor JSONs, as when no bundle can be built, +and writes nothing. Selections, region and per-open decorations are applied +downstream of the cache either way, so a served catalog is indistinguishable from a +rebuilt one. Nothing ships this file and the updater never touches it; it is a +locally written artifact, re-derived whenever stale, written through a temp file and +rename so half a cache is never readable. The cache lives under `/cache/`, not beside the vendors: everything that scans `/system/` treats any `.opc` there as a vendor, so a non-vendor @@ -378,6 +397,13 @@ enumerates only `*.json` will find no vendors at all in a packaged build. the `CachedPreset` field list — written and read by `visit_entry` in `PresetCacheFormat.cpp`, one list for the save, the load and the name peek alike — or the cache's own layout or stamps, requires bumping `CACHE_VERSION` by hand. +- **Adding a kind of reference between presets**, as `inherits` and `include` are: + parse the names into `CachedPreset` (a field change, so `CACHE_VERSION` is bumped), + have `install_vendor_entries` end a run before an entry that names one already in it + and retain what the names point at, look them up only in `resolve_vendor_preset`, and + register what they point at only in `commit_vendor_preset`. The listing-order test in + `test_vendor_cache.cpp` fails for a kind the runs do not check once its fixture uses + it. - **The dictionary indexes with a `uint16`**, so `print_config_def` may hold at most 65535 options and one cache at most 65535 distinct enum value names. `CacheDictionary::save` throws past that, which surfaces when CI generates the diff --git a/localization/i18n/list.txt b/localization/i18n/list.txt index ef049fa48e..296829814a 100644 --- a/localization/i18n/list.txt +++ b/localization/i18n/list.txt @@ -213,6 +213,7 @@ src/slic3r/Utils/Process.cpp src/libslic3r/GCode.cpp src/libslic3r/GCodeWriter.cpp src/libslic3r/GCode/ToolOrdering.cpp +src/libslic3r/GCode/SeamPlacer.cpp src/libslic3r/ExtrusionEntity.cpp src/libslic3r/Flow.cpp src/libslic3r/Format/AMF.cpp diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index 2d35c31a26..043aa5b476 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -27357,3 +27357,22 @@ msgstr "" #~ msgid "Right click to reset value to system default." #~ msgstr "Правая кнопка мыши - сброс значения до системного по умолчанию." + +# AI Translated +msgid "Precise Seam" +msgstr "Точный шов" + +msgid "multiple intersections with a perimeter detected" +msgstr "обнаружены множественные пересечения с периметром" + +msgid "modifier fully crosses the printable perimeter" +msgstr "модификатор пересекает печатаемый периметр насквозь" + +msgid "modifier shape is not solid (has holes inside) and was ignored" +msgstr "форма модификатора не сплошная (имеет отверстия) и была проигнорирована" + +msgid "perimeter is fully contained inside modifier and was ignored" +msgstr "периметр полностью содержится внутри модификатора и был проигнорирован" + +msgid "Seam placement may differ from expected." +msgstr "Размещение шва может отличаться от ожидаемого." diff --git a/resources/images/menu_precise_seam_add.svg b/resources/images/menu_precise_seam_add.svg new file mode 100644 index 0000000000..f7efb2feb0 --- /dev/null +++ b/resources/images/menu_precise_seam_add.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_blocked.svg b/resources/images/menu_precise_seam_blocked.svg new file mode 100644 index 0000000000..d84c2f1468 --- /dev/null +++ b/resources/images/menu_precise_seam_blocked.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_center.svg b/resources/images/menu_precise_seam_center.svg new file mode 100644 index 0000000000..f7efb2feb0 --- /dev/null +++ b/resources/images/menu_precise_seam_center.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_enforced.svg b/resources/images/menu_precise_seam_enforced.svg new file mode 100644 index 0000000000..116cdb5bed --- /dev/null +++ b/resources/images/menu_precise_seam_enforced.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_left.svg b/resources/images/menu_precise_seam_left.svg new file mode 100644 index 0000000000..737d422373 --- /dev/null +++ b/resources/images/menu_precise_seam_left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_neutral.svg b/resources/images/menu_precise_seam_neutral.svg new file mode 100644 index 0000000000..cf5af99506 --- /dev/null +++ b/resources/images/menu_precise_seam_neutral.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_right.svg b/resources/images/menu_precise_seam_right.svg new file mode 100644 index 0000000000..202895cac2 --- /dev/null +++ b/resources/images/menu_precise_seam_right.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_precise_seam_type.svg b/resources/images/menu_precise_seam_type.svg new file mode 100644 index 0000000000..42436d5441 --- /dev/null +++ b/resources/images/menu_precise_seam_type.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/texture_displacement_add.svg b/resources/images/texture_displacement_add.svg new file mode 100644 index 0000000000..bb12b2e953 --- /dev/null +++ b/resources/images/texture_displacement_add.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_add_negative.svg b/resources/images/texture_displacement_add_negative.svg new file mode 100644 index 0000000000..a3fc829863 --- /dev/null +++ b/resources/images/texture_displacement_add_negative.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_adjust.svg b/resources/images/texture_displacement_adjust.svg new file mode 100644 index 0000000000..f3632b3f19 --- /dev/null +++ b/resources/images/texture_displacement_adjust.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_avg_scale.svg b/resources/images/texture_displacement_avg_scale.svg new file mode 100644 index 0000000000..c94a62709c --- /dev/null +++ b/resources/images/texture_displacement_avg_scale.svg @@ -0,0 +1,330 @@ + + diff --git a/resources/images/texture_displacement_brush.svg b/resources/images/texture_displacement_brush.svg new file mode 100644 index 0000000000..cc3cd3740e --- /dev/null +++ b/resources/images/texture_displacement_brush.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_checker.svg b/resources/images/texture_displacement_checker.svg new file mode 100644 index 0000000000..833a76288e --- /dev/null +++ b/resources/images/texture_displacement_checker.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_connected_area.svg b/resources/images/texture_displacement_connected_area.svg new file mode 100644 index 0000000000..8c066f7be0 --- /dev/null +++ b/resources/images/texture_displacement_connected_area.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_cross.svg b/resources/images/texture_displacement_cross.svg new file mode 100644 index 0000000000..d7d2cfeace --- /dev/null +++ b/resources/images/texture_displacement_cross.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_cut.svg b/resources/images/texture_displacement_cut.svg new file mode 100644 index 0000000000..532793eb25 --- /dev/null +++ b/resources/images/texture_displacement_cut.svg @@ -0,0 +1,359 @@ + + diff --git a/resources/images/texture_displacement_distortion.svg b/resources/images/texture_displacement_distortion.svg new file mode 100644 index 0000000000..441baf0964 --- /dev/null +++ b/resources/images/texture_displacement_distortion.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_drag.svg b/resources/images/texture_displacement_drag.svg new file mode 100644 index 0000000000..75a3efe419 --- /dev/null +++ b/resources/images/texture_displacement_drag.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_erase_all.svg b/resources/images/texture_displacement_erase_all.svg new file mode 100644 index 0000000000..d45e6c7d35 --- /dev/null +++ b/resources/images/texture_displacement_erase_all.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_face.svg b/resources/images/texture_displacement_face.svg new file mode 100644 index 0000000000..a0c5d0a4b7 --- /dev/null +++ b/resources/images/texture_displacement_face.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_fast_preview.svg b/resources/images/texture_displacement_fast_preview.svg new file mode 100644 index 0000000000..84286f0c7f --- /dev/null +++ b/resources/images/texture_displacement_fast_preview.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_frame.svg b/resources/images/texture_displacement_frame.svg new file mode 100644 index 0000000000..3bf29bcc5a --- /dev/null +++ b/resources/images/texture_displacement_frame.svg @@ -0,0 +1,242 @@ + + diff --git a/resources/images/texture_displacement_join.svg b/resources/images/texture_displacement_join.svg new file mode 100644 index 0000000000..ff5e9a907f --- /dev/null +++ b/resources/images/texture_displacement_join.svg @@ -0,0 +1,387 @@ + + diff --git a/resources/images/texture_displacement_map_unwrap.svg b/resources/images/texture_displacement_map_unwrap.svg new file mode 100644 index 0000000000..a1af920f2b --- /dev/null +++ b/resources/images/texture_displacement_map_unwrap.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_map_view.svg b/resources/images/texture_displacement_map_view.svg new file mode 100644 index 0000000000..70ef64c198 --- /dev/null +++ b/resources/images/texture_displacement_map_view.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_move_down.svg b/resources/images/texture_displacement_move_down.svg new file mode 100644 index 0000000000..8f15b7c181 --- /dev/null +++ b/resources/images/texture_displacement_move_down.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_move_up.svg b/resources/images/texture_displacement_move_up.svg new file mode 100644 index 0000000000..32dfd19011 --- /dev/null +++ b/resources/images/texture_displacement_move_up.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_real_preview.svg b/resources/images/texture_displacement_real_preview.svg new file mode 100644 index 0000000000..0d132e6950 --- /dev/null +++ b/resources/images/texture_displacement_real_preview.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_select_all.svg b/resources/images/texture_displacement_select_all.svg new file mode 100644 index 0000000000..bf420df6c6 --- /dev/null +++ b/resources/images/texture_displacement_select_all.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_snap.svg b/resources/images/texture_displacement_snap.svg new file mode 100644 index 0000000000..f6abea8a3f --- /dev/null +++ b/resources/images/texture_displacement_snap.svg @@ -0,0 +1,260 @@ + + diff --git a/resources/images/texture_displacement_tile_repeat.svg b/resources/images/texture_displacement_tile_repeat.svg new file mode 100644 index 0000000000..9a4fc8d3c8 --- /dev/null +++ b/resources/images/texture_displacement_tile_repeat.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_unjoin.svg b/resources/images/texture_displacement_unjoin.svg new file mode 100644 index 0000000000..2f50d35767 --- /dev/null +++ b/resources/images/texture_displacement_unjoin.svg @@ -0,0 +1,387 @@ + + diff --git a/resources/images/texture_displacement_uv_avg_scale.svg b/resources/images/texture_displacement_uv_avg_scale.svg new file mode 100644 index 0000000000..4734381399 --- /dev/null +++ b/resources/images/texture_displacement_uv_avg_scale.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_bg_height.svg b/resources/images/texture_displacement_uv_bg_height.svg new file mode 100644 index 0000000000..354f12d9f4 --- /dev/null +++ b/resources/images/texture_displacement_uv_bg_height.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_clear_edits.svg b/resources/images/texture_displacement_uv_clear_edits.svg new file mode 100644 index 0000000000..3d1c6c0e87 --- /dev/null +++ b/resources/images/texture_displacement_uv_clear_edits.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_cut.svg b/resources/images/texture_displacement_uv_cut.svg new file mode 100644 index 0000000000..9ae7d5e273 --- /dev/null +++ b/resources/images/texture_displacement_uv_cut.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_frame.svg b/resources/images/texture_displacement_uv_frame.svg new file mode 100644 index 0000000000..c74e648fe0 --- /dev/null +++ b/resources/images/texture_displacement_uv_frame.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_join.svg b/resources/images/texture_displacement_uv_join.svg new file mode 100644 index 0000000000..99cc51dbc0 --- /dev/null +++ b/resources/images/texture_displacement_uv_join.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_path.svg b/resources/images/texture_displacement_uv_path.svg new file mode 100644 index 0000000000..2bdf164197 --- /dev/null +++ b/resources/images/texture_displacement_uv_path.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_seam.svg b/resources/images/texture_displacement_uv_seam.svg new file mode 100644 index 0000000000..755fa231fa --- /dev/null +++ b/resources/images/texture_displacement_uv_seam.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_select_edge.svg b/resources/images/texture_displacement_uv_select_edge.svg new file mode 100644 index 0000000000..d309addbd5 --- /dev/null +++ b/resources/images/texture_displacement_uv_select_edge.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_select_island.svg b/resources/images/texture_displacement_uv_select_island.svg new file mode 100644 index 0000000000..430d187965 --- /dev/null +++ b/resources/images/texture_displacement_uv_select_island.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_select_vertex.svg b/resources/images/texture_displacement_uv_select_vertex.svg new file mode 100644 index 0000000000..f9d5318189 --- /dev/null +++ b/resources/images/texture_displacement_uv_select_vertex.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_snap.svg b/resources/images/texture_displacement_uv_snap.svg new file mode 100644 index 0000000000..b3beeaaf5a --- /dev/null +++ b/resources/images/texture_displacement_uv_snap.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_uv_unjoin.svg b/resources/images/texture_displacement_uv_unjoin.svg new file mode 100644 index 0000000000..bde79aec0a --- /dev/null +++ b/resources/images/texture_displacement_uv_unjoin.svg @@ -0,0 +1 @@ + diff --git a/resources/images/texture_displacement_wireframe.svg b/resources/images/texture_displacement_wireframe.svg new file mode 100644 index 0000000000..44d1c0c3e0 --- /dev/null +++ b/resources/images/texture_displacement_wireframe.svg @@ -0,0 +1 @@ + diff --git a/resources/images/toolbar_big_brush.svg b/resources/images/toolbar_big_brush.svg new file mode 100644 index 0000000000..20be9ec53b --- /dev/null +++ b/resources/images/toolbar_big_brush.svg @@ -0,0 +1,60 @@ + + + + + + + + + + diff --git a/resources/images/toolbar_face.svg b/resources/images/toolbar_face.svg new file mode 100644 index 0000000000..6975e0f6e4 --- /dev/null +++ b/resources/images/toolbar_face.svg @@ -0,0 +1,97 @@ + + + + + + + + + + + + + diff --git a/resources/images/toolbar_texture_displacement.svg b/resources/images/toolbar_texture_displacement.svg new file mode 100644 index 0000000000..c154258c75 --- /dev/null +++ b/resources/images/toolbar_texture_displacement.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/profiles/Afinia.json b/resources/profiles/Afinia.json index e65ced0f68..8f3676c875 100644 --- a/resources/profiles/Afinia.json +++ b/resources/profiles/Afinia.json @@ -1,6 +1,6 @@ { "name": "Afinia", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Afinia configurations", "machine_model_list": [ diff --git a/resources/profiles/Afinia/filament/Afinia ABS+@HS.json b/resources/profiles/Afinia/filament/Afinia ABS+@HS.json index 77fc0deee9..1a50c4cc98 100644 --- a/resources/profiles/Afinia/filament/Afinia ABS+@HS.json +++ b/resources/profiles/Afinia/filament/Afinia ABS+@HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFLfywkp", - "setting_id": "wAJTMxtCY7EoavRi", "name": "Afinia ABS+@HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "wAJTMxtCY7EoavRi", + "filament_id": "OFLfywkp", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Afinia/filament/Afinia ABS@HS.json b/resources/profiles/Afinia/filament/Afinia ABS@HS.json index e905e002bd..8c561e0cca 100644 --- a/resources/profiles/Afinia/filament/Afinia ABS@HS.json +++ b/resources/profiles/Afinia/filament/Afinia ABS@HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFV5wEMe", - "setting_id": "qCDnb2iBaz4hd4vX", "name": "Afinia ABS@HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "qCDnb2iBaz4hd4vX", + "filament_id": "OFV5wEMe", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Afinia/filament/Afinia PLA@HS.json b/resources/profiles/Afinia/filament/Afinia PLA@HS.json index cfd15a574b..d593ae69b4 100644 --- a/resources/profiles/Afinia/filament/Afinia PLA@HS.json +++ b/resources/profiles/Afinia/filament/Afinia PLA@HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OF9HCdyQ", - "setting_id": "N3sCgjdjvp6FTtw9", "name": "Afinia PLA@HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "N3sCgjdjvp6FTtw9", + "filament_id": "OF9HCdyQ", + "instantiation": "true", "filament_cost": [ "24.99" ], diff --git a/resources/profiles/Afinia/filament/Afinia Value ABS@HS.json b/resources/profiles/Afinia/filament/Afinia Value ABS@HS.json index f98da8225d..7ef404c191 100644 --- a/resources/profiles/Afinia/filament/Afinia Value ABS@HS.json +++ b/resources/profiles/Afinia/filament/Afinia Value ABS@HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFXi59OX", - "setting_id": "OxIiEYjbhEvSykaQ", "name": "Afinia Value ABS@HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "OxIiEYjbhEvSykaQ", + "filament_id": "OFXi59OX", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Afinia/filament/Afinia Value PLA@HS.json b/resources/profiles/Afinia/filament/Afinia Value PLA@HS.json index 1d9f669bd0..caf58c0956 100644 --- a/resources/profiles/Afinia/filament/Afinia Value PLA@HS.json +++ b/resources/profiles/Afinia/filament/Afinia Value PLA@HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFgHh8ly", - "setting_id": "BASsUdyvElEVJ9AA", "name": "Afinia Value PLA@HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "BASsUdyvElEVJ9AA", + "filament_id": "OFgHh8ly", + "instantiation": "true", "filament_cost": [ "24.99" ], diff --git a/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.4 nozzle.json b/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.4 nozzle.json index 1c93b3f1cd..f0c6153ff2 100644 --- a/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.4 nozzle.json +++ b/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "iwkXfmEyz9RLZTvh", "name": "Afinia H+1(HS) 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_afinia_common", + "from": "system", + "setting_id": "iwkXfmEyz9RLZTvh", + "instantiation": "true", "printer_model": "Afinia H+1(HS)", "default_print_profile": "0.20mm Standard @Afinia H+1(HS)", "nozzle_diameter": [ diff --git a/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.6 nozzle.json b/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.6 nozzle.json index ecfca28454..0e5222b7ed 100644 --- a/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.6 nozzle.json +++ b/resources/profiles/Afinia/machine/Afinia H+1(HS) 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "vngsrxKvEIsmr8tQ", "name": "Afinia H+1(HS) 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Afinia H+1(HS) 0.4 nozzle", + "from": "system", + "setting_id": "vngsrxKvEIsmr8tQ", + "instantiation": "true", "printer_model": "Afinia H+1(HS)", "default_print_profile": "0.30mm Strength @Afinia H+1(HS) 0.6 nozzle", "nozzle_diameter": [ diff --git a/resources/profiles/Afinia/process/0.12mm Fine @Afinia H+1(HS).json b/resources/profiles/Afinia/process/0.12mm Fine @Afinia H+1(HS).json index 18e497cd01..954c198bfe 100644 --- a/resources/profiles/Afinia/process/0.12mm Fine @Afinia H+1(HS).json +++ b/resources/profiles/Afinia/process/0.12mm Fine @Afinia H+1(HS).json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "FueWYijuvLNWzNmL", "name": "0.12mm Fine @Afinia H+1(HS)", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_afinia_HS_common", + "from": "system", + "setting_id": "FueWYijuvLNWzNmL", + "instantiation": "true", "layer_height": "0.12", "bottom_shell_layers": "5", "elefant_foot_compensation": "0.15", diff --git a/resources/profiles/Afinia/process/0.16mm Optimal @Afinia H+1(HS).json b/resources/profiles/Afinia/process/0.16mm Optimal @Afinia H+1(HS).json index cebbfe2206..0c6cedfd05 100644 --- a/resources/profiles/Afinia/process/0.16mm Optimal @Afinia H+1(HS).json +++ b/resources/profiles/Afinia/process/0.16mm Optimal @Afinia H+1(HS).json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "Ntf0ZMcETTPz7EY1", "name": "0.16mm Optimal @Afinia H+1(HS)", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_afinia_HS_common", + "from": "system", + "setting_id": "Ntf0ZMcETTPz7EY1", + "instantiation": "true", "layer_height": "0.16", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "4", diff --git a/resources/profiles/Afinia/process/0.20mm Standard @Afinia H+1(HS).json b/resources/profiles/Afinia/process/0.20mm Standard @Afinia H+1(HS).json index e5449b7e16..6b9b9ff29b 100644 --- a/resources/profiles/Afinia/process/0.20mm Standard @Afinia H+1(HS).json +++ b/resources/profiles/Afinia/process/0.20mm Standard @Afinia H+1(HS).json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Lxid5Z2e0fvVDMMm", "name": "0.20mm Standard @Afinia H+1(HS)", - "from": "system", "inherits": "fdm_process_afinia_HS_common", + "from": "system", + "setting_id": "Lxid5Z2e0fvVDMMm", "instantiation": "true", "elefant_foot_compensation": "0.15", "top_shell_thickness": "1.0", diff --git a/resources/profiles/Afinia/process/0.24mm Draft @Afinia H+1(HS).json b/resources/profiles/Afinia/process/0.24mm Draft @Afinia H+1(HS).json index 0dad08c3b0..67af0c4dd0 100644 --- a/resources/profiles/Afinia/process/0.24mm Draft @Afinia H+1(HS).json +++ b/resources/profiles/Afinia/process/0.24mm Draft @Afinia H+1(HS).json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "APeSqnRZh6I9OTFr", "name": "0.24mm Draft @Afinia H+1(HS)", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_afinia_HS_common", + "from": "system", + "setting_id": "APeSqnRZh6I9OTFr", + "instantiation": "true", "layer_height": "0.24", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Afinia/process/0.28mm Extra Draft @Afinia H+1(HS).json b/resources/profiles/Afinia/process/0.28mm Extra Draft @Afinia H+1(HS).json index e8fb41dcb8..212b87411c 100644 --- a/resources/profiles/Afinia/process/0.28mm Extra Draft @Afinia H+1(HS).json +++ b/resources/profiles/Afinia/process/0.28mm Extra Draft @Afinia H+1(HS).json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "VZ3NOVzdVWqZ37Ge", "name": "0.28mm Extra Draft @Afinia H+1(HS)", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_afinia_HS_common", + "from": "system", + "setting_id": "VZ3NOVzdVWqZ37Ge", + "instantiation": "true", "layer_height": "0.28", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Anker.json b/resources/profiles/Anker.json index 945378db9c..6ff3e6d959 100644 --- a/resources/profiles/Anker.json +++ b/resources/profiles/Anker.json @@ -1,6 +1,6 @@ { "name": "Anker", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "Anker configurations", "machine_model_list": [ diff --git a/resources/profiles/Anker/filament/Generic ABS @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic ABS @Anker 0.2 nozzle.json index c3e47c80a3..b6ff6f9ca7 100644 --- a/resources/profiles/Anker/filament/Generic ABS @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic ABS @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Anker 0.2 nozzle", - "inherits": "Generic ABS @Anker base", "renamed_from": "Anker Generic ABS 0.2 nozzle", + "inherits": "Generic ABS @Anker base", "from": "system", "setting_id": "iOCt7x95XbWYMe5q", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic ABS @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic ABS @Anker 0.25 nozzle.json index 64fd62eb64..51f6de86ef 100644 --- a/resources/profiles/Anker/filament/Generic ABS @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic ABS @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Anker 0.25 nozzle", - "inherits": "Generic ABS @Anker base", "renamed_from": "Anker Generic ABS 0.25 nozzle", + "inherits": "Generic ABS @Anker base", "from": "system", "setting_id": "7Q2pr70SpSjK7v7Y", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic ABS @Anker.json b/resources/profiles/Anker/filament/Generic ABS @Anker.json index 978bc00e31..f33406b467 100644 --- a/resources/profiles/Anker/filament/Generic ABS @Anker.json +++ b/resources/profiles/Anker/filament/Generic ABS @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Anker", - "inherits": "Generic ABS @Anker base", "renamed_from": "Anker Generic ABS", + "inherits": "Generic ABS @Anker base", "from": "system", "setting_id": "x3IBYtgKBx6Mszzk", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic ASA @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic ASA @Anker 0.2 nozzle.json index 1a40e93730..cb5c4d1a25 100644 --- a/resources/profiles/Anker/filament/Generic ASA @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic ASA @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Anker 0.2 nozzle", - "inherits": "Generic ASA @Anker base", "renamed_from": "Anker Generic ASA 0.2 nozzle", + "inherits": "Generic ASA @Anker base", "from": "system", "setting_id": "lTR8QLbuttyVs5UW", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic ASA @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic ASA @Anker 0.25 nozzle.json index 0b85eef27c..9f44b88a13 100644 --- a/resources/profiles/Anker/filament/Generic ASA @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic ASA @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Anker 0.25 nozzle", - "inherits": "Generic ASA @Anker base", "renamed_from": "Anker Generic ASA 0.25 nozzle", + "inherits": "Generic ASA @Anker base", "from": "system", "setting_id": "FU4BiMydEyo7zxq5", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic ASA @Anker.json b/resources/profiles/Anker/filament/Generic ASA @Anker.json index 53b84223df..0d83d71947 100644 --- a/resources/profiles/Anker/filament/Generic ASA @Anker.json +++ b/resources/profiles/Anker/filament/Generic ASA @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Anker", - "inherits": "Generic ASA @Anker base", "renamed_from": "Anker Generic ASA", + "inherits": "Generic ASA @Anker base", "from": "system", "setting_id": "aDADuxiEKt2dVKOJ", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PA @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic PA @Anker 0.2 nozzle.json index 6460721e2f..203b000c31 100644 --- a/resources/profiles/Anker/filament/Generic PA @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PA @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Anker 0.2 nozzle", - "inherits": "Generic PA @Anker base", "renamed_from": "Anker Generic PA 0.2 nozzle", + "inherits": "Generic PA @Anker base", "from": "system", "setting_id": "tYAT7xnNFD6gY84A", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PA @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic PA @Anker 0.25 nozzle.json index ee2514e92c..96675fb685 100644 --- a/resources/profiles/Anker/filament/Generic PA @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PA @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Anker 0.25 nozzle", - "inherits": "Generic PA @Anker base", "renamed_from": "Anker Generic PA 0.25 nozzle", + "inherits": "Generic PA @Anker base", "from": "system", "setting_id": "Zlv65wLA94PbevRG", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PA @Anker.json b/resources/profiles/Anker/filament/Generic PA @Anker.json index e9acc2d7f6..eeb428ee33 100644 --- a/resources/profiles/Anker/filament/Generic PA @Anker.json +++ b/resources/profiles/Anker/filament/Generic PA @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Anker", - "inherits": "Generic PA @Anker base", "renamed_from": "Anker Generic PA", + "inherits": "Generic PA @Anker base", "from": "system", "setting_id": "sLWVtBxpAC53eUwo", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PA-CF @Anker.json b/resources/profiles/Anker/filament/Generic PA-CF @Anker.json index 6c3b2d1860..80e71d3c37 100644 --- a/resources/profiles/Anker/filament/Generic PA-CF @Anker.json +++ b/resources/profiles/Anker/filament/Generic PA-CF @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Anker", - "inherits": "Generic PA-CF @Anker base", "renamed_from": "Anker Generic PA-CF", + "inherits": "Generic PA-CF @Anker base", "from": "system", "setting_id": "K4LcpR0zBp5klSpb", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PC @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic PC @Anker 0.2 nozzle.json index 0126f9f893..024af4955c 100644 --- a/resources/profiles/Anker/filament/Generic PC @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PC @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Anker 0.2 nozzle", - "inherits": "Generic PC @Anker base", "renamed_from": "Anker Generic PC 0.2 nozzle", + "inherits": "Generic PC @Anker base", "from": "system", "setting_id": "2sSOgctcnVh9bGbQ", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PC @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic PC @Anker 0.25 nozzle.json index 50aca840aa..ab09365cac 100644 --- a/resources/profiles/Anker/filament/Generic PC @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PC @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Anker 0.25 nozzle", - "inherits": "Generic PC @Anker base", "renamed_from": "Anker Generic PC 0.25 nozzle", + "inherits": "Generic PC @Anker base", "from": "system", "setting_id": "h7IRuq5uekjNw4vg", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PC @Anker.json b/resources/profiles/Anker/filament/Generic PC @Anker.json index 5433518c5a..4c28fc9182 100644 --- a/resources/profiles/Anker/filament/Generic PC @Anker.json +++ b/resources/profiles/Anker/filament/Generic PC @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Anker", - "inherits": "Generic PC @Anker base", "renamed_from": "Anker Generic PC", + "inherits": "Generic PC @Anker base", "from": "system", "setting_id": "ffufXVvW95sunH1B", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PETG @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic PETG @Anker 0.2 nozzle.json index 2ff7eca4d1..ed66989ed4 100644 --- a/resources/profiles/Anker/filament/Generic PETG @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PETG @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Anker 0.2 nozzle", - "inherits": "Generic PETG @Anker base", "renamed_from": "Anker Generic PETG 0.2 nozzle", + "inherits": "Generic PETG @Anker base", "from": "system", "setting_id": "67ZHuiXPyCP6Tdtr", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PETG @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic PETG @Anker 0.25 nozzle.json index 9f9ae2da35..62deaea017 100644 --- a/resources/profiles/Anker/filament/Generic PETG @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PETG @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Anker 0.25 nozzle", - "inherits": "Generic PETG @Anker base", "renamed_from": "Anker Generic PETG 0.25 nozzle", + "inherits": "Generic PETG @Anker base", "from": "system", "setting_id": "aLuRALDt0Otbd2So", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PETG @Anker.json b/resources/profiles/Anker/filament/Generic PETG @Anker.json index cdb08f8671..f4a1a3b557 100644 --- a/resources/profiles/Anker/filament/Generic PETG @Anker.json +++ b/resources/profiles/Anker/filament/Generic PETG @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Anker", - "inherits": "Generic PETG @Anker base", "renamed_from": "Anker Generic PETG", + "inherits": "Generic PETG @Anker base", "from": "system", "setting_id": "hvV0rmnzRHJk9sMz", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PETG-CF @Anker.json b/resources/profiles/Anker/filament/Generic PETG-CF @Anker.json index e5a265c40f..ce47b93b01 100644 --- a/resources/profiles/Anker/filament/Generic PETG-CF @Anker.json +++ b/resources/profiles/Anker/filament/Generic PETG-CF @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Anker", - "inherits": "Generic PETG-CF @Anker base", "renamed_from": "Anker Generic PETG-CF", + "inherits": "Generic PETG-CF @Anker base", "from": "system", "setting_id": "vCAuQeQLoXUk28ph", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic PLA @Anker 0.2 nozzle.json index e8ffdb8c57..7f8c7cf5ad 100644 --- a/resources/profiles/Anker/filament/Generic PLA @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PLA @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Anker 0.2 nozzle", - "inherits": "Generic PLA @Anker base", "renamed_from": "Anker Generic PLA 0.2 nozzle", + "inherits": "Generic PLA @Anker base", "from": "system", "setting_id": "rCvmCzPgi4KA6nmI", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic PLA @Anker 0.25 nozzle.json index 5e4e3e0f0b..73fa17a0dc 100644 --- a/resources/profiles/Anker/filament/Generic PLA @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PLA @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Anker 0.25 nozzle", - "inherits": "Generic PLA @Anker base", "renamed_from": "Anker Generic PLA 0.25 nozzle", + "inherits": "Generic PLA @Anker base", "from": "system", "setting_id": "C0hNEbEueKrcYojS", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA @Anker.json b/resources/profiles/Anker/filament/Generic PLA @Anker.json index 5049571bcb..b077555137 100644 --- a/resources/profiles/Anker/filament/Generic PLA @Anker.json +++ b/resources/profiles/Anker/filament/Generic PLA @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Anker", - "inherits": "Generic PLA @Anker base", "renamed_from": "Anker Generic PLA", + "inherits": "Generic PLA @Anker base", "from": "system", "setting_id": "GfVhcxRmt6mHSemI", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.2 nozzle.json index e28ab1c79a..0f327899b8 100644 --- a/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Anker 0.2 nozzle", - "inherits": "Generic PLA Silk @Anker base", "renamed_from": "Anker Generic PLA Silk 0.2 nozzle", + "inherits": "Generic PLA Silk @Anker base", "from": "system", "setting_id": "NWGiPWYmLVktDMJt", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.25 nozzle.json index 2699cb1aea..2204fd0f6a 100644 --- a/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PLA Silk @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Anker 0.25 nozzle", - "inherits": "Generic PLA Silk @Anker base", "renamed_from": "Anker Generic PLA Silk 0.25 nozzle", + "inherits": "Generic PLA Silk @Anker base", "from": "system", "setting_id": "4thKBCnYgDtnAtF5", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA Silk @Anker.json b/resources/profiles/Anker/filament/Generic PLA Silk @Anker.json index 9629ba4f0b..109e113c55 100644 --- a/resources/profiles/Anker/filament/Generic PLA Silk @Anker.json +++ b/resources/profiles/Anker/filament/Generic PLA Silk @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Anker", - "inherits": "Generic PLA Silk @Anker base", "renamed_from": "Anker Generic PLA Silk", + "inherits": "Generic PLA Silk @Anker base", "from": "system", "setting_id": "URRIeNXIiIPjxbKL", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.2 nozzle.json b/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.2 nozzle.json index f32fb75a92..27fb60c005 100644 --- a/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.2 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Anker 0.2 nozzle", - "inherits": "Generic PLA+ @Anker base", "renamed_from": "Anker Generic PLA+ 0.2 nozzle", + "inherits": "Generic PLA+ @Anker base", "from": "system", "setting_id": "5m3xLxdReqLlE2Jp", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.25 nozzle.json b/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.25 nozzle.json index 291773e546..400d9d3752 100644 --- a/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.25 nozzle.json +++ b/resources/profiles/Anker/filament/Generic PLA+ @Anker 0.25 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Anker 0.25 nozzle", - "inherits": "Generic PLA+ @Anker base", "renamed_from": "Anker Generic PLA+ 0.25 nozzle", + "inherits": "Generic PLA+ @Anker base", "from": "system", "setting_id": "wwkWVDsg6SoeCS0F", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA+ @Anker.json b/resources/profiles/Anker/filament/Generic PLA+ @Anker.json index 1381c839da..41c212e697 100644 --- a/resources/profiles/Anker/filament/Generic PLA+ @Anker.json +++ b/resources/profiles/Anker/filament/Generic PLA+ @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Anker", - "inherits": "Generic PLA+ @Anker base", "renamed_from": "Anker Generic PLA+", + "inherits": "Generic PLA+ @Anker base", "from": "system", "setting_id": "MDb4CH02FxbgPNjS", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PLA-CF @Anker.json b/resources/profiles/Anker/filament/Generic PLA-CF @Anker.json index 7be034702f..6b281e029c 100644 --- a/resources/profiles/Anker/filament/Generic PLA-CF @Anker.json +++ b/resources/profiles/Anker/filament/Generic PLA-CF @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Anker", - "inherits": "Generic PLA-CF @Anker base", "renamed_from": "Anker Generic PLA-CF", + "inherits": "Generic PLA-CF @Anker base", "from": "system", "setting_id": "5AdjHUxRi8LCU4E9", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic PVA @Anker.json b/resources/profiles/Anker/filament/Generic PVA @Anker.json index 35a7dd456a..852bf35006 100644 --- a/resources/profiles/Anker/filament/Generic PVA @Anker.json +++ b/resources/profiles/Anker/filament/Generic PVA @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Anker", - "inherits": "Generic PVA @Anker base", "renamed_from": "Anker Generic PVA", + "inherits": "Generic PVA @Anker base", "from": "system", "setting_id": "HXERDaP3AgzWtmiu", "instantiation": "true", diff --git a/resources/profiles/Anker/filament/Generic TPU @Anker.json b/resources/profiles/Anker/filament/Generic TPU @Anker.json index 44204f1113..4b931e51bd 100644 --- a/resources/profiles/Anker/filament/Generic TPU @Anker.json +++ b/resources/profiles/Anker/filament/Generic TPU @Anker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Anker", - "inherits": "Generic TPU @Anker base", "renamed_from": "Anker Generic TPU", + "inherits": "Generic TPU @Anker base", "from": "system", "setting_id": "5YigkBBSP2RM1MbK", "instantiation": "true", diff --git a/resources/profiles/Anycubic.json b/resources/profiles/Anycubic.json index bb0eedbd91..731d2b32eb 100644 --- a/resources/profiles/Anycubic.json +++ b/resources/profiles/Anycubic.json @@ -1,6 +1,6 @@ { "name": "Anycubic", - "version": "02.04.00.07", + "version": "02.04.00.08", "force_update": "0", "description": "Anycubic configurations", "machine_model_list": [ diff --git a/resources/profiles/Anycubic/filament/Generic ABS @Anycubic.json b/resources/profiles/Anycubic/filament/Generic ABS @Anycubic.json index cc7334fa34..99f5351291 100644 --- a/resources/profiles/Anycubic/filament/Generic ABS @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic ABS @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Anycubic", - "inherits": "fdm_filament_abs", "renamed_from": "Anycubic Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "jKvjWU6rcHvWblWC", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Anycubic/filament/Generic ASA @Anycubic.json b/resources/profiles/Anycubic/filament/Generic ASA @Anycubic.json index 282f590739..cc16da633f 100644 --- a/resources/profiles/Anycubic/filament/Generic ASA @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic ASA @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Anycubic", - "inherits": "fdm_filament_asa", "renamed_from": "Anycubic Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "o2Cr8cBtE4OKsTqm", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Anycubic/filament/Generic PA @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PA @Anycubic.json index da5d2424e2..31be665d6d 100644 --- a/resources/profiles/Anycubic/filament/Generic PA @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PA @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Anycubic", - "inherits": "fdm_filament_pa", "renamed_from": "Anycubic Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "5MJsYpJIimshIDZm", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Anycubic/filament/Generic PA-CF @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PA-CF @Anycubic.json index a360cfea1a..56243e67aa 100644 --- a/resources/profiles/Anycubic/filament/Generic PA-CF @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PA-CF @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Anycubic", - "inherits": "fdm_filament_pa", "renamed_from": "Anycubic Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "j1uioy0lCnm4AKrm", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Anycubic/filament/Generic PC @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PC @Anycubic.json index e2da18b155..818f20c41f 100644 --- a/resources/profiles/Anycubic/filament/Generic PC @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PC @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Anycubic", - "inherits": "fdm_filament_pc", "renamed_from": "Anycubic Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "3jP8aWkWw2dT2fNM", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Anycubic/filament/Generic PETG @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PETG @Anycubic.json index 697caad9d7..bace5dcb40 100644 --- a/resources/profiles/Anycubic/filament/Generic PETG @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PETG @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Anycubic", - "inherits": "fdm_filament_pet", "renamed_from": "Anycubic Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "ddafY4oOvEc6L6Ej", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Anycubic/filament/Generic PLA @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PLA @Anycubic.json index e7fe864b7e..f9752fb4a0 100644 --- a/resources/profiles/Anycubic/filament/Generic PLA @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PLA @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Anycubic", - "inherits": "fdm_filament_pla", "renamed_from": "Anycubic Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "qoYfeBQCSt15O9ye", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Anycubic/filament/Generic PLA-CF @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PLA-CF @Anycubic.json index 0f0bd4462a..ba3ed7d904 100644 --- a/resources/profiles/Anycubic/filament/Generic PLA-CF @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PLA-CF @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Anycubic", - "inherits": "fdm_filament_pla", "renamed_from": "Anycubic Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "mLENUT39vBcQiLpm", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Anycubic/filament/Generic PVA @Anycubic.json b/resources/profiles/Anycubic/filament/Generic PVA @Anycubic.json index 7f6603b6db..5223c56dc8 100644 --- a/resources/profiles/Anycubic/filament/Generic PVA @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic PVA @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Anycubic", - "inherits": "fdm_filament_pva", "renamed_from": "Anycubic Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "ae5ljmDsW7uauLz8", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Anycubic/filament/Generic TPU @Anycubic.json b/resources/profiles/Anycubic/filament/Generic TPU @Anycubic.json index d52428e4e5..a14d8f302b 100644 --- a/resources/profiles/Anycubic/filament/Generic TPU @Anycubic.json +++ b/resources/profiles/Anycubic/filament/Generic TPU @Anycubic.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Anycubic", - "inherits": "fdm_filament_tpu", "renamed_from": "Anycubic Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "z0FSikhD8ZHv2UYt", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 Max 0.4 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 Max 0.4 nozzle.json index ed52a91b21..f20d9cc14e 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 Max 0.4 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 Max 0.4 nozzle.json @@ -104,79 +104,64 @@ "machine_end_gcode": "M400\nG92 E0 ; zero the extruder\nG1 E-2 F3600\n{if max_layer_z < max_print_height-1}G1 Z{max_layer_z+2} F900 ; Move print head further up{endif}\nG1 X420 Y420 F12000 ; present print\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107;turn off fan\nM84; disable motors\n; disable stepper motors", "machine_load_filament_time": "75", "machine_max_acceleration_e": [ - "10000", "10000", "10000" ], "machine_max_acceleration_extruding": [ - "10000", "10000", "10000" ], "machine_max_acceleration_retracting": [ - "10000", "10000", "10000" ], "machine_max_acceleration_travel": [ - "10000", "10000", "10000" ], "machine_max_acceleration_x": [ - "10000", "10000", "10000" ], "machine_max_acceleration_y": [ - "10000", "10000", "10000" ], "machine_max_acceleration_z": [ - "3000", "3000", "3000" ], "machine_max_jerk_e": [ - "20", "20", "20" ], "machine_max_jerk_x": [ - "20", "20", "20" ], "machine_max_jerk_y": [ - "20", "20", "20" ], "machine_max_jerk_z": [ - "20", "20", "20" ], "machine_max_speed_e": [ "600", - "300", - "780" + "300" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "20", - "10", - "26" + "10" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.2 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.2 nozzle.json index 676b43000d..09e690ea30 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.2 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.2 nozzle.json @@ -77,79 +77,64 @@ "machine_end_gcode": "G92 E0\nG1 E-2 F3600\n{if max_layer_z < max_print_height-1}G1 Z{max_layer_z+2} F900 ; Move print head further up{endif}\nG1 X250 Y220 F12000 ; present print\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107;turn off fan\nM84; disable motors\n; disable stepper motors\n\n", "machine_load_filament_time": "42", "machine_max_acceleration_e": [ - "20000", "20000", "20000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "1000", "1000", "1000" ], "machine_max_jerk_e": [ - "20", "20", "20" ], "machine_max_jerk_x": [ - "20", "20", "20" ], "machine_max_jerk_y": [ - "20", "20", "20" ], "machine_max_jerk_z": [ - "20", "20", "20" ], "machine_max_speed_e": [ "600", - "300", - "780" + "300" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "15", - "10", - "26" + "10" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.4 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.4 nozzle.json index 8f265955c8..bacaca6168 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.4 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.4 nozzle.json @@ -73,79 +73,64 @@ "machine_end_gcode": "M400\nG92 E0 ; zero the extruder\nG1 E-2 F3600\n{if max_layer_z < max_print_height-1}G1 Z{max_layer_z+2} F900 ; Move print head further up{endif}\nG1 X250 Y220 F12000 ; present print\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107;turn off fan\nM84; disable motors\n; disable stepper motors", "machine_load_filament_time": "42", "machine_max_acceleration_e": [ - "20000", "20000", "20000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "1000", "1000", "1000" ], "machine_max_jerk_e": [ - "20", "20", "20" ], "machine_max_jerk_x": [ - "20", "20", "20" ], "machine_max_jerk_y": [ - "20", "20", "20" ], "machine_max_jerk_z": [ - "20", "20", "20" ], "machine_max_speed_e": [ "600", - "300", - "780" + "300" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "15", - "10", - "26" + "10" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.6 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.6 nozzle.json index b8271d0d74..d76b34af49 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.6 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.6 nozzle.json @@ -73,79 +73,64 @@ "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-1 F3600 ; retract\n{if max_layer_z < max_print_height-1}G1 Z{max_layer_z+2} F600 ; Move print head further up{endif}\nG1 X250 Y220 F12000 ; present print\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107;turn off fan\nM84; disable motors\n; disable stepper motors\n\n", "machine_load_filament_time": "42", "machine_max_acceleration_e": [ - "20000", "20000", "20000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "1000", "1000", "1000" ], "machine_max_jerk_e": [ - "20", "20", "20" ], "machine_max_jerk_x": [ - "20", "20", "20" ], "machine_max_jerk_y": [ - "20", "20", "20" ], "machine_max_jerk_z": [ - "20", "20", "20" ], "machine_max_speed_e": [ "600", - "300", - "780" + "300" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "15", - "10", - "26" + "10" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.8 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.8 nozzle.json index 11565051e6..c28e9c620b 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.8 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2 0.8 nozzle.json @@ -77,79 +77,64 @@ "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-2 F3000 ; retract\n{if max_layer_z < max_print_height-1}G1 Z{max_layer_z+2} F600 ; Move print head further up{endif}\nG1 X250 Y220 F12000 ; present print\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107;turn off fan\nM84; disable motors\n; disable stepper motors\n\n", "machine_load_filament_time": "42", "machine_max_acceleration_e": [ - "20000", "20000", "20000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "1000", "1000", "1000" ], "machine_max_jerk_e": [ - "20", "20", "20" ], "machine_max_jerk_x": [ - "20", "20", "20" ], "machine_max_jerk_y": [ - "20", "20", "20" ], "machine_max_jerk_z": [ - "20", "20", "20" ], "machine_max_speed_e": [ "600", - "300", - "780" + "300" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "15", - "10", - "26" + "10" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2.json b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2.json index 84651d79de..6ce4e4ccf5 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra 3 V2.json @@ -1,12 +1,12 @@ { - "type": "machine_model", - "machine_tech": "FFF", - "family": "Anycubic", - "name": "Anycubic Kobra 3 V2", - "model_id": "Anycubic Kobra 3 V2", - "nozzle_diameter": "0.4;0.2;0.6;0.8", - "bed_model": "Anycubic Kobra 3 V2_buildplate_model.stl", - "bed_texture": "Anycubic Kobra 3 V2_buildplate_texture.svg", - "hotend_model": "", - "default_materials": "Anycubic PLA @Anycubic Kobra 3 V2 0.2 nozzle;Anycubic PLA @Anycubic Kobra 3 V2 0.4 nozzle;Anycubic PLA @Anycubic Kobra 3 V2 0.6 nozzle;Anycubic PLA @Anycubic Kobra 3 V2 0.8 nozzle" + "type": "machine_model", + "name": "Anycubic Kobra 3 V2", + "machine_tech": "FFF", + "family": "Anycubic", + "model_id": "Anycubic Kobra 3 V2", + "nozzle_diameter": "0.4;0.2;0.6;0.8", + "bed_model": "Anycubic Kobra 3 V2_buildplate_model.stl", + "bed_texture": "Anycubic Kobra 3 V2_buildplate_texture.svg", + "hotend_model": "", + "default_materials": "Anycubic PLA @Anycubic Kobra 3 V2 0.2 nozzle;Anycubic PLA @Anycubic Kobra 3 V2 0.4 nozzle;Anycubic PLA @Anycubic Kobra 3 V2 0.6 nozzle;Anycubic PLA @Anycubic Kobra 3 V2 0.8 nozzle" } diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.25 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.25 nozzle.json index 8786b75afa..e49fc80ced 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.25 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.25 nozzle.json @@ -73,79 +73,64 @@ "machine_end_gcode": "M400\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM141 S0 ; turn off box temperature\nM106 P1 S0 ; turn off fan\nM106 P2 S0\nM106 P3 S0\nM84; disable motors \n; disable stepper motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ - "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "400", "400", "400" ], "machine_max_jerk_e": [ - "1", "1", "1" ], "machine_max_jerk_x": [ - "15", "15", "15" ], "machine_max_jerk_y": [ - "15", "15", "15" ], "machine_max_jerk_z": [ - "1", "1", "1" ], "machine_max_speed_e": [ "80", - "40", - "104" + "40" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "10", - "5", - "13" + "5" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.4 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.4 nozzle.json index f0ba840124..917ef24eb7 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.4 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.4 nozzle.json @@ -73,79 +73,64 @@ "machine_end_gcode": "M400\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM141 S0 ; turn off box temperature\nM106 P1 S0 ; turn off fan\nM106 P2 S0\nM106 P3 S0\nM84; disable motors \n; disable stepper motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ - "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "400", "400", "400" ], "machine_max_jerk_e": [ - "1", "1", "1" ], "machine_max_jerk_x": [ - "15", "15", "15" ], "machine_max_jerk_y": [ - "15", "15", "15" ], "machine_max_jerk_z": [ - "1", "1", "1" ], "machine_max_speed_e": [ "80", - "40", - "104" + "40" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "10", - "5", - "13" + "5" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.6 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.6 nozzle.json index 604d488bdb..15069e5a78 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.6 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.6 nozzle.json @@ -73,79 +73,64 @@ "machine_end_gcode": "M400\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM141 S0 ; turn off box temperature\nM106 P1 S0 ; turn off fan\nM106 P2 S0\nM106 P3 S0\nM84; disable motors \n; disable stepper motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ - "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "400", "400", "400" ], "machine_max_jerk_e": [ - "1", "1", "1" ], "machine_max_jerk_x": [ - "15", "15", "15" ], "machine_max_jerk_y": [ - "15", "15", "15" ], "machine_max_jerk_z": [ - "1", "1", "1" ], "machine_max_speed_e": [ "80", - "40", - "104" + "40" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "10", - "5", - "13" + "5" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.8 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.8 nozzle.json index d51a6fc560..711450dd79 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.8 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max 0.8 nozzle.json @@ -73,79 +73,64 @@ "machine_end_gcode": "M400\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM141 S0 ; turn off box temperature\nM106 P1 S0 ; turn off fan\nM106 P2 S0\nM106 P3 S0\nM84; disable motors \n; disable stepper motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ - "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ - "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ - "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ - "20000", "20000", "20000" ], "machine_max_acceleration_x": [ - "20000", "20000", "20000" ], "machine_max_acceleration_y": [ - "20000", "20000", "20000" ], "machine_max_acceleration_z": [ - "400", "400", "400" ], "machine_max_jerk_e": [ - "1", "1", "1" ], "machine_max_jerk_x": [ - "15", "15", "15" ], "machine_max_jerk_y": [ - "15", "15", "15" ], "machine_max_jerk_z": [ - "1", "1", "1" ], "machine_max_speed_e": [ "80", - "40", - "104" + "40" ], "machine_max_speed_x": [ "600", - "300", - "780" + "300" ], "machine_max_speed_y": [ "600", - "300", - "780" + "300" ], "machine_max_speed_z": [ "10", - "5", - "13" + "5" ], "machine_min_extruding_rate": [ "0", diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max.json b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max.json index 0f35afd33f..ec754a7324 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra S1 Max.json @@ -1,12 +1,12 @@ { - "type": "machine_model", - "machine_tech": "FFF", - "family": "Anycubic", - "name": "Anycubic Kobra S1 Max", - "model_id": "Anycubic Kobra S1 Max", - "nozzle_diameter": "0.4;0.25;0.6;0.8", - "bed_model": "Anycubic Kobra S1 Max_buildplate_model.stl", - "bed_texture": "Anycubic Kobra S1 Max_buildplate_texture.svg", - "hotend_model": "", - "default_materials": "Anycubic PLA @Anycubic Kobra S1 Max 0.4 nozzle;Anycubic PLA @Anycubic Kobra S1 Max 0.25 nozzle;Anycubic PLA @Anycubic Kobra S1 Max 0.6 nozzle;Anycubic PLA @Anycubic Kobra S1 Max 0.8 nozzle" + "type": "machine_model", + "name": "Anycubic Kobra S1 Max", + "machine_tech": "FFF", + "family": "Anycubic", + "model_id": "Anycubic Kobra S1 Max", + "nozzle_diameter": "0.4;0.25;0.6;0.8", + "bed_model": "Anycubic Kobra S1 Max_buildplate_model.stl", + "bed_texture": "Anycubic Kobra S1 Max_buildplate_texture.svg", + "hotend_model": "", + "default_materials": "Anycubic PLA @Anycubic Kobra S1 Max 0.4 nozzle;Anycubic PLA @Anycubic Kobra S1 Max 0.25 nozzle;Anycubic PLA @Anycubic Kobra S1 Max 0.6 nozzle;Anycubic PLA @Anycubic Kobra S1 Max 0.8 nozzle" } diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json index 8e2952b123..3bbdb12fc6 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json @@ -53,7 +53,7 @@ "before_layer_change_gcode": "", "best_object_pos": "0.5,0.5", "change_extrusion_role_gcode": "", - "change_filament_gcode": "; FLUSH_START\n;@2026-04-03 17:46:45 3+n换料gcode,包括7=3+4,19=3+4×4\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n;;; SET_VELOCITY_LIMIT VELOCITY=350 ACCEL=10000\n;;; G1 E-2 F4800\n;;; G1 Z{toolchange_z+0.6} F1800\n;;; M106 S0\n;;; G1 X265 F21000\n;;; M400 P370\n;;; G1 X277.5 F600\n;;; G1 E-2 F300\n;;; M400 P361\n;;; G1 Z{toolchange_z+3} F1200\n;;; G1 X0 F21000\n;;; G1 X-17.5 F5250\n;;; M400 P1569\n\n{local minimal_extrude_ = 5.0}\n{if one_of(filament_type[current_extruder], \"TPU\", \"PVA\")}\n{local minimal_extrude_ = 8.0}\n{endif}\n;;; G1 E{minimal_extrude_} F300\n;;; G1 E-33 F600\n\n{ local curr_t = current_extruder; local next_t = next_extruder;}\n{ local tab_step_time_ = (0, 850, 1350, 850, 850, 0, 1350, 1350, 1350, 1350, 0, 850, 850, 1350, 850, 0)};\n{ if (0 <= curr_t && curr_t < 3) then local step_from_=curr_t else local step_from_=3 endif}; from {step_from_}\n{ if (0 <= next_t && next_t < 3) then local step_into_=next_t else local step_into_=3 endif}; from {step_into_}\n;;; M400 P{tab_step_time_[step_from_ * 4 + step_into_]}\n\n{ local magic_mask_with_box = flush_length_4}\n{ if magic_mask_with_box == -1392 }\n { local is_curr_in_box = size(ace_t_box_vector) > curr_t ? ace_t_box_vector[curr_t] >= 0 ? true : false : false}; is_curr_in_box = {is_curr_in_box}\n { local is_next_in_box = size(ace_t_box_vector) > next_t ? ace_t_box_vector[next_t] >= 0 ? true : false : false}; is_next_in_box = {is_next_in_box}\n\n; curr_t box={ace_t_box_vector[curr_t]}, slot={ace_t_slot_vector[curr_t]}; next_t box={ace_t_box_vector[next_t]}, slot={ace_t_slot_vector[next_t]}\n { if ace_t_box_vector[curr_t] < 0 && ace_t_box_vector[next_t] < 0}\n;;; M400 P0 ; 料架→料架\n { elsif ace_t_box_vector[curr_t] < 0 && ace_t_box_vector[next_t] >= 0 }\n;;; M400 P40409 ; 料架→盒子\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] < 0 }\n;;; M400 P51591 ; 盒子→料架\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] == ace_t_box_vector[curr_t] }\n { if 0 < ace_t_slot_vector[curr_t] && ace_t_slot_vector[curr_t] <= 4 && 0 < ace_t_slot_vector[next_t] && ace_t_slot_vector[next_t] <= 4}\n;;; M400 P2700 ; 四进四→料盒\n { else }\n;;; M400 P91279 ; 盒子→盒子\n { endif }\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] != ace_t_box_vector[curr_t] }\n;;; M400 P93746 ; 盒子→不同盒子\n { else }\n; 未知\n { endif }\n{ endif }\n\n\nT[next_extruder]\n\n;;; G1 E8 F300\n;;; M400 P3643\n;;; G1 E13 F1200\n;;; M400 P1000\n\n{local flush_length_= flush_length}\n{local loops_=max(1,int((flush_length_-70+150) / 150))}\n{local extrude_length_=flush_length_ / loops_}\n{local EXTRUDE_SPEED_ = 5 * 60}\n{local UNWIND_SPEED_ = 20 *60}\n{local index_ = 0}\n\n{ if (loops_ > 0) }\n{ local loops_ = loops_ - 1}\n{ local index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; G1 E0.000001\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ loops_ = loops_ - 1}\n{ index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ loops_ = loops_ - 1}\n{ index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n\n; G1 X{x_after_toolchange} Y{y_after_toolchange} F12000\n; G1 Z{toolchange_z} F1200\n;;; G1 E2 F1800\n; SET_VELOCITY_LIMIT VELOCITY=450 ACCEL=10000\n;;; M400 P0\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n; FLUSH_END", + "change_filament_gcode": "; FLUSH_START\n;@2026-04-03 17:46:45 3+n换料gcode,包括7=3+4,19=3+4×4\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n;;; SET_VELOCITY_LIMIT VELOCITY=350 ACCEL=10000\n;;; G1 E-2 F4800\n;;; G1 Z{toolchange_z+0.6} F1800\n;;; M106 S0\n;;; G1 X265 F21000\n;;; M400 P370\n;;; G1 X277.5 F600\n;;; G1 E-2 F300\n;;; M400 P361\n;;; G1 Z{toolchange_z+3} F1200\n;;; G1 X0 F21000\n;;; G1 X-17.5 F5250\n;;; M400 P1569\n\n{local minimal_extrude_ = 5.0}\n{if one_of(filament_type[current_extruder], \"TPU\", \"PVA\")}\n{local minimal_extrude_ = 8.0}\n{endif}\n;;; G1 E{minimal_extrude_} F300\n;;; G1 E-33 F600\n\n{ local curr_t = current_extruder; local next_t = next_extruder;}\n{ local tab_step_time_ = (0, 850, 1350, 850, 850, 0, 1350, 1350, 1350, 1350, 0, 850, 850, 1350, 850, 0)};\n{ if (0 <= curr_t && curr_t < 3) then local step_from_=curr_t else local step_from_=3 endif}; from {step_from_}\n{ if (0 <= next_t && next_t < 3) then local step_into_=next_t else local step_into_=3 endif}; from {step_into_}\n;;; M400 P{tab_step_time_[step_from_ * 4 + step_into_]}\n\n\nT[next_extruder]\n\n;;; G1 E8 F300\n;;; M400 P3643\n;;; G1 E13 F1200\n;;; M400 P1000\n\n{local flush_length_= flush_length}\n{local loops_=max(1,int((flush_length_-70+150) / 150))}\n{local extrude_length_=flush_length_ / loops_}\n{local EXTRUDE_SPEED_ = 5 * 60}\n{local UNWIND_SPEED_ = 20 *60}\n{local index_ = 0}\n\n{ if (loops_ > 0) }\n{ local loops_ = loops_ - 1}\n{ local index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; G1 E0.000001\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ loops_ = loops_ - 1}\n{ index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ loops_ = loops_ - 1}\n{ index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n\n; G1 X{x_after_toolchange} Y{y_after_toolchange} F12000\n; G1 Z{toolchange_z} F1200\n;;; G1 E2 F1800\n; SET_VELOCITY_LIMIT VELOCITY=450 ACCEL=10000\n;;; M400 P0\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n; FLUSH_END", "cooling_tube_length": "0", "cooling_tube_retraction": "0", "deretraction_speed": [ @@ -85,48 +85,63 @@ "machine_end_gcode": "M400\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107;turn off fan\nM84; disable motors\n; disable stepper motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "6500", "6500" ], "machine_max_acceleration_extruding": [ + "6500", "6500" ], "machine_max_acceleration_retracting": [ + "6500", "6500" ], "machine_max_acceleration_travel": [ + "10000", "10000" ], "machine_max_acceleration_x": [ + "10000", "10000" ], "machine_max_acceleration_y": [ + "10000", "10000" ], "machine_max_acceleration_z": [ + "1000", "1000" ], "machine_max_jerk_e": [ + "1", "1" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "20", "20" ], "machine_max_speed_e": [ + "250", "250" ], "machine_max_speed_x": [ + "450", "450" ], "machine_max_speed_y": [ + "450", "450" ], "machine_max_speed_z": [ + "12", "12" ], "machine_min_extruding_rate": [ diff --git a/resources/profiles/Artillery.json b/resources/profiles/Artillery.json index 180622cf3a..faa5aa0a98 100644 --- a/resources/profiles/Artillery.json +++ b/resources/profiles/Artillery.json @@ -1,6 +1,6 @@ { "name": "Artillery", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Artillery configurations", "machine_model_list": [ diff --git a/resources/profiles/Artillery/filament/Generic ABS @Artillery.json b/resources/profiles/Artillery/filament/Generic ABS @Artillery.json index caf687b95e..bad2754127 100644 --- a/resources/profiles/Artillery/filament/Generic ABS @Artillery.json +++ b/resources/profiles/Artillery/filament/Generic ABS @Artillery.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFY9muEs", - "setting_id": "DNgTEZpEz8bJoobJ", "name": "Generic ABS @Artillery", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_abs", "renamed_from": "Artillery Generic ABS", + "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "DNgTEZpEz8bJoobJ", + "filament_id": "OFY9muEs", + "instantiation": "true", "filament_flow_ratio": [ "0.926" ], diff --git a/resources/profiles/Artillery/filament/Generic ASA @Artillery.json b/resources/profiles/Artillery/filament/Generic ASA @Artillery.json index 74ef4c775f..afc3e0cafc 100644 --- a/resources/profiles/Artillery/filament/Generic ASA @Artillery.json +++ b/resources/profiles/Artillery/filament/Generic ASA @Artillery.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFLPAxz3", - "setting_id": "xWHuScm0fPJCqjVx", "name": "Generic ASA @Artillery", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_asa", "renamed_from": "Artillery Generic ASA", + "inherits": "fdm_filament_asa", + "from": "system", + "setting_id": "xWHuScm0fPJCqjVx", + "filament_id": "OFLPAxz3", + "instantiation": "true", "filament_flow_ratio": [ "0.93" ], diff --git a/resources/profiles/Artillery/filament/Generic PETG @Artillery.json b/resources/profiles/Artillery/filament/Generic PETG @Artillery.json index aa354e517d..8abc30673a 100644 --- a/resources/profiles/Artillery/filament/Generic PETG @Artillery.json +++ b/resources/profiles/Artillery/filament/Generic PETG @Artillery.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFYPdQJh", - "setting_id": "6wZKfV2XvuJSUSwl", "name": "Generic PETG @Artillery", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_pet", "renamed_from": "Artillery Generic PETG", + "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "6wZKfV2XvuJSUSwl", + "filament_id": "OFYPdQJh", + "instantiation": "true", "reduce_fan_stop_start_freq": [ "1" ], diff --git a/resources/profiles/Artillery/filament/Generic PLA @Artillery.json b/resources/profiles/Artillery/filament/Generic PLA @Artillery.json index d691a9b470..6b5a88cfda 100644 --- a/resources/profiles/Artillery/filament/Generic PLA @Artillery.json +++ b/resources/profiles/Artillery/filament/Generic PLA @Artillery.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFDSrzZ8", - "setting_id": "T0sW3uMBr94Y1X1G", "name": "Generic PLA @Artillery", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_pla", "renamed_from": "Artillery Generic PLA", + "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "T0sW3uMBr94Y1X1G", + "filament_id": "OFDSrzZ8", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Artillery/filament/Generic PLA-CF @Artillery.json b/resources/profiles/Artillery/filament/Generic PLA-CF @Artillery.json index 08fd583e18..e3541dd937 100644 --- a/resources/profiles/Artillery/filament/Generic PLA-CF @Artillery.json +++ b/resources/profiles/Artillery/filament/Generic PLA-CF @Artillery.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFWbdGsC", - "setting_id": "Gxafdb0zYnf9kPwa", "name": "Generic PLA-CF @Artillery", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_pla", "renamed_from": "Artillery Generic PLA-CF", + "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "Gxafdb0zYnf9kPwa", + "filament_id": "OFWbdGsC", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Artillery/filament/Generic TPU @Artillery.json b/resources/profiles/Artillery/filament/Generic TPU @Artillery.json index f1270d0afb..75a423c165 100644 --- a/resources/profiles/Artillery/filament/Generic TPU @Artillery.json +++ b/resources/profiles/Artillery/filament/Generic TPU @Artillery.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFgbpcy9", - "setting_id": "dWhysRiE5GrAGyME", "name": "Generic TPU @Artillery", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_tpu", "renamed_from": "Artillery Generic TPU", + "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "dWhysRiE5GrAGyME", + "filament_id": "OFgbpcy9", + "instantiation": "true", "filament_max_volumetric_speed": [ "3.2" ], diff --git a/resources/profiles/Artillery/filament/fdm_filament_abs.json b/resources/profiles/Artillery/filament/fdm_filament_abs.json index 0b06432204..5eb599e552 100644 --- a/resources/profiles/Artillery/filament/fdm_filament_abs.json +++ b/resources/profiles/Artillery/filament/fdm_filament_abs.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_abs", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "105" ], diff --git a/resources/profiles/Artillery/filament/fdm_filament_asa.json b/resources/profiles/Artillery/filament/fdm_filament_asa.json index 930a2d3d0f..795413a24d 100644 --- a/resources/profiles/Artillery/filament/fdm_filament_asa.json +++ b/resources/profiles/Artillery/filament/fdm_filament_asa.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_asa", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "105" ], diff --git a/resources/profiles/Artillery/filament/fdm_filament_pet.json b/resources/profiles/Artillery/filament/fdm_filament_pet.json index 379e0e0013..da7e5db8ec 100644 --- a/resources/profiles/Artillery/filament/fdm_filament_pet.json +++ b/resources/profiles/Artillery/filament/fdm_filament_pet.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pet", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "60" ], diff --git a/resources/profiles/Artillery/filament/fdm_filament_pla.json b/resources/profiles/Artillery/filament/fdm_filament_pla.json index 062c3ea6f5..e8f09e7717 100644 --- a/resources/profiles/Artillery/filament/fdm_filament_pla.json +++ b/resources/profiles/Artillery/filament/fdm_filament_pla.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pla", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "fan_cooling_layer_time": [ "100" ], diff --git a/resources/profiles/Artillery/filament/fdm_filament_tpu.json b/resources/profiles/Artillery/filament/fdm_filament_tpu.json index 91b0b1a200..fe1520851b 100644 --- a/resources/profiles/Artillery/filament/fdm_filament_tpu.json +++ b/resources/profiles/Artillery/filament/fdm_filament_tpu.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_tpu", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "30" ], diff --git a/resources/profiles/Artillery/machine/Artillery Genius 0.4 nozzle.json b/resources/profiles/Artillery/machine/Artillery Genius 0.4 nozzle.json index fec7ef73d3..71250b7ccd 100644 --- a/resources/profiles/Artillery/machine/Artillery Genius 0.4 nozzle.json +++ b/resources/profiles/Artillery/machine/Artillery Genius 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "F9lEQfH826Mqt6u3", "name": "Artillery Genius 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "F9lEQfH826Mqt6u3", + "instantiation": "true", "printer_model": "Artillery Genius", "default_print_profile": "0.20mm Standard @Artillery Genius", "nozzle_diameter": [ diff --git a/resources/profiles/Artillery/machine/Artillery Genius Pro 0.4 nozzle.json b/resources/profiles/Artillery/machine/Artillery Genius Pro 0.4 nozzle.json index abac060832..27dbc934c8 100644 --- a/resources/profiles/Artillery/machine/Artillery Genius Pro 0.4 nozzle.json +++ b/resources/profiles/Artillery/machine/Artillery Genius Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "afpW4NvrOWzQvHbB", "name": "Artillery Genius Pro 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "afpW4NvrOWzQvHbB", + "instantiation": "true", "printer_model": "Artillery Genius Pro", "default_print_profile": "0.20mm Standard @Artillery Genius Pro", "nozzle_diameter": [ diff --git a/resources/profiles/Artillery/machine/Artillery Hornet 0.4 nozzle.json b/resources/profiles/Artillery/machine/Artillery Hornet 0.4 nozzle.json index 232b68d62e..65a60c6649 100644 --- a/resources/profiles/Artillery/machine/Artillery Hornet 0.4 nozzle.json +++ b/resources/profiles/Artillery/machine/Artillery Hornet 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "02YSChoFQuBRQ8vf", "name": "Artillery Hornet 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "02YSChoFQuBRQ8vf", + "instantiation": "true", "printer_model": "Artillery Hornet", "default_print_profile": "0.20mm Standard @Artillery Hornet", "nozzle_diameter": [ diff --git a/resources/profiles/Artillery/machine/Artillery Sidewinder X1 0.4 nozzle.json b/resources/profiles/Artillery/machine/Artillery Sidewinder X1 0.4 nozzle.json index ab83e7d429..3e10106e08 100644 --- a/resources/profiles/Artillery/machine/Artillery Sidewinder X1 0.4 nozzle.json +++ b/resources/profiles/Artillery/machine/Artillery Sidewinder X1 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "nY4RXX9Ylh7AIc4U", "name": "Artillery Sidewinder X1 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "nY4RXX9Ylh7AIc4U", + "instantiation": "true", "printer_model": "Artillery Sidewinder X1", "default_print_profile": "0.20mm Standard @Artillery X1", "nozzle_diameter": [ diff --git a/resources/profiles/Artillery/machine/Artillery Sidewinder X2 0.4 nozzle.json b/resources/profiles/Artillery/machine/Artillery Sidewinder X2 0.4 nozzle.json index 416ddfb056..a4ac11e7f9 100644 --- a/resources/profiles/Artillery/machine/Artillery Sidewinder X2 0.4 nozzle.json +++ b/resources/profiles/Artillery/machine/Artillery Sidewinder X2 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "cUhse9TrF7ElM5dh", "name": "Artillery Sidewinder X2 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "cUhse9TrF7ElM5dh", + "instantiation": "true", "printer_model": "Artillery Sidewinder X2", "default_print_profile": "0.20mm Standard @Artillery X2", "nozzle_diameter": [ diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 44354ce026..68d2028473 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "02.08.00.10", + "version": "02.08.00.12", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json index fd561c9b02..c00681818c 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json @@ -21,9 +21,11 @@ "0.0241" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json index 43827c7a5e..538d2920ec 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.3341" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json index 7fd3b25a7e..798ed443ba 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json @@ -21,6 +21,7 @@ "0.0241" ], "fan_max_speed": [ + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json index 410db132d7..28b7404dc2 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json @@ -21,6 +21,8 @@ "0.3341" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.2 nozzle.json index e357dc5e05..ba4c0fd8b8 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.2 nozzle.json @@ -21,6 +21,7 @@ "0.0241" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.6 nozzle.json index 328543f9c0..9434bd4159 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.0241" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.8 nozzle.json index 5d75f70a48..6cc753de96 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D 0.8 nozzle.json @@ -21,6 +21,7 @@ "0.0241" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D.json index dcbe4c9c9b..10b4722918 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2D.json @@ -21,6 +21,8 @@ "0.0241" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json index afb7d2af99..a13bfa07e8 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.2 nozzle.json @@ -9,6 +9,7 @@ "65" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json index 5ed4484f7f..980bdef186 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.6 nozzle.json @@ -9,6 +9,7 @@ "65" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json index 5f5a3435d7..284578284a 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP 0.8 nozzle.json @@ -9,6 +9,7 @@ "65" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json index ed170c8a30..9e9162545e 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2DP.json @@ -9,6 +9,7 @@ "65" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.2 nozzle.json index 6f18702239..2945800452 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.2 nozzle.json @@ -21,9 +21,11 @@ "0.3341" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.6 nozzle.json index d995f5cf2f..22595bb69d 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.3341" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.8 nozzle.json index af38270fbb..d6ab8201db 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S 0.8 nozzle.json @@ -21,6 +21,7 @@ "0.3341" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S.json index 35a8d05943..84027cf8dc 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2S.json @@ -21,6 +21,8 @@ "0.3341" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.4 nozzle.json index d2b3ac673b..025925b578 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.4 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_38", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.6 nozzle.json index df087aa06b..e83e751cb1 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL P1S 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_39", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.2 nozzle.json index 0c48231b9e..4788f5e566 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_14", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "chamber_temperatures": [ @@ -24,6 +25,7 @@ "0.0241" ], "fan_min_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.6 nozzle.json index 6627fb2e62..98be4a6887 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.3341" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.8 nozzle.json index bb2c6c215c..3c42f060f5 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_15", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "chamber_temperatures": [ @@ -24,6 +25,7 @@ "0.0241" ], "fan_max_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S.json b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S.json index 2b3151df5f..c22e0202c5 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSB00_10", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ @@ -24,6 +26,8 @@ "0.3341" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json index ef901b0dc1..a55b483e20 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_00", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.6 nozzle.json index b7d3a06ea2..aecbbff44d 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_40", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json index c25c690d8b..597c843568 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_01", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json index 4632ca054f..d95cb4a119 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.2 nozzle.json index 63b7b1ea67..ba65ac0e69 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_05", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.8 nozzle.json index 5022a70244..18639ac21f 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1E 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_06", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1E.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1E.json index 996212ace3..22b568affb 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1E.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1E.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_04", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.2 nozzle.json index 31edcc6add..bb895bc66a 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.2 nozzle.json @@ -21,6 +21,9 @@ "0.0241" ], "fan_min_speed": [ + "80", + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.4 nozzle.json index e647fa477c..0defaafc07 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.4 nozzle.json @@ -21,6 +21,11 @@ "0.0241" ], "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.8 nozzle.json index ab10c78829..33bf55cdf1 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D 0.8 nozzle.json @@ -21,6 +21,9 @@ "0.0241" ], "fan_max_speed": [ + "60", + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D.json index 6a0850497b..6f9adbd82a 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X2D.json @@ -21,6 +21,11 @@ "0.0241" ], "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL P2S.json index 0e8b03a063..6e921bdcc0 100644 --- a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSB50_04", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.2 nozzle.json index d93ebff0f4..3b07712c16 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB01_15", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "chamber_temperatures": [ @@ -24,9 +25,11 @@ "-0.0092" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.4 nozzle.json index 8751a771b7..b06aaf1b4a 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSB01_16", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.6 nozzle.json index 6b8e36bb44..035e6e1269 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSB01_14", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ @@ -24,6 +26,8 @@ "0.2258" ], "fan_min_speed": [ + "25", + "25", "25" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.8 nozzle.json index 284e476b53..1967867290 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL P2S 0.8 nozzle.json @@ -21,6 +21,7 @@ "-0.0092" ], "fan_min_speed": [ + "25", "25" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL X1 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL X1 0.6 nozzle.json index 63e38090f7..01b0a9ec05 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL X1 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL X1 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB01_04", "instantiation": "true", "fan_min_speed": [ + "25", "25" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL X1C.json b/resources/profiles/BBL/filament/Bambu ASA @BBL X1C.json index ab1677285e..a4b301716c 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSB01_00", "instantiation": "true", "fan_min_speed": [ + "25", "25" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL X1E.json b/resources/profiles/BBL/filament/Bambu ASA @BBL X1E.json index 9336323c61..7bf1d303ca 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL X1E.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL X1E.json @@ -6,6 +6,7 @@ "setting_id": "GFSB01_05", "instantiation": "true", "fan_min_speed": [ + "25", "25" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL X2D 0.8 nozzle.json index 4bf30b3fce..45a24500f6 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL X2D 0.8 nozzle.json @@ -21,6 +21,9 @@ "-0.0092" ], "fan_min_speed": [ + "25", + "25", + "25", "25" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL X2D.json b/resources/profiles/BBL/filament/Bambu ASA @BBL X2D.json index 38c96bff13..9f702c0058 100644 --- a/resources/profiles/BBL/filament/Bambu ASA @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL X2D.json @@ -21,6 +21,11 @@ "-0.0092" ], "fan_min_speed": [ + "25", + "25", + "25", + "25", + "25", "25" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL P2S.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL P2S.json index 3a8ecc97b9..592b65fef4 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSB02_04", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.4 nozzle.json index eb7f04ca4e..30b6e616e6 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSB51_08", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.6 nozzle.json index 49b0a84c3c..fdff13b164 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSB51_09", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2S.json index b1a9ff5a1b..dce0062f7a 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2S.json @@ -12,9 +12,13 @@ "5" ], "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL P2S.json index 5459a2e484..70d1a9841c 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSN03_03", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ @@ -15,9 +17,13 @@ "5" ], "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json index 52af58d8ba..a6b2b9f83a 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json @@ -9,9 +9,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1E.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1E.json index b12f9f014e..38e1aa5902 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1E.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1E.json @@ -12,9 +12,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D 0.4 nozzle.json index 4cd5698e7f..c94de9de77 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D 0.4 nozzle.json @@ -15,9 +15,19 @@ "5" ], "fan_max_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "fan_min_speed": [ + "10", + "10", + "10", + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D.json index 384d2e4f3b..d0b17e5af0 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X2D.json @@ -15,9 +15,19 @@ "5" ], "fan_max_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "fan_min_speed": [ + "10", + "10", + "10", + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.6 nozzle.json index 1f5d9d345e..20193526c3 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSN05_25", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.8 nozzle.json index 3c469c04ec..a7945881c9 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSN05_26", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S.json index 8fe541f028..4ba451c4b5 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSN05_05", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X2D 0.4 nozzle.json index 2f8844aac0..34a181b789 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X2D 0.4 nozzle.json @@ -21,9 +21,19 @@ "-0.038" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "20", + "20", + "20", + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL P2S.json index 88ec94b226..dcfec62f7a 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSN08_04", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.6 nozzle.json index 6bf14f208f..f133eedc1d 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSN04_27", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.8 nozzle.json index 256de3bf41..e0cab2e004 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSN04_28", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S.json index 1adc791245..90443c1446 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSN04_02", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL X2D 0.4 nozzle.json index 0f02b6ea95..778e557421 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL X2D 0.4 nozzle.json @@ -21,9 +21,19 @@ "-0.055" ], "fan_max_speed": [ + "45", + "45", + "45", + "45", + "45", "45" ], "fan_min_speed": [ + "25", + "25", + "25", + "25", + "25", "25" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json index a3ba75304a..5a84b1af84 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json @@ -21,6 +21,7 @@ "0.0183" ], "fan_max_speed": [ + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json index b53e6eaf93..cd61e78fd6 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.2208" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json index f4f455a8b2..ac5133e81e 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json @@ -21,6 +21,7 @@ "0.0183" ], "fan_max_speed": [ + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json index b2bb924ca0..90fb772a06 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json @@ -21,6 +21,8 @@ "0.2208" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.2 nozzle.json index fea45a13bd..2830345d52 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.2 nozzle.json @@ -21,6 +21,7 @@ "0.0183" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.4 nozzle.json index 7877739470..b5fb71be51 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.4 nozzle.json @@ -21,6 +21,8 @@ "0.0183" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.6 nozzle.json index 50a080979a..5abbb98402 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.0183" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.8 nozzle.json index 37aa3eb857..f287b4b916 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2D 0.8 nozzle.json @@ -21,6 +21,7 @@ "0.0183" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json index 55575cee0b..fdcc06fe39 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json index 4f843feadd..1fd18e3279 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.4 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json index 1417c3c5a0..31025856e9 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.6 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json index 01f3c1431f..159942cfe2 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2DP 0.8 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.2 nozzle.json index 8b6b883bb6..6887890740 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.2 nozzle.json @@ -18,6 +18,7 @@ "0.2208" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.6 nozzle.json index 21a6b513d5..7cffb5f3d7 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.6 nozzle.json @@ -21,6 +21,8 @@ "0.2208" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.8 nozzle.json index 6564a05f22..1d18c887cd 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2S 0.8 nozzle.json @@ -21,6 +21,7 @@ "0.2208" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2S.json index 0a6ae94079..8cdcb1f9b5 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2S.json @@ -21,6 +21,8 @@ "0.2208" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.4 nozzle.json index 37390058bf..c7b0d65ca6 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.4 nozzle.json @@ -27,6 +27,8 @@ "100" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.6 nozzle.json index 0e8d81de92..fcad5a9ccf 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.6 nozzle.json @@ -27,6 +27,8 @@ "100" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.8 nozzle.json index 27a717ab89..d22d8550ef 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL P2S 0.8 nozzle.json @@ -27,6 +27,7 @@ "100" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json index b2227e037e..dd9ab06970 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSC00_02", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json index e8b0cf29d0..47dbdb48ac 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSC00_01", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json index 7b18784bc6..4c2820a6f7 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSC00_00", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C.json index 2462d8ccb9..ce801cb6c2 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSC00", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.2 nozzle.json index 8cab064d11..4bfeb106eb 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.6 nozzle.json index 6166c3653e..265364e4fd 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.6 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.8 nozzle.json index 299637f67d..1fe2bd26c4 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1E 0.8 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1E.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1E.json index a0f287e1e5..d452548dfc 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1E.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1E.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.4 nozzle.json index ef08e157a6..8c844e320e 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.4 nozzle.json @@ -21,9 +21,19 @@ "0.0183" ], "fan_max_speed": [ + "55", + "55", + "55", + "55", + "55", "55" ], "fan_min_speed": [ + "25", + "25", + "25", + "25", + "25", "25" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.8 nozzle.json index 45a270ee3a..0fe7536db8 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X2D 0.8 nozzle.json @@ -21,6 +21,9 @@ "0.0183" ], "fan_max_speed": [ + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PC @BBL X2D.json index dfd7ca334f..94e8ba6fc5 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X2D.json @@ -21,6 +21,11 @@ "0.0183" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json index ffde022ea3..40e596e5a9 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json index fcf1a079ce..460057a736 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json index 957304bc2a..5446841b6e 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.2 nozzle.json index e768297ad6..02269c8464 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.4 nozzle.json index 75dffbd64b..a3c4f6355a 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.4 nozzle.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.6 nozzle.json index e30efad3f5..3b16cfe4ce 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.6 nozzle.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.8 nozzle.json index 9806d53088..27a87f6ce9 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2D 0.8 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json index d61c1da460..a68b8ebf75 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json index 8902b0bd27..42bbef7019 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.4 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json index 0ba2dc14ed..99e6d107ab 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.6 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json index 1b1768ef51..4d8873fd12 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2DP 0.8 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S 0.2 nozzle.json index ebcb2129dd..d773154c7d 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S.json index cf9963a435..aaf725a515 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2S.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P 0.2 nozzle.json index b9e028b071..8fbd9582bc 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P 0.2 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P.json index 50c66f2864..c532964815 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1P.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.2 nozzle.json index 472acab285..53d7d9f9f0 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.2 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.6 nozzle.json index 1089e6e4d7..1d12b0f53f 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.6 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.8 nozzle.json index a8d3cea654..f7a86aaf4c 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S 0.8 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S.json index 0150515d70..93a219b4dd 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P1S.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.4 nozzle.json index ea21badf01..12cc5c1f31 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.4 nozzle.json @@ -15,6 +15,8 @@ "100" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.6 nozzle.json index ae0a394959..ad42035768 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.6 nozzle.json @@ -15,6 +15,8 @@ "100" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.8 nozzle.json index 6698de66a4..e1b6bcbb96 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL P2S 0.8 nozzle.json @@ -15,6 +15,7 @@ "100" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.2 nozzle.json index a58b3a34fc..4b764c32bf 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSC01_03", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.6 nozzle.json index 5f9fc6b9f8..41825cbce6 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSC01_01", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.8 nozzle.json index bf7f605858..f7704e22bf 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSC01_02", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C.json index c30bef59b3..b3b011aefe 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSC01_00", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.2 nozzle.json index d786e82f33..01ea062c32 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.2 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.6 nozzle.json index f5545427f1..d323b5ff9b 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.6 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.8 nozzle.json index 050855f467..9f7506e488 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E 0.8 nozzle.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E.json index 5314f3101a..5c062b2d0f 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X1E.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.4 nozzle.json index ccdeb880a0..fcf2b10b28 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.4 nozzle.json @@ -9,6 +9,11 @@ "60" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.8 nozzle.json index 5c58c59432..8661cafc38 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D 0.8 nozzle.json @@ -9,6 +9,9 @@ "60" ], "fan_max_speed": [ + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D.json index 9dd52a836f..032233bbfa 100644 --- a/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL X2D.json @@ -9,6 +9,11 @@ "60" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json index 4633db0021..08692a967c 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json @@ -30,9 +30,13 @@ "80" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", "1" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json index cee2b21e4d..8fc8fa046b 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json @@ -30,9 +30,13 @@ "80" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", "1" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2D.json index 204fcc2b98..b6824b4c0b 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2D.json @@ -30,9 +30,13 @@ "80" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", "1" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json index d6a563e31f..d60c7cecff 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2DP.json @@ -24,9 +24,11 @@ "80" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "1", "1" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2S.json index 9eb410e996..d1726e1a55 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2S.json @@ -30,9 +30,13 @@ "80" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", "1" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL P2S.json index 8d5f30f117..5331a62893 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL P2S.json @@ -30,9 +30,13 @@ "80" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", "1" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1C.json index e119b37000..5c48a06982 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1C.json @@ -9,9 +9,11 @@ "80" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "1", "1" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1E.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1E.json index 2e750018cf..1ce4d8ac33 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1E.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X1E.json @@ -12,9 +12,11 @@ "80" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "1", "1" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D 0.4 nozzle.json index 55a854c514..42156c4444 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D 0.4 nozzle.json @@ -30,9 +30,19 @@ "80" ], "fan_max_speed": [ + "80", + "80", + "80", + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D.json index 277b655bf1..f902e4b8c7 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL X2D.json @@ -30,9 +30,19 @@ "80" ], "fan_max_speed": [ + "80", + "80", + "80", + "80", + "80", "80" ], "fan_min_speed": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json index 1767dc81c5..5b3ffab072 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_24", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json index 9611d1f270..cd0d3bc27d 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG00_23", "instantiation": "true", "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.8 nozzle.json index f84645846a..b37b8dffc7 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_44", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json index 1b09bc58f6..fc20f3b466 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSG00_25", "instantiation": "true", "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.2 nozzle.json index bc8b057d8a..754241c419 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_15", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.4 nozzle.json index a2fd083bc2..08293df379 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG00_09", "instantiation": "true", "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.6 nozzle.json index 22ad00b017..bb30864d70 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSG00_16", "instantiation": "true", "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.8 nozzle.json index 122c8a04cc..e3e9d11068 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_45", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json index 36bb96bd39..f3ace78797 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_20", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json index c2a14583c4..7e6b7ce770 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG00_19", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json index 53a228357b..bd9579de8a 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_21", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.8 nozzle.json index 50663c56b2..82534872ba 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_46", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.2 nozzle.json index 7c16a6a6c9..a513dff4d9 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_11", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json index 48fdf41ed8..50b170db33 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG00_32", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.8 nozzle.json index 3887491880..5c04eb6cce 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG00_47", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json index a640e8927f..11db629a3b 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json @@ -6,9 +6,13 @@ "setting_id": "GFSG00_10", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.2 nozzle.json index c718d3d5a3..16e0ee2324 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.2 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG00_17", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.4 nozzle.json index 8c24685000..cc6375362e 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG00_14", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.6 nozzle.json index 1b5a5fb77e..1a01f48967 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.6 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG00_18", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.8 nozzle.json index 0bcf1a6a65..375ecfbb25 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL P2S 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG00_48", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.2 nozzle.json index 9d1f36e9f3..de6792eb32 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.2 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG00_00", "instantiation": "true", "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.8 nozzle.json index b7a18afcd6..31a23708dd 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG00_02", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C.json index a43717b952..96139668a3 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSG00_01", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.2 nozzle.json index 69852348e4..8f22458ba7 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.2 nozzle.json @@ -6,9 +6,15 @@ "setting_id": "GFSG00_13", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.4 nozzle.json index c6cba824fd..99741b8e2b 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.4 nozzle.json @@ -6,9 +6,19 @@ "setting_id": "GFSG00_12", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.8 nozzle.json index bf242cb1c1..4523b64c71 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D 0.8 nozzle.json @@ -6,9 +6,15 @@ "setting_id": "GFSG00_49", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D.json index 829448ab91..6f26175cfd 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL X2D.json @@ -6,9 +6,19 @@ "setting_id": "GFSG00_22", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json index 0fbf4068cb..10cf829118 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json @@ -21,6 +21,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json index 71292a2121..c41df16615 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json @@ -21,6 +21,8 @@ "20" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json index 6be40ba26d..bd71516546 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json @@ -21,6 +21,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json index 77226518e4..7298848d07 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json @@ -21,6 +21,8 @@ "20" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.2 nozzle.json index d7e22db57d..6e36e81da8 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.2 nozzle.json @@ -21,6 +21,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.4 nozzle.json index e53509cfa5..f290a019f6 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.4 nozzle.json @@ -21,9 +21,13 @@ "20" ], "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.6 nozzle.json index 4ebbc2da27..e7e359704c 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.6 nozzle.json @@ -21,6 +21,8 @@ "20" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.8 nozzle.json index 20402f5724..3303ea7265 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2D 0.8 nozzle.json @@ -21,6 +21,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json index e0eaa5b1f4..63e2a461f8 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.2 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json index 7fec884516..71189a22a9 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.4 nozzle.json @@ -18,6 +18,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json index 9a75d0fb5c..612992bf14 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.6 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json index d4f215c1f2..3d2fd0c48c 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2DP 0.8 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.2 nozzle.json index ecfadc5c2f..98b79fb3ad 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.2 nozzle.json @@ -21,9 +21,11 @@ "20" ], "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.6 nozzle.json index a06b5d9f2a..28d6e8e8aa 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.6 nozzle.json @@ -21,9 +21,13 @@ "20" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.8 nozzle.json index 2c38bb2fd7..9f165d9c76 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S 0.8 nozzle.json @@ -21,9 +21,11 @@ "20" ], "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S.json index 1fc3f03964..43787a6732 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2S.json @@ -21,9 +21,13 @@ "20" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1P 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1P 0.4 nozzle.json index c50087e617..67cb2723cf 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1P 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1P 0.4 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1S 0.4 nozzle.json index 782a19a045..00fdfaf9d2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P1S 0.4 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.2 nozzle.json index 7160dd0f0d..eef6358ed2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG02_17", "instantiation": "true", "additional_cooling_fan_speed": [ + "40", "40" ], "counter_coef_2": [ @@ -24,9 +25,11 @@ "20" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.4 nozzle.json index 4ff218f195..2fa9117a78 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.4 nozzle.json @@ -21,9 +21,13 @@ "20" ], "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.6 nozzle.json index 10b8b449d7..ad0d25672c 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.6 nozzle.json @@ -21,9 +21,13 @@ "20" ], "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.8 nozzle.json index f214212555..6a519754da 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL P2S 0.8 nozzle.json @@ -21,9 +21,11 @@ "20" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.2 nozzle.json index 52cf7e42be..11baeedb6e 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.2 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.6 nozzle.json index 5461db84fe..d9f680dd17 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.6 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.8 nozzle.json index e0df40dfcc..29c4ed85e3 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C 0.8 nozzle.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C.json index 38d2d0a11b..cf3d77288c 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X1C.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.2 nozzle.json index 20e69622e7..9666dae7d0 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.2 nozzle.json @@ -21,9 +21,15 @@ "20" ], "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.4 nozzle.json index 81ffc9bf01..2b5576971e 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.4 nozzle.json @@ -21,9 +21,19 @@ "20" ], "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.8 nozzle.json index 6db5064f92..af398088dc 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D 0.8 nozzle.json @@ -21,9 +21,15 @@ "20" ], "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D.json index 84f2ede658..0b5bcd8fa4 100644 --- a/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL X2D.json @@ -21,9 +21,19 @@ "20" ], "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.2 nozzle.json index 11e340a26f..a9159c0e51 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_10", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.4 nozzle.json index 1feb3bc3d1..33fffd64a6 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_11", "instantiation": "true", "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.8 nozzle.json index 57ada86690..ed24e8c0f2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_12", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C.json index c848448b3b..e4987f9444 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSG03_13", "instantiation": "true", "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.2 nozzle.json index a50efe69d3..48de52a8ee 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_14", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.4 nozzle.json index 037dbb39fc..2c637e48aa 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_15", "instantiation": "true", "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.6 nozzle.json index a60362042d..0339fb0505 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSG03_16", "instantiation": "true", "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.8 nozzle.json index 003c19bb28..2fea9bb488 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_17", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.2 nozzle.json index 8ba7e1fd4e..f28b6e63da 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_18", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.4 nozzle.json index 201b082b3f..19dee4f9c7 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_19", "instantiation": "true", "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.6 nozzle.json index 292a5d108e..264ba6b25b 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSG03_20", "instantiation": "true", "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.8 nozzle.json index 085e159b28..7779e219c1 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_21", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.2 nozzle.json index ca2e8219fa..99d5279359 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_22", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.6 nozzle.json index 052d7c8068..a5ab2326bc 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.6 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_23", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.8 nozzle.json index 3346abab97..8bf7065e8c 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_24", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S.json index 0f95f15edd..c3716d514d 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL H2S.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_25", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.2 nozzle.json index 4f6e6b260a..2d35e4fb91 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.2 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_49", "instantiation": "true", "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "20", "20" ], "filament_density": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.4 nozzle.json index 793997445f..7d20fb5b1f 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.4 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_50", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_density": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.6 nozzle.json index 6c379dd43d..abf497bc62 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P1P 0.6 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_51", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_density": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.2 nozzle.json index 8f17112e84..a743638555 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.2 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_38", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.4 nozzle.json index 252bc6f136..03eae4d6d3 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.4 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_39", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.6 nozzle.json index 4297e9278c..913a646355 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.6 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG03_40", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.8 nozzle.json index df51c24fd2..1d3e65ee6f 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL P2S 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_41", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.2 nozzle.json index 31a5b61e21..b878af8540 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.2 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_42", "instantiation": "true", "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "20", "20" ], "filament_density": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.8 nozzle.json index 23db5e43c6..42bda23e2f 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG03_43", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_density": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C.json index e56d030427..7d4ede9cae 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSG03_44", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_density": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.2 nozzle.json index 0e56e63a37..3cb97fc7e5 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.2 nozzle.json @@ -6,9 +6,15 @@ "setting_id": "GFSG03_45", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.4 nozzle.json index a95be25e66..083cf77ded 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.4 nozzle.json @@ -6,9 +6,19 @@ "setting_id": "GFSG03_46", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.8 nozzle.json index 9b9fa384c8..d9f44afcf5 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D 0.8 nozzle.json @@ -6,9 +6,15 @@ "setting_id": "GFSG03_47", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D.json index 8e90a43b96..9343f1265f 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PETG Matte @BBL X2D.json @@ -6,9 +6,19 @@ "setting_id": "GFSG03_48", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.8 nozzle.json index 75ac270250..1caa272343 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG01_40", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json index 73e0247e95..7942bf46f5 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json @@ -6,9 +6,13 @@ "setting_id": "GFSG01_23", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.6 nozzle.json index 0c2c4df008..adadc5b30d 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.6 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG01_11", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.8 nozzle.json index 66e2bbd006..b7532312a2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2D 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG01_41", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json index 236296a6ce..d31ac20557 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.6 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG01_17", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.8 nozzle.json index fc0bf555ea..5f9c5dc247 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2DP 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG01_42", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.2 nozzle.json index af938e3c2b..7415dbb6f7 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.2 nozzle.json @@ -6,12 +6,15 @@ "setting_id": "GFSG01_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "20", "20" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.6 nozzle.json index 27b5f3a1fd..81620208c5 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.6 nozzle.json @@ -6,9 +6,13 @@ "setting_id": "GFSG01_14", "instantiation": "true", "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.8 nozzle.json index cfbc2d52a7..eb44d5da56 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL P2S 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG01_43", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X1C 0.8 nozzle.json index 3ec40f01c5..68bf87dc3a 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X1C 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSG01_01", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.2 nozzle.json index 5d5cb6d173..47b3c851e3 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.2 nozzle.json @@ -6,12 +6,21 @@ "setting_id": "GFSG01_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "20", + "20", + "20", "20" ], "fan_max_speed": [ + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "20", + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.4 nozzle.json index 974b3528d6..212b9f5036 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.4 nozzle.json @@ -6,12 +6,27 @@ "setting_id": "GFSG01_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "10", + "10", + "10", + "10", + "10", "10" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "20", + "20", + "20", + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.8 nozzle.json index 4281c834f7..3f67d59a15 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D 0.8 nozzle.json @@ -6,9 +6,15 @@ "setting_id": "GFSG01_29", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D.json index aca3950f6e..eda8949e91 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL X2D.json @@ -6,9 +6,19 @@ "setting_id": "GFSG01_20", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "fan_min_speed": [ + "20", + "20", + "20", + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json index 4de1312338..72a1b3bacc 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.8 nozzle.json index f327384244..c85b6dc200 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.8 nozzle.json @@ -21,9 +21,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json index fa1cab99a7..5c0f7497a8 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.4 nozzle.json index cf5ed3198f..161f672a53 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.4 nozzle.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.6 nozzle.json index 347a56d4bf..54feeaf911 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.6 nozzle.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.8 nozzle.json index 4ae2558fb2..a976aa1b55 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2D 0.8 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json index 93bb7ca67d..47056bd31a 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.4 nozzle.json @@ -18,9 +18,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json index 62bc309cfa..90dd4f26cf 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.6 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.8 nozzle.json index 62b7d54979..4b0f63c90c 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2DP 0.8 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.6 nozzle.json index 236fa4d02d..ed7f2ee8c7 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.6 nozzle.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.8 nozzle.json index c9ce999176..cd56208ee1 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S 0.8 nozzle.json @@ -21,9 +21,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S.json index f85e5e820c..5e6d734d53 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2S.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.4 nozzle.json index f7987b06fe..731a8539c2 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.4 nozzle.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.6 nozzle.json index 3958df13ad..b6d7bcd845 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.6 nozzle.json @@ -21,9 +21,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.8 nozzle.json index 7239839b3d..80bd8b59d6 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL P2S 0.8 nozzle.json @@ -21,9 +21,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C 0.4 nozzle.json index c136712f57..0d405a8ea8 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C 0.4 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C.json index e953110fe0..6e926af484 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X1C.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.4 nozzle.json index 24b3775fd5..59de3f7aeb 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.4 nozzle.json @@ -21,9 +21,19 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.8 nozzle.json index 378ad209c9..fe7a25ebe5 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D 0.8 nozzle.json @@ -21,9 +21,15 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D.json index f6e03276e0..b9bcb45fb4 100644 --- a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL X2D.json @@ -21,9 +21,19 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json index ed720d6732..ad7ecb17d9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA11_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json index 0d5865af10..f89fdd8bcb 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA11_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2D.json index 43a47a4722..5b6a9e0f5d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA11_05", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json index 4f30395743..71c62a47b2 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSA11_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2S.json index 3a651c0105..d77572787e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA11_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL P2S.json index f2ea01ad72..56ac92382a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA11_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1.json index 9e5ac03bf3..9a42cebace 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1.json @@ -6,6 +6,7 @@ "setting_id": "GFSA11_00", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", "0" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1C.json index 9fe7a958e1..9e7e06ad66 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSA11_01", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", "0" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D 0.4 nozzle.json index 40f718ed86..dbd40cffc8 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D 0.4 nozzle.json @@ -6,6 +6,11 @@ "setting_id": "GFSA11_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", + "0", + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D.json index d3472e210f..4c08f1619f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL X2D.json @@ -6,6 +6,11 @@ "setting_id": "GFSA11_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", + "0", + "0", + "0", "0" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json index 07ee98f7e6..1466508a02 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json index 63a6a766b0..1905ccf9c0 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA00_31", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json index a8f668860c..ea9d7d781f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_32", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json index fb7e781c55..025c7658c3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA00_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.2 nozzle.json index 53dfefb6b8..97bdac45bb 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_13", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.6 nozzle.json index b201c04ae8..a39249eeb1 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA00_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.8 nozzle.json index 155afbbc68..bcd8e2994d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D.json index 0cb3530b9c..9f3286c359 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA00_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json index 9c49c6d367..07baeac758 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_18", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json index 2efcf62609..8328a49d6f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_28", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -24,9 +25,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json index ded3b4e3d9..b44ce50908 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json index 6df1b590b0..364a6dc643 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_17", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -24,9 +25,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.2 nozzle.json index a26fae8231..25ea7ee5db 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,6 +28,7 @@ "55" ], "fan_min_speed": [ + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.6 nozzle.json index 5e8717b0fc..253b994f0d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA00_30", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,6 +29,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.8 nozzle.json index fcfed64523..c1f368c66a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA00_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,6 +28,7 @@ "55" ], "fan_min_speed": [ + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S.json index 2b26b5a33b..fd525c42ca 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA00_05", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,6 +29,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json index 31708faa3f..8936eee190 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA13_25", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json index 203111f93d..e688214030 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA13_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json index d6ae035131..42a99c95bb 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA13_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S 0.2 nozzle.json index 2e4df09afb..58caf94a5d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA13_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "55" ], "fan_min_speed": [ + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S.json index 6bd6a008d5..7dc39f15c6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA13_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.2 nozzle.json index 92b19310cb..5e8b2724c3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.6 nozzle.json index 6f4d0fdbdc..a09807cbf2 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P.json index 8dd853022d..3cbae45547 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json index d7d9738881..90a2d75d36 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA15_25", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json index 5fdb9b941f..98fe16b9e3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA15_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json index 3c4a3181fd..8152a27d3f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA15_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S 0.2 nozzle.json index c9beecd89c..d8ed6ca17b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA15_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "55" ], "fan_min_speed": [ + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S.json index 91d24f8332..eceb331c7f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA15_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.2 nozzle.json index 7aa84eccd3..8967431e24 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.6 nozzle.json index b5d4190792..4f33e1c9ba 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P.json index 2c0bd7a5fe..949d6bdc40 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S 0.2 nozzle.json index 049e3ad804..d1773e3953 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA15_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S.json index 52fe7324be..5a5f0e4688 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA15_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json index f0601b5374..018bcd48fe 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA12_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json index 7130e8e127..63cf2055ac 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA12_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2S.json index 4530262350..4b9feb7ea3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2S.json @@ -7,6 +7,8 @@ "setting_id": "GFSA12_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -16,6 +18,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P 0.6 nozzle.json index 930f3a2160..0776e594b0 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P.json index 0d37c339c1..cd60db4f0a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S 0.2 nozzle.json index 1ac8c17a57..264f9ac893 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA12_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S.json index 43a636a896..d2cd72ccba 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA12_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json index 938f70ef5f..f3c08d0276 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_17", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json index a435869e4d..e47f6b0cfa 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA18_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.8 nozzle.json index b10f90036d..c43ee9c55d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_44", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json index a30e801edd..e0423ed4f4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA18_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.2 nozzle.json index fcd3c66c1c..04084d28de 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.6 nozzle.json index fbb2fb9994..5ab62e7c67 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA18_45", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.8 nozzle.json index fb7b165418..b64c4716c8 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D.json index f7bcb1ad8f..fa4dd81219 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA18_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json index 3844c578ee..d35ffc498e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_30", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json index e2aea610ee..90df178b13 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.4 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json index 758129964a..b896b19979 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_28", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json index 924d3416d2..58bb62979a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.2 nozzle.json index c28b9c1e67..29f52784ee 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.6 nozzle.json index e1580f9a56..0a63f0b344 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA18_46", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.8 nozzle.json index a1435c6c6f..553ed9ea7e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA18_47", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S.json index da3587b191..834a9456f6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA18_18", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.2 nozzle.json index 897af5a38f..6c11a968f3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.6 nozzle.json index a270dea0ab..a85ef0d269 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P.json index e7a9400504..d1eaa7e721 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json index 1cdc32a534..3d1e35961b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA07_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json index 6840297c89..b20ddba103 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA07_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2S.json index 077bbab752..bb34a9a0b7 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA07_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json index 8b970d07f2..52ba7791f1 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,6 +28,7 @@ "55" ], "fan_min_speed": [ + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json index 7ff6555cec..861d01de6c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_31", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,6 +29,8 @@ "55" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json index 9bcd43edb4..0b325ba2e6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_32", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,6 +28,7 @@ "55" ], "fan_min_speed": [ + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json index 06643057f8..ace8143221 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,6 +29,8 @@ "55" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.2 nozzle.json index b190108aed..b432c42994 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_13", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.6 nozzle.json index be51abe9d3..bed53a5d5f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.8 nozzle.json index 3ada24f209..07f10c4332 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D.json index 2a0b55932e..c78634c8a8 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_05", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ @@ -27,9 +29,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json index f69cf85eca..41eb682f5a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_18", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json index 477bf3492a..e213adcb5b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_28", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json index 85a1fbcf4f..cec1466727 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json index 08a123c6c4..ba91002588 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_17", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.2 nozzle.json index eeea4e7a78..131148ccae 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.6 nozzle.json index 6c611715da..390537664d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_30", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.8 nozzle.json index 0c38e3d228..309723835c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S.json index f794e7e0f5..fcfee24f76 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.2 nozzle.json index 7af0bca0ae..e7eaf4e62f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.6 nozzle.json index 8845412d00..62ddb12047 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_26", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.8 nozzle.json index 369c15e2cd..0a04e30c0f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA01_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S.json index 85051a2210..079b580168 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA01_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json index d500051bb1..ee08893a69 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA02_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json index 75b221dcd3..6d9f35a444 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA02_20", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json index 1ec6730b1a..a061873ce1 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA02_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S 0.2 nozzle.json index e437ccd9f9..535253427f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA02_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S.json index 9c5648425d..b09fb08051 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA02_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.2 nozzle.json index d178683ef1..7c878d42bc 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA02_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.6 nozzle.json index 7c26b3e980..37e8e36af1 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA02_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.8 nozzle.json index 8211ae0b54..e875278247 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA02_25", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json index 2fce1d0a33..5a3bbcbc90 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.6 nozzle.json index 54866db466..ff6d82be48 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA19_42", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.8 nozzle.json index 88ab702e3e..bfd283ae88 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_43", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json index 8a01b018c3..cc7b2051af 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA19_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json index e30e6203b4..0071b46427 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.6 nozzle.json index 8126977f4b..b6c9a22b07 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA19_44", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json index aa981c5177..7a0e25ccb4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json index 002589887f..9f7d65ea19 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA19_13", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json index 27c1be9d5f..c78968507b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.6 nozzle.json index 66a86f93ae..88074952fe 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_45", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json index dc62f9cecc..f3cf3e9800 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json index 516cb30a90..d019971078 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json index 1206f03c01..25266ec00f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_17", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.6 nozzle.json index 9a14fb210c..8f69445623 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.6 nozzle.json @@ -7,6 +7,8 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.8 nozzle.json index a780734dc8..23d1564a08 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.8 nozzle.json @@ -7,6 +7,7 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json index a3ce5df6ea..71d49c9453 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json @@ -7,6 +7,8 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.2 nozzle.json index 9c77055180..eae13723b6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "60", "60" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.8 nozzle.json index 18d8fd4a8a..b2bc0cb4f6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P 0.8 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "60", "60" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P.json index ff2ff52185..f4147158b6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "60", "60" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.2 nozzle.json index 053c0cc82a..f81a615252 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_26", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.4 nozzle.json index cf2c8c5584..37529fde6f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.4 nozzle.json @@ -7,6 +7,8 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.6 nozzle.json index 081ae17a81..0c7542dc06 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA19_28", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.8 nozzle.json index 51b2957e47..d727ad3f43 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA19_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.2 nozzle.json index 32120fd0c8..b945c2ed24 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.2 nozzle.json @@ -6,6 +6,9 @@ "setting_id": "GFSA19_33", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.4 nozzle.json index b6079ea5d2..b37d3bbdd3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.4 nozzle.json @@ -7,6 +7,11 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", + "75", + "75", + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.6 nozzle.json index 358b0ff624..dc8a1569ab 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.6 nozzle.json @@ -6,6 +6,11 @@ "setting_id": "GFSA19_35", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", + "75", + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.8 nozzle.json index 73a363cfab..5eb09d1b12 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL X2D 0.8 nozzle.json @@ -6,6 +6,9 @@ "setting_id": "GFSA19_36", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json index 5f6ac11da9..082074f8be 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json index d738fa5afd..2ea73c7c6e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA05_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json index e690d6b168..81ba2dbba1 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA05_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D 0.2 nozzle.json index c14f4c2f2b..b33bf9d81e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D.json index 991a51de13..7fc75dc921 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA05_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json index 7a619beb01..2642126fd7 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_18", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json index 3a26b9d69e..b0795534f7 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S 0.2 nozzle.json index ad5e9778c7..6f32b716f0 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S.json index 6221528724..3b3737d286 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA05_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.2 nozzle.json index 3600a41bbb..caafdde46c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.6 nozzle.json index 71b9f5522b..207d52231d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA05_26", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.8 nozzle.json index 95374a8d59..3ab3db3646 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA05_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S.json index a650da3329..bcd959725c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA05_17", "instantiation": "true", "additional_cooling_fan_speed": [ + "80", + "80", "80" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json index 6d0f939e60..36f37b26ef 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_20", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json index 40b37f32b9..ee9d9b4098 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_18", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.8 nozzle.json index 4d460cde49..f51d644ad9 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_40", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json index e3a787b51c..8da4bf0b6b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.2 nozzle.json index 80791f03c7..45d7f7b13c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.6 nozzle.json index 8c97969bf2..b6deafebea 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_41", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.8 nozzle.json index f8508cd0f9..e9a49ec749 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_42", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D.json index a1e9d5a6a9..25af3f5fa5 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json index 6ef42bcf5f..fa1a9ebcdc 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.6 nozzle.json index acb22ba23a..fe2e4f047a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_43", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.8 nozzle.json index a4b9e799a4..ff86fe004f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_44", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json index cba3b52ae0..a56401ff23 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_13", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.2 nozzle.json index b1bf42971c..756829d4df 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.6 nozzle.json index 8868530a19..abdd991834 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_45", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.8 nozzle.json index 7e3270c32a..af15bde51b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_46", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S.json index 7d143d2360..9543ecc828 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S 0.2 nozzle.json index 05f3286f11..fee682b69f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA06_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S.json index 027b694a64..4bc7d8b4e6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA06_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "80", + "80", "80" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json index d635be71a7..85141b91ff 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA08_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json index 59f9880889..5223c79445 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA08_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2S.json index 53ce3da06c..01582d9f28 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA08_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL P2S 0.6 nozzle.json index 8368e4c558..3696f420aa 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA08_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json index afc18f86e9..3d77b54d7f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA09_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json index 395e917d6d..1d4ad13d8b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA09_20", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json index 687135999b..20c96446c3 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA09_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S 0.2 nozzle.json index 935d868854..0a3f3ac5a4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA09_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "55" ], "fan_min_speed": [ + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S.json index 0f202955c9..3fb79ac36b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA09_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL X1.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL X1.json index 80e7689736..ed66381b35 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL X1.json +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL X1.json @@ -6,12 +6,14 @@ "setting_id": "GFSA10_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "70", "70" ], "fan_cooling_layer_time": [ "80" ], "fan_min_speed": [ + "90", "90" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json index 743a5d09aa..160791f8fe 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA17_30", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -65,6 +66,7 @@ "fdm_filament_template_direct_dual" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.6 nozzle.json index bf8d33de15..55f6e27d6a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA17_43", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -115,6 +117,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "pre_start_fan_time": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.8 nozzle.json index 7c19dbe1a7..406cabd416 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA17_44", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -101,6 +102,7 @@ "220" ], "nozzle_temperature_range_low": [ + "200", "200" ], "pre_start_fan_time": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json index 6a059d251b..d2de2598db 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA17_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -103,6 +105,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "pre_start_fan_time": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2D 0.6 nozzle.json index 595316f8b8..d9be5d6c45 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2D 0.6 nozzle.json @@ -82,6 +82,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "slow_down_min_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.6 nozzle.json index d4e2e52372..23c3a5de4a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2DP 0.6 nozzle.json @@ -73,6 +73,7 @@ "220" ], "nozzle_temperature_range_low": [ + "200", "200" ], "slow_down_min_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.2 nozzle.json index 8ee80929b7..1bbe592a2d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA17_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -48,6 +49,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.6 nozzle.json index 264712fbc9..7d82407ece 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.6 nozzle.json @@ -7,6 +7,8 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -86,6 +88,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "pre_start_fan_time": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.8 nozzle.json index 398d122abe..3091014ddf 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S 0.8 nozzle.json @@ -7,6 +7,7 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -75,6 +76,7 @@ "220" ], "nozzle_temperature_range_low": [ + "200", "200" ], "pre_start_fan_time": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S.json index 5a1f621995..f041cc80c5 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2S.json @@ -7,6 +7,8 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -80,6 +82,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "pre_start_fan_time": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.2 nozzle.json index 00bc9dac11..72d39255e4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ @@ -41,6 +42,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.8 nozzle.json index 670d60514e..a79b0e1316 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P 0.8 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ @@ -41,6 +42,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P.json index 7ae191d7af..a6017bd39d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ @@ -41,6 +42,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.2 nozzle.json index f4d864f29e..5fee15f5e0 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSA17_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -66,6 +67,7 @@ "240" ], "nozzle_temperature_range_low": [ + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.4 nozzle.json index c09cce8eaf..a5902e29e6 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.4 nozzle.json @@ -7,6 +7,8 @@ "instantiation": "true", "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -59,6 +61,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.6 nozzle.json index 2725f38791..d49dceff5e 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA17_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -68,6 +70,8 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.8 nozzle.json index fda701016e..0099579353 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL P2S 0.8 nozzle.json @@ -51,6 +51,7 @@ "220" ], "nozzle_temperature_range_low": [ + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.2 nozzle.json index 56c2cb1916..749eb63e59 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.2 nozzle.json @@ -29,6 +29,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.8 nozzle.json index 41f54caeb0..bcb3002712 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C 0.8 nozzle.json @@ -29,6 +29,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C.json index cfe114c228..cb52e670ff 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X1C.json @@ -30,6 +30,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.2 nozzle.json index 9ff9f3c7c9..f6b9163be8 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.2 nozzle.json @@ -108,6 +108,9 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.4 nozzle.json index 8fbd944596..828f755d23 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.4 nozzle.json @@ -115,6 +115,11 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", + "200", + "200", + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.6 nozzle.json index 2efa9652d0..6219086298 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.6 nozzle.json @@ -114,6 +114,11 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", + "200", + "200", + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.8 nozzle.json index e8bba0ada4..27f1d0ada2 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL X2D 0.8 nozzle.json @@ -90,6 +90,9 @@ "220" ], "nozzle_temperature_range_low": [ + "200", + "200", + "200", "200" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json index 2165790d3a..88e688db95 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSA16_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json index 1d718aa068..715c72353f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSA16_15", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2S.json index 8d45019fdd..746c38b10d 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSA16_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "55" ], "fan_min_speed": [ + "80", + "80", "80" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P 0.6 nozzle.json index abb60dfc31..8dcd364d90 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P.json index 16208882d0..4d8785a24c 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL P2S.json index fca2ea793b..3a8b52097d 100644 --- a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSN06_03", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ @@ -24,9 +26,13 @@ "-0.0075" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PVA @BBL P1P 0.2 nozzle.json index 597e2d83ba..76ebb00b63 100644 --- a/resources/profiles/BBL/filament/Bambu PVA @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL P1P.json b/resources/profiles/BBL/filament/Bambu PVA @BBL P1P.json index 4c98d516d1..1167c54593 100644 --- a/resources/profiles/BBL/filament/Bambu PVA @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL P2S.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL P2S.json index 21492b5673..d8a299efd2 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSS03_04", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json index 50022ade4b..afa2910113 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json index c8b6e555c3..46e55e63ba 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json @@ -12,9 +12,13 @@ "55" ], "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.8 nozzle.json index 6186fbbfb1..7e9e769bec 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.8 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json index ccdcb88f8b..0300745302 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json @@ -12,9 +12,13 @@ "55" ], "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.2 nozzle.json index 9ffdfdde10..2701b25584 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.2 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.6 nozzle.json index 0157469f7b..9a66fa6176 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.6 nozzle.json @@ -12,9 +12,13 @@ "55" ], "fan_max_speed": [ + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.8 nozzle.json index 18f993668b..4eda30ff3e 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D 0.8 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D.json index 224744fbe2..6a0624836e 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2D.json @@ -12,9 +12,13 @@ "55" ], "fan_max_speed": [ + "15", + "15", "15" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json index 6d3d64f4e4..5970e18cdf 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.2 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.6 nozzle.json index 96927d4949..d24ff505b5 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.6 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.8 nozzle.json index 1790f3dc7e..5584bbb12d 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP 0.8 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json index ddf96b9502..6c61a92acc 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2DP.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.2 nozzle.json index c3bc4b262f..112de8a48e 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSS02_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.6 nozzle.json index e1a5cabe18..f6f0016403 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSS02_39", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +17,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.8 nozzle.json index 3c6c49d850..71e743880c 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSS02_40", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S.json index 9a65ce122d..9ff211ad6f 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSS02_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +17,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL P2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL P2S 0.2 nozzle.json index 67d1b7513c..2b7667a143 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL P2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL P2S 0.2 nozzle.json @@ -12,9 +12,11 @@ "55" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL X2D 0.4 nozzle.json index f6241c25d3..3dddf75456 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL X2D 0.4 nozzle.json @@ -12,9 +12,19 @@ "55" ], "fan_max_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "fan_min_speed": [ + "20", + "20", + "20", + "20", + "20", "20" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2D.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2D.json index 658e24aee0..2af3930c39 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2D.json @@ -12,9 +12,13 @@ "60" ], "fan_max_speed": [ + "15", + "15", "15" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2S 0.2 nozzle.json index 0c9ad96894..312df41753 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSS00_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2S.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2S.json index e1bb915584..2a9ca56c04 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSS00_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ @@ -15,9 +17,13 @@ "55" ], "fan_max_speed": [ + "80", + "80", "80" ], "fan_min_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.6 nozzle.json index efa5fbedf2..1f48d62041 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSS06_21", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.8 nozzle.json index d0ebd6307d..95161a1a3e 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSS06_22", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S.json index 67492a22da..bc11aaa193 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSS06_03", "instantiation": "true", "activate_air_filtration": [ + "0", + "0", "0" ], "chamber_temperatures": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json index 50da178634..ec735c5deb 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU04_05", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -115,6 +117,8 @@ "fdm_filament_template_direct_dual_e3d" ], "nozzle_temperature_range_high": [ + "250", + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json index a1c364a9ec..b0f686e2b3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json @@ -6,6 +6,9 @@ "setting_id": "GFSU04_02", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", + "100", "100" ], "eng_plate_temp": [ @@ -252,6 +255,9 @@ "225" ], "nozzle_temperature_range_high": [ + "250", + "250", + "250", "250" ], "override_process_overhang_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json index 5afdd55df6..de3bccb27b 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json @@ -6,6 +6,8 @@ "setting_id": "GFSU04_03", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -214,6 +216,8 @@ "235" ], "nozzle_temperature_range_high": [ + "250", + "250", "250" ], "override_process_overhang_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.6 nozzle.json index 493fb2004d..c3766b23b3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU04_8", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.8 nozzle.json index b39cbdfe34..9585ab1101 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU04_9", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S.json index 32401c7021..403197ee60 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU04_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json index 9a41e06a29..9e63a28406 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -112,6 +114,8 @@ "fdm_filament_template_direct_dual_e3d" ], "nozzle_temperature_range_high": [ + "250", + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json index 28f6778d20..2191881728 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -112,6 +114,8 @@ "fdm_filament_template_direct_dual_e3d" ], "nozzle_temperature_range_high": [ + "250", + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json index feb9db8a13..dacefeec95 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json @@ -6,6 +6,9 @@ "setting_id": "GFSU03_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", + "100", "100" ], "eng_plate_temp": [ @@ -240,6 +243,9 @@ "1" ], "nozzle_temperature_range_high": [ + "250", + "250", + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json index b1a45e6d9a..6615572218 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU03_26", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -72,6 +73,7 @@ "220" ], "nozzle_temperature_range_high": [ + "250", "250" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json index f2d39bc05c..24ca1c2dca 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json @@ -6,6 +6,9 @@ "setting_id": "GFSU03_02", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", + "100", "100" ], "eng_plate_temp": [ @@ -252,6 +255,9 @@ "225" ], "nozzle_temperature_range_high": [ + "250", + "250", + "250", "250" ], "override_process_overhang_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json index cb24fbdbdd..261a5ccf41 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_25", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -214,6 +216,8 @@ "220" ], "nozzle_temperature_range_high": [ + "250", + "250", "250" ], "override_process_overhang_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json index 6f8fc61c4e..a131ceacbe 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU03_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -72,6 +73,7 @@ "220" ], "nozzle_temperature_range_high": [ + "250", "250" ], "retraction_distances_when_ec": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json index a77efbc6d7..02871a3337 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_03", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -214,6 +216,8 @@ "225" ], "nozzle_temperature_range_high": [ + "250", + "250", "250" ], "override_process_overhang_speed": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.6 nozzle.json index c56c11ff05..b365a9a185 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_13", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.8 nozzle.json index d6358536a6..7dc1555cb3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU03_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S.json index 0cae43b7ab..132086eef3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S 0.6 nozzle.json index b294fbacc4..6a2f08a138 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_16", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S.json index 1942641481..89648b3efe 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU03_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json index bbd0dbc809..8c480a2ff2 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU01_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json index 20331454b3..54023d7e7d 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU01_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json index fa3cb556e2..88c16df8f3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json @@ -6,6 +6,9 @@ "setting_id": "GFSU01_03", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json index b2c79b2b94..487b31709b 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json @@ -6,6 +6,8 @@ "setting_id": "GFSU01_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2S.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2S.json index af483d6b70..6ae911cb74 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU01_04", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json index e482736c0e..e37518a172 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_13", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.8 nozzle.json index d2368268d3..081cfb90a3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU00_26", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json index 52fdb8633b..1ec5931109 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_14", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.8 nozzle.json index 04662c4e58..3ce09e805e 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU00_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json index e4333a1576..08f1fda6f3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json @@ -6,6 +6,9 @@ "setting_id": "GFSU00_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.8 nozzle.json index 68762079c0..a3eab351a5 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU00_28", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json index d0b0b6191f..a3eb1be1c1 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.6 nozzle.json index c9afffaaf8..6f26afb875 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.8 nozzle.json index bbe70e2225..e1f6f3ceab 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU00_30", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S.json index 82964bc87a..0f81463bfc 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.6 nozzle.json index 949d9c0906..d7a54596c3 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_31", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.8 nozzle.json index a2665f6707..a55b3fbcdb 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU00_32", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S.json index ab6761cea9..40799c1dd6 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU00_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json index 73f4e42208..f8a39ec2e4 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "35" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.8 nozzle.json index 0e54a2e1d5..77446cdc1a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_25", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "35" ], "fan_max_speed": [ + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json index 74253e1452..c3f47d4ffd 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "35" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.6 nozzle.json index 24405af162..4136556b4f 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_26", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "35" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.8 nozzle.json index cc9f65412d..0fa63dbfce 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_27", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "35" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D.json index 22d29a0b08..29e9cbbf73 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_04", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "35" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.6 nozzle.json index 728ec60720..66a4403a4d 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_28", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "35" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.8 nozzle.json index 405b96caa6..bc564266ef 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_29", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "35" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json index 641c6bd8b2..14173055e1 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "35" ], "fan_max_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.6 nozzle.json index 3791a37dfb..5d958d75df 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_24", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "35" ], "fan_max_speed": [ + "40", + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.8 nozzle.json index 785f6512f1..22d4b92b7a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_23", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +16,7 @@ "35" ], "fan_max_speed": [ + "40", "40" ], "filament_change_length": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S.json index 195742bdb0..525f771285 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,6 +17,8 @@ "35" ], "fan_max_speed": [ + "60", + "60", "60" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P 0.6 nozzle.json index bf9b7554f8..dde9ae028a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_16", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P.json index 80d40378a7..fa0005a6f0 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P1P.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_01", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_retraction_length": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.6 nozzle.json index 4f2c364ef4..0e11fa482f 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.6 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_30", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,9 +17,13 @@ "35" ], "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.8 nozzle.json index fe6a92f21c..d5249e0707 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S 0.8 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_31", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -15,9 +16,11 @@ "35" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S.json index bf1249ebcb..437fd35001 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL P2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU02_05", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -15,9 +17,13 @@ "35" ], "fan_max_speed": [ + "60", + "60", "60" ], "fan_min_speed": [ + "30", + "30", "30" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C 0.6 nozzle.json index f7e164fe81..caef461097 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_13", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C.json index 45b784e741..42271bba10 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSU02_00", "instantiation": "true", "fan_max_speed": [ + "40", "40" ], "filament_retraction_length": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.4 nozzle.json index 696a79e84a..99183ac320 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.4 nozzle.json @@ -12,6 +12,11 @@ "35" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.8 nozzle.json index 116476ceeb..100cfb14bc 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D 0.8 nozzle.json @@ -12,6 +12,9 @@ "35" ], "fan_max_speed": [ + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D.json index ee378baeff..02d5532acd 100644 --- a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL X2D.json @@ -12,6 +12,11 @@ "35" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json index a95f8b7000..8d1a12f356 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json @@ -9,9 +9,11 @@ "60" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2S 0.2 nozzle.json index e412d22e80..b2d460207f 100644 --- a/resources/profiles/BBL/filament/Generic ABS @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2S 0.2 nozzle.json @@ -9,9 +9,11 @@ "60" ], "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "40", "40" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json index e2dc6c43da..609200aaf7 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json @@ -9,9 +9,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json index fffb6a6e49..a8d158bf12 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json @@ -9,9 +9,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2D.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2D.json index 063d30a279..627dcf1ea7 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2D.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2D.json @@ -9,9 +9,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json index d0e4ff8752..4e15261404 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2DP.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2S.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2S.json index 585f656ab1..123c23d5d7 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2S.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2S.json @@ -9,9 +9,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL P2S.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL P2S.json index e1944cca5d..eaf44c29a4 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL P2S.json @@ -9,9 +9,13 @@ "30" ], "fan_max_speed": [ + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL X1C.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL X1C.json index 46dda5c26d..fe45f29947 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL X1C.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D 0.4 nozzle.json index 73db99b2ce..f21d59a9ca 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D 0.4 nozzle.json @@ -9,9 +9,19 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D.json index 2309a91389..59f4b1c1f1 100644 --- a/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D.json +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL X2D.json @@ -9,9 +9,19 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json index 634dc781c4..0109d97d23 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL99_22", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json index 9489ef729a..6d00ddb005 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSL99_20", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json index 334c18e36c..18fbaaa915 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSL99_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2S 0.2 nozzle.json index c04a5a7f1d..b5ab0c7b0e 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL99_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2S.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2S.json index d43e487d30..b02c02007f 100644 --- a/resources/profiles/BBL/filament/Generic PLA @BBL H2S.json +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL99_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json index 736f9d5b73..58b1f98c68 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL95_21", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json index 1978b96cf3..491d03de56 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSL95_19", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json index e7083107ef..762249175f 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSL95_20", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S 0.2 nozzle.json index 23633f4ce4..ae178912f4 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL95_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S.json index 97706a18ab..42372243fc 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL95_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json index 9c36600779..7d40128b9b 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json index c48a46337c..e4c891915d 100644 --- a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSL96_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json index 61201273f0..f3a82bdd05 100644 --- a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSL96_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2S.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2S.json index 100e03b3c9..dae0e857d4 100644 --- a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2S.json +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL96_04", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json index 6307ce8fd1..4d1f2c5c06 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json index 99fbafe181..7fefc47632 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2D.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2D.json index 5798bede95..0e0b947fa0 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2D.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2D.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json index ab2c95d6ec..3a6d182a8b 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2DP.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2S 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2S 0.4 nozzle.json index 1424641376..8f134d6350 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2S 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2S 0.4 nozzle.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL P2S.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL P2S.json index 77b17fb0d8..1ac2b972ff 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL P2S.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL P2S.json @@ -9,6 +9,8 @@ "60" ], "fan_max_speed": [ + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1C.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1C.json index 6b543ecd14..235dc251c6 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "GFSN97_00", "instantiation": "true", "fan_max_speed": [ + "35", "35" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1E.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1E.json index 636204070f..b455fbb083 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1E.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X1E.json @@ -9,6 +9,7 @@ "60" ], "fan_max_speed": [ + "35", "35" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D 0.4 nozzle.json index c171b03fe9..9963bf7c53 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D 0.4 nozzle.json @@ -9,6 +9,11 @@ "60" ], "fan_max_speed": [ + "35", + "35", + "35", + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D.json index 97b164c7a4..f3f53400d6 100644 --- a/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D.json +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL X2D.json @@ -9,6 +9,11 @@ "60" ], "fan_max_speed": [ + "35", + "35", + "35", + "35", + "35", "35" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json index 9dda2e9f85..fe62720d18 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU99_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json index 063f446f6d..818944cfa2 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU99_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json index 1d2e1a447d..b5d28a37e9 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json @@ -6,6 +6,9 @@ "setting_id": "GFSU99_02", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json index 456941431d..2fd9bf50e7 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json @@ -6,6 +6,8 @@ "setting_id": "GFSU99_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2S.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2S.json index be7f778869..aa6a537525 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2S.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU99_04", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json index 7232187281..58cf7270b5 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json @@ -6,6 +6,8 @@ "setting_id": "GFSU98_10", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -18,9 +20,13 @@ "40" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json index 4980e672f8..700c90e567 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json @@ -6,6 +6,8 @@ "setting_id": "GFSU98_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -18,9 +20,13 @@ "40" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2D.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2D.json index 37f4f2ffa4..9eec32f435 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2D.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2D.json @@ -6,6 +6,8 @@ "setting_id": "GFSU98_04", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -18,9 +20,13 @@ "40" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json index 42f65f4680..1e3b9ac042 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2DP.json @@ -6,6 +6,7 @@ "setting_id": "GFSU98_08", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -18,9 +19,11 @@ "40" ], "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2S.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2S.json index 7931394b1f..6cd4066909 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2S.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSU98_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", + "100", "100" ], "eng_plate_temp": [ @@ -18,9 +20,13 @@ "40" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P1P.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P1P.json index 437aadfa54..e93e38f3dd 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P1P.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P1P.json @@ -9,9 +9,11 @@ "40" ], "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "10", "10" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P2S.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P2S.json index 24c8b552fb..cde0a1e7f7 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P2S.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL P2S.json @@ -15,9 +15,13 @@ "40" ], "fan_max_speed": [ + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X1C.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X1C.json index 85b053a0cd..189175d6c1 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X1C.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X1C.json @@ -9,9 +9,11 @@ "40" ], "fan_max_speed": [ + "50", "50" ], "fan_min_speed": [ + "10", "10" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D 0.4 nozzle.json index 446cb91fbb..0e71a2ab70 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D 0.4 nozzle.json @@ -15,9 +15,19 @@ "40" ], "fan_max_speed": [ + "50", + "50", + "50", + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", + "10", + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D.json index 3223336a76..6b7ccfcb34 100644 --- a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D.json +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL X2D.json @@ -15,9 +15,19 @@ "40" ], "fan_max_speed": [ + "50", + "50", + "50", + "50", + "50", "50" ], "fan_min_speed": [ + "10", + "10", + "10", + "10", + "10", "10" ], "filament_cooling_before_tower": [ diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S 0.2 nozzle.json index 5c258fbd47..843ad953e4 100644 --- a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL05_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S.json index eb84bfac73..c2f8591551 100644 --- a/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S.json +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL05_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json index b6747d4d27..0b4c7295e5 100644 --- a/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture PLA @BBL H2S 0.2 nozzle.json index 015bd25840..d810f76495 100644 --- a/resources/profiles/BBL/filament/Overture PLA @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Overture PLA @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL04_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL H2S.json b/resources/profiles/BBL/filament/Overture PLA @BBL H2S.json index e66b7c9405..f65421b43c 100644 --- a/resources/profiles/BBL/filament/Overture PLA @BBL H2S.json +++ b/resources/profiles/BBL/filament/Overture PLA @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL04_11", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json b/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json index c8ad574304..9c24fa069a 100644 --- a/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.2 nozzle.json index dcbd382ffe..d86054d733 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_02", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.6 nozzle.json index ea6060ba15..bd88551b01 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P 0.6 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_41", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P.json index c21004ca75..c667b7bb37 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu ABS @BBL P1P.json @@ -6,6 +6,7 @@ "setting_id": "GFSB00_03", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PA-CF @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PA-CF @BBL P1P.json index b7cfc61878..b4e7c13da7 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PA-CF @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PA-CF @BBL P1P.json @@ -9,9 +9,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.2 nozzle.json index d64fff5af9..d211d9acff 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.2 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.6 nozzle.json index bc23bb1607..4167792881 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P 0.6 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P.json index 0977c4fbb8..0d40c57d7f 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PC @BBL P1P.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PET-CF @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PET-CF @BBL P1P.json index 5095859d67..f31d1108a6 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PET-CF @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PET-CF @BBL P1P.json @@ -9,9 +9,11 @@ "80" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "1", "1" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P 0.4 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P 0.4 nozzle.json index 6f21d17509..1d0a40bbc1 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P 0.4 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P 0.4 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P.json index bf140d0d31..514ff302b6 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PETG-CF @BBL P1P.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Aero @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Aero @BBL P1P.json index 01eb23cd11..eb6c25d774 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Aero @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Aero @BBL P1P.json @@ -6,6 +6,7 @@ "setting_id": "GFSA11_02", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", "0" ], "fan_cooling_layer_time": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.2 nozzle.json index db4088ef94..14ffc1f3af 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.6 nozzle.json index f30ef29c1f..3afb4e04d7 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P.json index eb897cf359..c8d5579415 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Basic @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P 0.6 nozzle.json index 2cbd700b75..98d76749a1 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P.json index 1cc0306b4b..dbdfba324d 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Marble @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.2 nozzle.json index 6dbead6f4d..58d82e9947 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.6 nozzle.json index 6107e5ba72..444a896d66 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P.json index a70c160320..54b746b622 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Matte @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.2 nozzle.json index c33ce2a479..ddab76f59b 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.6 nozzle.json index f0fd865b66..2b4247d4df 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P.json index 9c600caafe..58c8d0f1f6 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Metal @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P 0.6 nozzle.json index eaa8896497..15251bcf61 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P 0.6 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P.json index 240da6d165..1f13647b2f 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Sparkle @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P 0.2 nozzle.json index f99ea5200f..ed776be75b 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P.json index 8a1a0fd274..c50562687f 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.2 nozzle.json index 1a0c12f0ff..f578485c6e 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.2 nozzle.json @@ -6,12 +6,14 @@ "setting_id": "GFSA10_33", "instantiation": "true", "additional_cooling_fan_speed": [ + "70", "70" ], "fan_cooling_layer_time": [ "80" ], "fan_min_speed": [ + "90", "90" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.6 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.6 nozzle.json index c090797121..09fd6e3614 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P 0.6 nozzle.json @@ -6,12 +6,14 @@ "setting_id": "GFSA10_38", "instantiation": "true", "additional_cooling_fan_speed": [ + "70", "70" ], "fan_cooling_layer_time": [ "80" ], "fan_min_speed": [ + "90", "90" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P.json index b4e25f845b..13c6ae6a58 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA Tough+ @BBL P1P.json @@ -6,12 +6,14 @@ "setting_id": "GFSA10_34", "instantiation": "true", "additional_cooling_fan_speed": [ + "70", "70" ], "fan_cooling_layer_time": [ "80" ], "fan_min_speed": [ + "90", "90" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P 0.8 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P 0.8 nozzle.json index dcf38827ce..def3a2b834 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P 0.8 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P.json index 82a84b4d1f..607ad46ade 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu PLA-CF @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P 0.2 nozzle.json index 0a789a6941..3e06730971 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P.json index 3bbd78f489..bed7a8a83f 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu Support For PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P 0.2 nozzle.json index 43c99264b1..34d24468ed 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P.json index ca08dc8ce3..1d0ddf542f 100644 --- a/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Bambu Support W @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P 0.2 nozzle.json index a11c8b406c..b8ba38cc18 100644 --- a/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSB99_02", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P.json index 77f537261e..e2d57d2407 100644 --- a/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Generic ABS @BBL P1P.json @@ -6,6 +6,7 @@ "setting_id": "GFSB99_01", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P 0.2 nozzle.json index 75837ececb..9fac30cbfc 100644 --- a/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P 0.2 nozzle.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P.json index 08086f47f6..df1ea38f65 100644 --- a/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Generic PC @BBL P1P.json @@ -12,6 +12,7 @@ "100" ], "fan_max_speed": [ + "20", "20" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic PETG-CF @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Generic PETG-CF @BBL P1P.json index fc0eb4132b..59049ae30c 100644 --- a/resources/profiles/BBL/filament/P1P/Generic PETG-CF @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Generic PETG-CF @BBL P1P.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P 0.2 nozzle.json index fb08c2ca3c..b4f52cf6e2 100644 --- a/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P.json index 23782d1f63..fefc87018c 100644 --- a/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Generic PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/Generic PVA @BBL P1P.json b/resources/profiles/BBL/filament/P1P/Generic PVA @BBL P1P.json index 55cbed4c0f..32406f8d79 100644 --- a/resources/profiles/BBL/filament/P1P/Generic PVA @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/Generic PVA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P 0.2 nozzle.json index c7e57b79d2..d5d4db0ceb 100644 --- a/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P.json b/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P.json index 9d5f349afb..1bd2bda10c 100644 --- a/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/PolyLite PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P 0.2 nozzle.json index c07ce9f912..608b2c4654 100644 --- a/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P.json b/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P.json index 69b0921119..d9389ab744 100644 --- a/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/PolyTerra PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P 0.2 nozzle.json index 07b2229f3c..1bab33f91d 100644 --- a/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P.json b/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P.json index c035419a13..b4bfa2366f 100644 --- a/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P.json +++ b/resources/profiles/BBL/filament/P1P/eSUN PLA+ @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json index 57d32de9a7..32b64c1349 100644 --- a/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json @@ -6,6 +6,7 @@ "setting_id": "GFSB60_04", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2D.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2D.json index 3e90dda823..ccc0b59c48 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2D.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2D.json @@ -24,6 +24,8 @@ "fdm_filament_template_direct_dual_e3d" ], "nozzle_temperature_range_high": [ + "270", + "270", "270" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json index 24fcafab4f..f8179f7c73 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2DP.json @@ -29,6 +29,7 @@ "255" ], "nozzle_temperature_range_high": [ + "270", "270" ], "slow_down_min_speed": [ diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S 0.2 nozzle.json index 0bdcad3735..d4e4978024 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S 0.2 nozzle.json @@ -33,6 +33,7 @@ "0" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S.json index 912cb9a3ed..58e42dba4e 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL H2S.json @@ -34,6 +34,8 @@ "0" ], "nozzle_temperature_range_high": [ + "270", + "270", "270" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json index 9b0b409cb9..ec05e93824 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json @@ -27,6 +27,7 @@ "0" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json index fb7f801850..a69f499126 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json @@ -21,6 +21,7 @@ "0" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature": [ diff --git a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S 0.2 nozzle.json index bcd5226a9e..f623a98acb 100644 --- a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL00_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S.json b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S.json index 8ff8f89d35..c4d8c7413f 100644 --- a/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S.json +++ b/resources/profiles/BBL/filament/PolyLite PLA @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL00_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S 0.2 nozzle.json index 38d5fec0ca..d966dce73c 100644 --- a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL01_07", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S.json b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S.json index ee6b8e2e36..533c00c5f8 100644 --- a/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S.json +++ b/resources/profiles/BBL/filament/PolyTerra PLA @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL01_06", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU Marble PLA @BBL P1P.json b/resources/profiles/BBL/filament/SUNLU/SUNLU Marble PLA @BBL P1P.json index 0a103c995c..bc6e1338f0 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU Marble PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU Marble PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PETG @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PETG @BBL X1C 0.8 nozzle.json index 99dc78c918..608f860fcc 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PETG @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PETG @BBL X1C 0.8 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GFSNLS08_01", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P 0.2 nozzle.json index 464e056c8c..7150b7078b 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P.json index 6054f5fd07..6fa8309b85 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA Matte @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P 0.2 nozzle.json index f8329334a4..5e6555da12 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P.json index b6bccf5151..ae8bcda763 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ 2.0 @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P 0.2 nozzle.json index 23227067a2..5f46964241 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P.json b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P.json index 092d213cca..c936fed91a 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU PLA+ @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/BBL/filament/SUNLU/SUNLU Wood PLA @BBL P1P.json b/resources/profiles/BBL/filament/SUNLU/SUNLU Wood PLA @BBL P1P.json index ff61f6d3ce..9b7811ef7b 100644 --- a/resources/profiles/BBL/filament/SUNLU/SUNLU Wood PLA @BBL P1P.json +++ b/resources/profiles/BBL/filament/SUNLU/SUNLU Wood PLA @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S 0.2 nozzle.json index eb6e63dd5c..c8d99496b4 100644 --- a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S 0.2 nozzle.json @@ -6,6 +6,7 @@ "setting_id": "GFSL03_12", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S.json b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S.json index 0a60b92b11..770b3ae75f 100644 --- a/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S.json +++ b/resources/profiles/BBL/filament/eSUN PLA+ @BBL H2S.json @@ -6,6 +6,8 @@ "setting_id": "GFSL03_09", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json b/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json index 826648ffde..10776c396d 100644 --- a/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json +++ b/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json @@ -86,7 +86,7 @@ ], "print_extruder_variant": [ "Direct Drive Standard", - "Direct Drive TPU285" + "Direct Drive High Flow" ], "slowdown_end_acc": [ "2000", diff --git a/resources/profiles/BIQU.json b/resources/profiles/BIQU.json index 2dd4115290..1230988a61 100644 --- a/resources/profiles/BIQU.json +++ b/resources/profiles/BIQU.json @@ -1,6 +1,6 @@ { "name": "BIQU", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "0", "description": "BIQU configurations", "machine_model_list": [ diff --git a/resources/profiles/BIQU/machine/BIQU B1 (0.4 nozzle).json b/resources/profiles/BIQU/machine/BIQU B1 (0.4 nozzle).json index 1f98c673e8..40e597b6e2 100644 --- a/resources/profiles/BIQU/machine/BIQU B1 (0.4 nozzle).json +++ b/resources/profiles/BIQU/machine/BIQU B1 (0.4 nozzle).json @@ -24,45 +24,59 @@ ], "gcode_flavor": "marlin", "machine_max_acceleration_e": [ + "10000", "10000" ], "machine_max_acceleration_extruding": [ + "1000", "1000" ], "machine_max_acceleration_retracting": [ + "1000", "1000" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "100", "100" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "10", "10" ], "machine_max_jerk_y": [ + "10", "10" ], "machine_max_jerk_z": [ + "0.3", "0.3" ], "machine_max_junction_deviation": [ diff --git a/resources/profiles/BIQU/machine/BIQU BX (0.4 nozzle).json b/resources/profiles/BIQU/machine/BIQU BX (0.4 nozzle).json index 8acfe76925..ecd11d7c5a 100644 --- a/resources/profiles/BIQU/machine/BIQU BX (0.4 nozzle).json +++ b/resources/profiles/BIQU/machine/BIQU BX (0.4 nozzle).json @@ -24,45 +24,59 @@ ], "gcode_flavor": "marlin", "machine_max_acceleration_e": [ + "10000", "10000" ], "machine_max_acceleration_extruding": [ + "1000", "1000" ], "machine_max_acceleration_retracting": [ + "1000", "1000" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "100", "100" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "10", "10" ], "machine_max_jerk_y": [ + "10", "10" ], "machine_max_jerk_z": [ + "0.3", "0.3" ], "machine_max_junction_deviation": [ diff --git a/resources/profiles/Blocks.json b/resources/profiles/Blocks.json index 4c4936ab28..e4dc6527a7 100644 --- a/resources/profiles/Blocks.json +++ b/resources/profiles/Blocks.json @@ -1,6 +1,6 @@ { "name": "Blocks", - "version": "02.04.00.13", + "version": "02.04.00.14", "force_update": "0", "description": "Blocks configurations", "machine_model_list": [ diff --git a/resources/profiles/Blocks/filament/Blocks ABS @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks ABS @Blocks_RD50_V2.json index 7ce4729e96..5ce6d8bed6 100644 --- a/resources/profiles/Blocks/filament/Blocks ABS @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks ABS @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks ABS @Blocks_RD50_V2", + "renamed_from": "Blocks Generic ABS;Generic ABS @Blocks", "inherits": "Blocks ABS @base", "from": "system", "setting_id": "qhQ0qQDGJgsueCAF", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic ABS;Generic ABS @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks ASA @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks ASA @Blocks_RD50_V2.json index bab020171f..99671f2d3d 100644 --- a/resources/profiles/Blocks/filament/Blocks ASA @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks ASA @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks ASA @Blocks_RD50_V2", + "renamed_from": "Blocks Generic ASA;Generic ASA @Blocks", "inherits": "Blocks ASA @base", "from": "system", "setting_id": "HW7xDXThvpVFbMq5", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic ASA;Generic ASA @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks ASA-CF @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks ASA-CF @Blocks_RD50_V2.json index bdfb288047..83929ad9b2 100644 --- a/resources/profiles/Blocks/filament/Blocks ASA-CF @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks ASA-CF @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks ASA-CF @Blocks_RD50_V2", + "renamed_from": "Blocks Generic ASA-CF;Generic ASA-CF @Blocks", "inherits": "Blocks ASA-CF @base", "from": "system", "setting_id": "x5ksnGLGGy1PgDns", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic ASA-CF;Generic ASA-CF @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PA @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks PA @Blocks_RD50_V2.json index 6486ec0ed8..f3b3e9e2ac 100644 --- a/resources/profiles/Blocks/filament/Blocks PA @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks PA @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PA @Blocks_RD50_V2", + "renamed_from": "Blocks Generic PA;Generic PA @Blocks", "inherits": "Blocks PA @base", "from": "system", "setting_id": "gxD81n2jjrReLD29", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic PA;Generic PA @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PA-CF @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks PA-CF @Blocks_RD50_V2.json index 1946ce16b6..174ffbab6d 100644 --- a/resources/profiles/Blocks/filament/Blocks PA-CF @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks PA-CF @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PA-CF @Blocks_RD50_V2", + "renamed_from": "Blocks Generic PA-CF;Generic PA-CF @Blocks", "inherits": "Blocks PA-CF @base", "from": "system", "setting_id": "EtbeKx3rbhUo1TtM", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic PA-CF;Generic PA-CF @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PC @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks PC @Blocks_RD50_V2.json index cdeec3a9aa..4fe1758a1d 100644 --- a/resources/profiles/Blocks/filament/Blocks PC @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks PC @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PC @Blocks_RD50_V2", + "renamed_from": "Blocks Generic PC;Generic PC @Blocks", "inherits": "Blocks PC @base", "from": "system", "setting_id": "HLc0shWnKwJzSFyW", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic PC;Generic PC @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PETG @Blocks_Pro_S100.json b/resources/profiles/Blocks/filament/Blocks PETG @Blocks_Pro_S100.json index 3a6619c8ef..8dab9e61d2 100644 --- a/resources/profiles/Blocks/filament/Blocks PETG @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/filament/Blocks PETG @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PETG @Blocks_Pro_S100", + "renamed_from": "Blocks Generic PETG;Generic PETG @Blocks", "inherits": "Blocks PETG @base", "from": "system", "setting_id": "AhMR49fcFqtrQ6hI", @@ -11,6 +12,5 @@ "BLOCKS Pro S100 0.8 nozzle", "BLOCKS Pro S100 1.0 nozzle", "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "Blocks Generic PETG;Generic PETG @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PLA @Blocks_Pro_S100.json b/resources/profiles/Blocks/filament/Blocks PLA @Blocks_Pro_S100.json index 64f6bbefa0..d68c94d143 100644 --- a/resources/profiles/Blocks/filament/Blocks PLA @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/filament/Blocks PLA @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PLA @Blocks_Pro_S100", + "renamed_from": "Blocks Generic PLA;Generic PLA @Blocks", "inherits": "Blocks PLA @base", "from": "system", "setting_id": "vWojuLYIfduLGFLL", @@ -11,6 +12,5 @@ "BLOCKS Pro S100 0.8 nozzle", "BLOCKS Pro S100 1.0 nozzle", "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "Blocks Generic PLA;Generic PLA @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PLA-CF @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks PLA-CF @Blocks_RD50_V2.json index 08050266b7..690779dfdb 100644 --- a/resources/profiles/Blocks/filament/Blocks PLA-CF @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks PLA-CF @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PLA-CF @Blocks_RD50_V2", + "renamed_from": "Blocks Generic PLA-CF;Generic PLA-CF @Blocks", "inherits": "Blocks PLA-CF @base", "from": "system", "setting_id": "lhBtMKP1DmOB3HOI", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic PLA-CF;Generic PLA-CF @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks PVA @Blocks_RD50_V2.json b/resources/profiles/Blocks/filament/Blocks PVA @Blocks_RD50_V2.json index f1beff3b23..c000e8bc7d 100644 --- a/resources/profiles/Blocks/filament/Blocks PVA @Blocks_RD50_V2.json +++ b/resources/profiles/Blocks/filament/Blocks PVA @Blocks_RD50_V2.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks PVA @Blocks_RD50_V2", + "renamed_from": "Blocks Generic PVA;Generic PVA @Blocks", "inherits": "Blocks PVA @base", "from": "system", "setting_id": "hREDqwKF6qyKkakp", @@ -9,6 +10,5 @@ "BLOCKS RD50 V2 0.4 nozzle", "BLOCKS RD50 V2 0.6 nozzle", "BLOCKS RD50 V2 0.8 nozzle" - ], - "renamed_from": "Blocks Generic PVA;Generic PVA @Blocks" + ] } diff --git a/resources/profiles/Blocks/filament/Blocks TPU @Blocks_Pro_S100.json b/resources/profiles/Blocks/filament/Blocks TPU @Blocks_Pro_S100.json index d186e824ef..c397c06bb6 100644 --- a/resources/profiles/Blocks/filament/Blocks TPU @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/filament/Blocks TPU @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Blocks TPU @Blocks_Pro_S100", + "renamed_from": "Blocks Generic TPU;Generic TPU @Blocks", "inherits": "Blocks TPU @base", "from": "system", "setting_id": "6Rkz2je91JRTRoTi", @@ -11,6 +12,5 @@ "BLOCKS Pro S100 0.8 nozzle", "BLOCKS Pro S100 1.0 nozzle", "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "Blocks Generic TPU;Generic TPU @Blocks" + ] } diff --git a/resources/profiles/Blocks/machine/BLOCKS RF50 0.4 nozzle.json b/resources/profiles/Blocks/machine/BLOCKS RF50 0.4 nozzle.json index 9e523ef843..00954cc1c3 100644 --- a/resources/profiles/Blocks/machine/BLOCKS RF50 0.4 nozzle.json +++ b/resources/profiles/Blocks/machine/BLOCKS RF50 0.4 nozzle.json @@ -39,15 +39,19 @@ "20000" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ], "retraction_length": [ diff --git a/resources/profiles/Blocks/machine/BLOCKS RF50 0.6 nozzle.json b/resources/profiles/Blocks/machine/BLOCKS RF50 0.6 nozzle.json index b0dbc7d2b9..930d7591f3 100644 --- a/resources/profiles/Blocks/machine/BLOCKS RF50 0.6 nozzle.json +++ b/resources/profiles/Blocks/machine/BLOCKS RF50 0.6 nozzle.json @@ -39,15 +39,19 @@ "20000" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ], "retraction_length": [ diff --git a/resources/profiles/Blocks/machine/BLOCKS RF50 0.8 nozzle.json b/resources/profiles/Blocks/machine/BLOCKS RF50 0.8 nozzle.json index c361a8da16..dc1b704a9e 100644 --- a/resources/profiles/Blocks/machine/BLOCKS RF50 0.8 nozzle.json +++ b/resources/profiles/Blocks/machine/BLOCKS RF50 0.8 nozzle.json @@ -39,15 +39,19 @@ "20000" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ], "retraction_length": [ diff --git a/resources/profiles/Blocks/process/0.20mm Standard 0.4 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.20mm Standard 0.4 nozzle @Blocks_Pro_S100.json index d5a27fa23b..8b7704a63a 100644 --- a/resources/profiles/Blocks/process/0.20mm Standard 0.4 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.20mm Standard 0.4 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.20mm Standard 0.4 nozzle @Blocks_Pro_S100", + "renamed_from": "0.20mm Standard 0.4 nozzle @Blocks", "inherits": "fdm_process_blocks_common", "from": "system", "setting_id": "QSEguMMChNFZsK5H", @@ -10,6 +11,5 @@ "top_shell_layers": "5", "compatible_printers": [ "BLOCKS Pro S100 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard 0.4 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.24mm Draft 0.4 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.24mm Draft 0.4 nozzle @Blocks_Pro_S100.json index 2716ce0c66..2bf1bc9b85 100644 --- a/resources/profiles/Blocks/process/0.24mm Draft 0.4 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.24mm Draft 0.4 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.24mm Draft 0.4 nozzle @Blocks_Pro_S100", + "renamed_from": "0.24mm Draft 0.4 nozzle @Blocks", "inherits": "fdm_process_blocks_common", "from": "system", "setting_id": "uALfEFHGmup6vBYI", @@ -10,6 +11,5 @@ "top_shell_layers": "5", "compatible_printers": [ "BLOCKS Pro S100 0.4 nozzle" - ], - "renamed_from": "0.24mm Draft 0.4 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100.json index c67ebf9341..eb2adc5e66 100644 --- a/resources/profiles/Blocks/process/0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100", + "renamed_from": "0.30mm Extra Draft 0.4 nozzle @Blocks", "inherits": "fdm_process_blocks_common", "from": "system", "setting_id": "HYKF5l2OGvpugSQy", @@ -10,6 +11,5 @@ "layer_height": "0.30", "compatible_printers": [ "BLOCKS Pro S100 0.4 nozzle" - ], - "renamed_from": "0.30mm Extra Draft 0.4 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100.json index bbd486176f..43c66f8978 100644 --- a/resources/profiles/Blocks/process/0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100", + "renamed_from": "0.30mm Optimal 0.8 nozzle @Blocks", "inherits": "fdm_process_common 0.8 nozzle", "from": "system", "setting_id": "OUfZvizM5MGnvHfp", @@ -10,6 +11,5 @@ "layer_height": "0.3", "compatible_printers": [ "BLOCKS Pro S100 0.8 nozzle" - ], - "renamed_from": "0.30mm Optimal 0.8 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100.json index e7ce874a77..be8a15f243 100644 --- a/resources/profiles/Blocks/process/0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100", + "renamed_from": "0.30mm Optimal 1.0 nozzle @Blocks", "inherits": "fdm_process_common 1.0 nozzle", "from": "system", "setting_id": "HGG9WxKVr89qNFDx", @@ -10,6 +11,5 @@ "layer_height": "0.30", "compatible_printers": [ "BLOCKS Pro S100 1.0 nozzle" - ], - "renamed_from": "0.30mm Optimal 1.0 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.30mm Standard 0.6 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.30mm Standard 0.6 nozzle @Blocks_Pro_S100.json index 00e37a7860..bdcc3d2f22 100644 --- a/resources/profiles/Blocks/process/0.30mm Standard 0.6 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.30mm Standard 0.6 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Standard 0.6 nozzle @Blocks_Pro_S100", + "renamed_from": "0.30mm Standard 0.6 nozzle @Blocks", "inherits": "fdm_process_common 0.6 nozzle", "from": "system", "setting_id": "gO2I1YjBl4nf8yzr", @@ -10,6 +11,5 @@ "layer_height": "0.30", "compatible_printers": [ "BLOCKS Pro S100 0.6 nozzle" - ], - "renamed_from": "0.30mm Standard 0.6 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.40mm Draft 0.6 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.40mm Draft 0.6 nozzle @Blocks_Pro_S100.json index 915d160b6c..6613c55d57 100644 --- a/resources/profiles/Blocks/process/0.40mm Draft 0.6 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.40mm Draft 0.6 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.40mm Draft 0.6 nozzle @Blocks_Pro_S100", + "renamed_from": "0.40mm Draft 0.6 nozzle @Blocks", "inherits": "fdm_process_common 0.6 nozzle", "from": "system", "setting_id": "OjsLUl1heqv1cevs", @@ -10,6 +11,5 @@ "layer_height": "0.40", "compatible_printers": [ "BLOCKS Pro S100 0.6 nozzle" - ], - "renamed_from": "0.40mm Draft 0.6 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.40mm Standard 0.8 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.40mm Standard 0.8 nozzle @Blocks_Pro_S100.json index 20f02ff7af..ae0a24b261 100644 --- a/resources/profiles/Blocks/process/0.40mm Standard 0.8 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.40mm Standard 0.8 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.40mm Standard 0.8 nozzle @Blocks_Pro_S100", + "renamed_from": "0.40mm Standard 0.8 nozzle @Blocks", "inherits": "fdm_process_common 0.8 nozzle", "from": "system", "setting_id": "laOTioBGySeudJpl", @@ -10,6 +11,5 @@ "layer_height": "0.40", "compatible_printers": [ "BLOCKS Pro S100 0.8 nozzle" - ], - "renamed_from": "0.40mm Standard 0.8 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.50mm Draft 0.8 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.50mm Draft 0.8 nozzle @Blocks_Pro_S100.json index 8f358e60e2..56058fc52d 100644 --- a/resources/profiles/Blocks/process/0.50mm Draft 0.8 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.50mm Draft 0.8 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.50mm Draft 0.8 nozzle @Blocks_Pro_S100", + "renamed_from": "0.50mm Draft 0.8 nozzle @Blocks", "inherits": "fdm_process_common 0.8 nozzle", "from": "system", "setting_id": "oAhgUZdADR7kP87e", @@ -10,6 +11,5 @@ "layer_height": "0.50", "compatible_printers": [ "BLOCKS Pro S100 0.8 nozzle" - ], - "renamed_from": "0.50mm Draft 0.8 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100.json index 11c79d1a65..582cdb1043 100644 --- a/resources/profiles/Blocks/process/0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100", + "renamed_from": "0.50mm Optimal 1.2 nozzle @Blocks", "inherits": "fdm_process_common 1.2 nozzle", "from": "system", "setting_id": "0eqNgX26jemsBfV5", @@ -10,6 +11,5 @@ "layer_height": "0.50", "compatible_printers": [ "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "0.50mm Optimal 1.2 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.50mm Standard 1.0 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.50mm Standard 1.0 nozzle @Blocks_Pro_S100.json index 0bd91d3405..301c7d6dd7 100644 --- a/resources/profiles/Blocks/process/0.50mm Standard 1.0 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.50mm Standard 1.0 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.50mm Standard 1.0 nozzle @Blocks_Pro_S100", + "renamed_from": "0.50mm Standard 1.0 nozzle @Blocks", "inherits": "fdm_process_common 1.0 nozzle", "from": "system", "setting_id": "z1qCW1cEMc4QvBbV", @@ -10,6 +11,5 @@ "layer_height": "0.50", "compatible_printers": [ "BLOCKS Pro S100 1.0 nozzle" - ], - "renamed_from": "0.50mm Standard 1.0 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.60mm Draft 1.0 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.60mm Draft 1.0 nozzle @Blocks_Pro_S100.json index f63ebde1bc..5d883bba1e 100644 --- a/resources/profiles/Blocks/process/0.60mm Draft 1.0 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.60mm Draft 1.0 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.60mm Draft 1.0 nozzle @Blocks_Pro_S100", + "renamed_from": "0.60mm Draft 1.0 nozzle @Blocks", "inherits": "fdm_process_common 1.0 nozzle", "from": "system", "setting_id": "gTTgtfG8qb9My3hH", @@ -10,6 +11,5 @@ "layer_height": "0.60", "compatible_printers": [ "BLOCKS Pro S100 1.0 nozzle" - ], - "renamed_from": "0.60mm Draft 1.0 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.60mm Standard 1.2 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.60mm Standard 1.2 nozzle @Blocks_Pro_S100.json index ba93c393a6..326215bc82 100644 --- a/resources/profiles/Blocks/process/0.60mm Standard 1.2 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.60mm Standard 1.2 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.60mm Standard 1.2 nozzle @Blocks_Pro_S100", + "renamed_from": "0.60mm Standard 1.2 nozzle @Blocks", "inherits": "fdm_process_common 1.2 nozzle", "from": "system", "setting_id": "ApcyToENCIANrI71", @@ -10,6 +11,5 @@ "layer_height": "0.60", "compatible_printers": [ "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "0.60mm Standard 1.2 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.70mm Draft 1.2 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.70mm Draft 1.2 nozzle @Blocks_Pro_S100.json index 7950bce0ca..00eb2414a9 100644 --- a/resources/profiles/Blocks/process/0.70mm Draft 1.2 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.70mm Draft 1.2 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.70mm Draft 1.2 nozzle @Blocks_Pro_S100", + "renamed_from": "0.70mm Draft 1.2 nozzle @Blocks", "inherits": "fdm_process_common 1.2 nozzle", "from": "system", "setting_id": "DEv7X7zaTfxRQmjo", @@ -10,6 +11,5 @@ "layer_height": "0.70", "compatible_printers": [ "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "0.70mm Draft 1.2 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100.json index 49d864ed8f..393e5937de 100644 --- a/resources/profiles/Blocks/process/0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100", + "renamed_from": "0.70mm Extra Draft 1.0 nozzle @Blocks", "inherits": "fdm_process_common 1.0 nozzle", "from": "system", "setting_id": "nUW7N9dJmTyQT4AG", @@ -10,6 +11,5 @@ "layer_height": "0.70", "compatible_printers": [ "BLOCKS Pro S100 1.0 nozzle" - ], - "renamed_from": "0.70mm Extra Draft 1.0 nozzle @Blocks" + ] } diff --git a/resources/profiles/Blocks/process/0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100.json b/resources/profiles/Blocks/process/0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100.json index 22f7628081..45642be537 100644 --- a/resources/profiles/Blocks/process/0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100.json +++ b/resources/profiles/Blocks/process/0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100", + "renamed_from": "0.80mm Extra Draft 1.2 nozzle @Blocks", "inherits": "fdm_process_common 1.2 nozzle", "from": "system", "setting_id": "JMy62SonRfK0cAdL", @@ -10,6 +11,5 @@ "layer_height": "0.80", "compatible_printers": [ "BLOCKS Pro S100 1.2 nozzle" - ], - "renamed_from": "0.80mm Extra Draft 1.2 nozzle @Blocks" + ] } diff --git a/resources/profiles/CONSTRUCT3D.json b/resources/profiles/CONSTRUCT3D.json index 55845903b0..eaa44771ea 100644 --- a/resources/profiles/CONSTRUCT3D.json +++ b/resources/profiles/CONSTRUCT3D.json @@ -1,6 +1,6 @@ { "name": "CONSTRUCT3D", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "Construct3D configurations", "machine_model_list": [ diff --git a/resources/profiles/CONSTRUCT3D/filament/Generic High Flow PETG @C1.json b/resources/profiles/CONSTRUCT3D/filament/Generic High Flow PETG @C1.json index 11a7df0903..9a511418e3 100644 --- a/resources/profiles/CONSTRUCT3D/filament/Generic High Flow PETG @C1.json +++ b/resources/profiles/CONSTRUCT3D/filament/Generic High Flow PETG @C1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic High Flow PETG @C1", - "inherits": "fdm_filament_pet", "renamed_from": "C1 Generic High Flow PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "STRDBlNRWBGfRctE", "filament_id": "OFNjku08", diff --git a/resources/profiles/CONSTRUCT3D/filament/Generic PETG @C1.json b/resources/profiles/CONSTRUCT3D/filament/Generic PETG @C1.json index dfb510e993..de2fa2b2ab 100644 --- a/resources/profiles/CONSTRUCT3D/filament/Generic PETG @C1.json +++ b/resources/profiles/CONSTRUCT3D/filament/Generic PETG @C1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @C1", - "inherits": "fdm_filament_pet", "renamed_from": "C1 Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "v0b4nWyzRw5z5EfK", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/CONSTRUCT3D/filament/Generic PLA @C1.json b/resources/profiles/CONSTRUCT3D/filament/Generic PLA @C1.json index 4c8a90b1de..c5474c89ff 100644 --- a/resources/profiles/CONSTRUCT3D/filament/Generic PLA @C1.json +++ b/resources/profiles/CONSTRUCT3D/filament/Generic PLA @C1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @C1", - "inherits": "fdm_filament_pla", "renamed_from": "C1 Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "mCKOBqN6Y92a9nHV", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/CONSTRUCT3D/machine/Construct 1 0.4 nozzle.json b/resources/profiles/CONSTRUCT3D/machine/Construct 1 0.4 nozzle.json index a83c207d1d..a186f253b1 100644 --- a/resources/profiles/CONSTRUCT3D/machine/Construct 1 0.4 nozzle.json +++ b/resources/profiles/CONSTRUCT3D/machine/Construct 1 0.4 nozzle.json @@ -22,12 +22,15 @@ "nozzle_type": "hardened_steel", "thumbnails_format": "QOI", "machine_max_acceleration_e": [ + "9000", "9000" ], "machine_max_acceleration_extruding": [ + "9000", "9000" ], "machine_max_acceleration_retracting": [ + "9000", "9000" ], "machine_max_acceleration_travel": [ @@ -35,30 +38,39 @@ "1250" ], "machine_max_acceleration_x": [ + "18000", "18000" ], "machine_max_acceleration_y": [ + "18000", "18000" ], "machine_max_jerk_e": [ + "6", "6" ], "machine_max_jerk_x": [ + "25", "25" ], "machine_max_jerk_y": [ + "25", "25" ], "machine_max_speed_e": [ + "100", "100" ], "machine_max_speed_x": [ + "320", "320" ], "machine_max_speed_y": [ + "320", "320" ], "machine_max_speed_z": [ + "40", "40" ], "machine_end_gcode": ";Retract the filament\nG92 E1\nG1 E-5 F900\n;Move nozzle fast\nG1 X5 Y258 F15000\n;Move Bed Down\nG1 Z180 F6000\n\n;Set machine to idle\nM104 S0\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM84 ; disable motors", diff --git a/resources/profiles/CONSTRUCT3D/machine/Construct 1 XL 0.6 nozzle.json b/resources/profiles/CONSTRUCT3D/machine/Construct 1 XL 0.6 nozzle.json index ca001ed3ea..51b7b0dc75 100644 --- a/resources/profiles/CONSTRUCT3D/machine/Construct 1 XL 0.6 nozzle.json +++ b/resources/profiles/CONSTRUCT3D/machine/Construct 1 XL 0.6 nozzle.json @@ -22,12 +22,15 @@ "nozzle_type": "hardened_steel", "thumbnails_format": "QOI", "machine_max_acceleration_e": [ + "9000", "9000" ], "machine_max_acceleration_extruding": [ + "9000", "9000" ], "machine_max_acceleration_retracting": [ + "9000", "9000" ], "machine_max_acceleration_travel": [ @@ -35,30 +38,39 @@ "1250" ], "machine_max_acceleration_x": [ + "18000", "18000" ], "machine_max_acceleration_y": [ + "18000", "18000" ], "machine_max_jerk_e": [ + "6", "6" ], "machine_max_jerk_x": [ + "25", "25" ], "machine_max_jerk_y": [ + "25", "25" ], "machine_max_speed_e": [ + "100", "100" ], "machine_max_speed_x": [ + "320", "320" ], "machine_max_speed_y": [ + "320", "320" ], "machine_max_speed_z": [ + "40", "40" ], "machine_end_gcode": ";Retract the filament\nG92 E1\nG1 E-5 F900\n;Move nozzle fast\nG1 X5 Y369 F15000\n;Move Bed Down\nG1 Z400 F6000\n\n;Set machine to idle\nT-1\nM104 S0\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM84 ; disable motors\n", diff --git a/resources/profiles/Chuanying.json b/resources/profiles/Chuanying.json index 5434e13bb8..3125f8d2e9 100644 --- a/resources/profiles/Chuanying.json +++ b/resources/profiles/Chuanying.json @@ -1,7 +1,7 @@ { "name": "Chuanying", "url": "", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Chuanying configurations", "machine_model_list": [ diff --git a/resources/profiles/Chuanying/filament/Generic ABS @Chuanying X1 0.25 Nozzle.json b/resources/profiles/Chuanying/filament/Generic ABS @Chuanying X1 0.25 Nozzle.json index f54d17ef0d..47115a5556 100644 --- a/resources/profiles/Chuanying/filament/Generic ABS @Chuanying X1 0.25 Nozzle.json +++ b/resources/profiles/Chuanying/filament/Generic ABS @Chuanying X1 0.25 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Chuanying X1 0.25 Nozzle", - "inherits": "Generic ABS @Chuanying", "renamed_from": "Chuanying ABS @Chuanying X1 0.25 Nozzle;Chuanying ABS Chuanying X1 0.25 Nozzle", + "inherits": "Generic ABS @Chuanying", "from": "system", "setting_id": "uHqfv6eUDzoxEkEj", "instantiation": "true", diff --git a/resources/profiles/Chuanying/filament/Generic ABS @Chuanying.json b/resources/profiles/Chuanying/filament/Generic ABS @Chuanying.json index 570cd814df..6c2ba4bc28 100644 --- a/resources/profiles/Chuanying/filament/Generic ABS @Chuanying.json +++ b/resources/profiles/Chuanying/filament/Generic ABS @Chuanying.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Chuanying", - "inherits": "fdm_filament_abs", "renamed_from": "Chuanying Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "iOgVkaYF0sixbb9x", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Chuanying/filament/Generic ASA @Chuanying X1 0.25 Nozzle.json b/resources/profiles/Chuanying/filament/Generic ASA @Chuanying X1 0.25 Nozzle.json index 690f31669a..903dd7feb2 100644 --- a/resources/profiles/Chuanying/filament/Generic ASA @Chuanying X1 0.25 Nozzle.json +++ b/resources/profiles/Chuanying/filament/Generic ASA @Chuanying X1 0.25 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Chuanying X1 0.25 Nozzle", - "inherits": "Generic ASA @Chuanying", "renamed_from": "Chuanying ASA @Chuanying X1 0.25 Nozzle;Chuanying ASA Chuanying X1 0.25 Nozzle", + "inherits": "Generic ASA @Chuanying", "from": "system", "setting_id": "bVxY01TC9sAM9KQW", "instantiation": "true", diff --git a/resources/profiles/Chuanying/filament/Generic HS PLA @Chuanying X1 0.25 Nozzle.json b/resources/profiles/Chuanying/filament/Generic HS PLA @Chuanying X1 0.25 Nozzle.json index 339fae8619..7a3e125246 100644 --- a/resources/profiles/Chuanying/filament/Generic HS PLA @Chuanying X1 0.25 Nozzle.json +++ b/resources/profiles/Chuanying/filament/Generic HS PLA @Chuanying X1 0.25 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic HS PLA @Chuanying X1 0.25 Nozzle", - "inherits": "Generic HS PLA @Chuanying", "renamed_from": "Chuanying HS PLA @Chuanying X1 0.25 Nozzle;Chuanying HS PLA Chuanying X1 0.25 Nozzle", + "inherits": "Generic HS PLA @Chuanying", "from": "system", "setting_id": "gdW1LIVf6BecAtpa", "instantiation": "true", diff --git a/resources/profiles/Chuanying/filament/Generic PETG @Chuanying X1 0.25 Nozzle.json b/resources/profiles/Chuanying/filament/Generic PETG @Chuanying X1 0.25 Nozzle.json index 88eaf57c01..c31060d7bd 100644 --- a/resources/profiles/Chuanying/filament/Generic PETG @Chuanying X1 0.25 Nozzle.json +++ b/resources/profiles/Chuanying/filament/Generic PETG @Chuanying X1 0.25 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Chuanying X1 0.25 Nozzle", - "inherits": "Generic PETG @Chuanying", "renamed_from": "Chuanying PETG @Chuanying X1 0.25 Nozzle;Chuanying PETG Chuanying X1 0.25 Nozzle", + "inherits": "Generic PETG @Chuanying", "from": "system", "setting_id": "YQ0HAxEDmMQgqNGY", "instantiation": "true", diff --git a/resources/profiles/Chuanying/filament/Generic PETG @Chuanying.json b/resources/profiles/Chuanying/filament/Generic PETG @Chuanying.json index ae84fb2982..ef2c336b7f 100644 --- a/resources/profiles/Chuanying/filament/Generic PETG @Chuanying.json +++ b/resources/profiles/Chuanying/filament/Generic PETG @Chuanying.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Chuanying", - "inherits": "fdm_filament_pet", "renamed_from": "Chuanying Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "Mq3uwHDMub81SuRG", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Chuanying/filament/Generic PLA @Chuanying X1 0.25 Nozzle.json b/resources/profiles/Chuanying/filament/Generic PLA @Chuanying X1 0.25 Nozzle.json index cea064f9da..05a142627f 100644 --- a/resources/profiles/Chuanying/filament/Generic PLA @Chuanying X1 0.25 Nozzle.json +++ b/resources/profiles/Chuanying/filament/Generic PLA @Chuanying X1 0.25 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Chuanying X1 0.25 Nozzle", - "inherits": "Generic PLA @Chuanying", "renamed_from": "Chuanying PLA @Chuanying X1 0.25 Nozzle;Chuanying PLA Chuanying X1 0.25 Nozzle", + "inherits": "Generic PLA @Chuanying", "from": "system", "setting_id": "XsPEVGHYiyAX4YXy", "instantiation": "true", diff --git a/resources/profiles/Chuanying/filament/Generic PLA @Chuanying.json b/resources/profiles/Chuanying/filament/Generic PLA @Chuanying.json index 3fcf7cf873..cf8b954c96 100644 --- a/resources/profiles/Chuanying/filament/Generic PLA @Chuanying.json +++ b/resources/profiles/Chuanying/filament/Generic PLA @Chuanying.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Chuanying", - "inherits": "fdm_filament_pla", "renamed_from": "Chuanying Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "PRk8NAihEzwi5Dqd", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying X1 0.25 Nozzle.json b/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying X1 0.25 Nozzle.json index 66d057cbf1..94f0bce238 100644 --- a/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying X1 0.25 Nozzle.json +++ b/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying X1 0.25 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-Silk @Chuanying X1 0.25 Nozzle", - "inherits": "Generic PLA-Silk @Chuanying", "renamed_from": "Chuanying PLA-SILK @Chuanying X1 0.25 Nozzle;Chuanying PLA-SILK Chuanying X1 0.25 Nozzle", + "inherits": "Generic PLA-Silk @Chuanying", "from": "system", "setting_id": "XaGDKARkuGTTabMN", "instantiation": "true", diff --git a/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying.json b/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying.json index 0739646658..f35355b2b7 100644 --- a/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying.json +++ b/resources/profiles/Chuanying/filament/Generic PLA-Silk @Chuanying.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-Silk @Chuanying", - "inherits": "fdm_filament_pla", "renamed_from": "Chuanying Generic PLA-Silk", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "tSCou6bWg8eY1TFn", "filament_id": "OFi6PfUM", diff --git a/resources/profiles/Co Print.json b/resources/profiles/Co Print.json index 2e1ad809eb..18902a2932 100644 --- a/resources/profiles/Co Print.json +++ b/resources/profiles/Co Print.json @@ -1,6 +1,6 @@ { "name": "Co Print", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "CoPrint configurations", "machine_model_list": [ diff --git a/resources/profiles/Co Print/filament/Generic ABS @CoPrint.json b/resources/profiles/Co Print/filament/Generic ABS @CoPrint.json index f047afc265..470a917e55 100644 --- a/resources/profiles/Co Print/filament/Generic ABS @CoPrint.json +++ b/resources/profiles/Co Print/filament/Generic ABS @CoPrint.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @CoPrint", - "inherits": "Generic PLA @CoPrint", "renamed_from": "CoPrint Generic ABS", + "inherits": "Generic PLA @CoPrint", "from": "system", "setting_id": "T6mJwfI7n1YDmDzv", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Co Print/filament/Generic PETG @CoPrint.json b/resources/profiles/Co Print/filament/Generic PETG @CoPrint.json index dd2d03af04..331056a6d9 100644 --- a/resources/profiles/Co Print/filament/Generic PETG @CoPrint.json +++ b/resources/profiles/Co Print/filament/Generic PETG @CoPrint.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @CoPrint", - "inherits": "Generic PLA @CoPrint", "renamed_from": "CoPrint Generic PETG", + "inherits": "Generic PLA @CoPrint", "from": "system", "setting_id": "99zIrGIXC9RUGDlM", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Co Print/filament/Generic TPU @CoPrint.json b/resources/profiles/Co Print/filament/Generic TPU @CoPrint.json index c25896fe55..f536912987 100644 --- a/resources/profiles/Co Print/filament/Generic TPU @CoPrint.json +++ b/resources/profiles/Co Print/filament/Generic TPU @CoPrint.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @CoPrint", - "inherits": "Generic PLA @CoPrint", "renamed_from": "CoPrint Generic TPU", + "inherits": "Generic PLA @CoPrint", "from": "system", "setting_id": "0V6UoaCfNUIwYwah", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json index f032c9bf6e..17fe8260d1 100644 --- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json +++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3 Plus.json @@ -29,48 +29,63 @@ "0.5" ], "machine_max_speed_e": [ + "100", "100" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_acceleration_e": [ + "2500", "2500" ], "machine_max_acceleration_extruding": [ + "5000", "5000" ], "machine_max_acceleration_retracting": [ + "2500", "2500" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "5000", "5000" ], "machine_max_acceleration_y": [ + "5000", "5000" ], "machine_max_acceleration_z": [ + "100", "100" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "8", "8" ], "machine_max_jerk_y": [ + "8", "8" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "z_hop": [ diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json index a36e231d94..e479a91cc6 100644 --- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json +++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle - Ender-3 V3.json @@ -29,48 +29,63 @@ "0.5" ], "machine_max_speed_e": [ + "100", "100" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_acceleration_e": [ + "2500", "2500" ], "machine_max_acceleration_extruding": [ + "5000", "5000" ], "machine_max_acceleration_retracting": [ + "2500", "2500" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "5000", "5000" ], "machine_max_acceleration_y": [ + "5000", "5000" ], "machine_max_acceleration_z": [ + "100", "100" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "8", "8" ], "machine_max_jerk_y": [ + "8", "8" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "z_hop": [ diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json index 2d206c1734..15620e545e 100644 --- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json +++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle fast.json @@ -29,48 +29,63 @@ "0.5" ], "machine_max_speed_e": [ + "100", "100" ], "machine_max_speed_x": [ + "700", "700" ], "machine_max_speed_y": [ + "700", "700" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", "20000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json index 72116fcd70..1f9cf4a9d1 100644 --- a/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json +++ b/resources/profiles/Co Print/machine/Co Print ChromaSet 0.4 nozzle.json @@ -29,48 +29,63 @@ "0.5" ], "machine_max_speed_e": [ + "100", "100" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_acceleration_e": [ + "2500", "2500" ], "machine_max_acceleration_extruding": [ + "5000", "5000" ], "machine_max_acceleration_retracting": [ + "2500", "2500" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "5000", "5000" ], "machine_max_acceleration_y": [ + "5000", "5000" ], "machine_max_acceleration_z": [ + "100", "100" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "8", "8" ], "machine_max_jerk_y": [ + "8", "8" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "z_hop": [ diff --git a/resources/profiles/CoLiDo.json b/resources/profiles/CoLiDo.json index 3333d2e71c..3aaee455d3 100644 --- a/resources/profiles/CoLiDo.json +++ b/resources/profiles/CoLiDo.json @@ -1,6 +1,6 @@ { "name": "CoLiDo", - "version": "02.04.00.06", + "version": "02.04.00.07", "force_update": "0", "description": "CoLiDo configurations", "machine_model_list": [ diff --git a/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo DIY 4.0.json b/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo DIY 4.0.json index acb6033883..cd80fbd170 100644 --- a/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo DIY 4.0.json +++ b/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo DIY 4.0.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @CoLiDo DIY 4.0", - "inherits": "fdm_filament_abs", "renamed_from": "CoLiDo Generic ABS @CoLiDo DIY 4.0;CoLiDo Generic ABS CoLiDo DIY 4.0", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "XLTLGUPGcCZnX5XA", "filament_id": "OFY9muEs", diff --git a/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo X16.json b/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo X16.json index aa567b7ba8..c5707a18cb 100644 --- a/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo X16.json +++ b/resources/profiles/CoLiDo/filament/Generic ABS @CoLiDo X16.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @CoLiDo X16", - "inherits": "fdm_filament_abs", "renamed_from": "CoLiDo Generic ABS @CoLiDo X16;CoLiDo Generic ABS CoLiDo X16", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "LE7jeYUNsBZEKQpJ", "filament_id": "OFY9muEs", diff --git a/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo DIY 4.0.json b/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo DIY 4.0.json index d70dd4d511..cf724d73c4 100644 --- a/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo DIY 4.0.json +++ b/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo DIY 4.0.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @CoLiDo DIY 4.0", - "inherits": "fdm_filament_pet", "renamed_from": "CoLiDo Generic PETG @CoLiDo DIY 4.0;CoLiDo Generic PETG CoLiDo DIY 4.0", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "FV2MjDSWlg3kolp3", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo X16.json b/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo X16.json index 5f68b5600b..771cbc8dd7 100644 --- a/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo X16.json +++ b/resources/profiles/CoLiDo/filament/Generic PETG @CoLiDo X16.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @CoLiDo X16", - "inherits": "fdm_filament_pet", "renamed_from": "CoLiDo Generic PETG @CoLiDo X16;CoLiDo Generic PETG CoLiDo X16", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "eX4i0rDwO3rAlQ2y", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo DIY 4.0.json b/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo DIY 4.0.json index 9bd8db3357..0bea71d187 100644 --- a/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo DIY 4.0.json +++ b/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo DIY 4.0.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @CoLiDo DIY 4.0", - "inherits": "fdm_filament_pla", "renamed_from": "CoLiDo Generic PLA @CoLiDo DIY 4.0;CoLiDo Generic PLA CoLiDo DIY 4.0", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "POF6nKughZF8OsBF", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo X16.json b/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo X16.json index f437702111..601ba78cde 100644 --- a/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo X16.json +++ b/resources/profiles/CoLiDo/filament/Generic PLA @CoLiDo X16.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @CoLiDo X16", - "inherits": "fdm_filament_pla", "renamed_from": "CoLiDo Generic PLA @CoLiDo X16;CoLiDo Generic PLA CoLiDo X16", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "38SFNLJEVBeAVL3B", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo DIY 4.0.json b/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo DIY 4.0.json index 0422f6b4c6..46dce9d565 100644 --- a/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo DIY 4.0.json +++ b/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo DIY 4.0.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @CoLiDo DIY 4.0", - "inherits": "fdm_filament_tpu", "renamed_from": "CoLiDo Generic TPU @CoLiDo DIY 4.0;CoLiDo Generic TPU CoLiDo DIY 4.0", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "5tJNn6c6RXqJUT2z", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo X16.json b/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo X16.json index ccf0d405b1..f1ba622d3b 100644 --- a/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo X16.json +++ b/resources/profiles/CoLiDo/filament/Generic TPU @CoLiDo X16.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @CoLiDo X16", - "inherits": "fdm_filament_tpu", "renamed_from": "CoLiDo Generic TPU @CoLiDo X16;CoLiDo Generic TPU CoLiDo X16", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "wylEuYSIKlzSVnoQ", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/CoLiDo/machine/CoLiDo 160 V2 0.4 nozzle.json b/resources/profiles/CoLiDo/machine/CoLiDo 160 V2 0.4 nozzle.json index b02f431b3e..76da0b0c03 100644 --- a/resources/profiles/CoLiDo/machine/CoLiDo 160 V2 0.4 nozzle.json +++ b/resources/profiles/CoLiDo/machine/CoLiDo 160 V2 0.4 nozzle.json @@ -57,12 +57,15 @@ "machine_end_gcode": "G1 E-1.0 F2100 ; retract\nG92 E0.0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} E-3.0 F720 ; move print head up & retract filament\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y0 F3000 ; park print head\nM84 ; disable motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "1000", "1000" ], "machine_max_acceleration_retracting": [ + "1000", "1000" ], "machine_max_acceleration_travel": [ @@ -70,36 +73,47 @@ "0" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "8", "8" ], "machine_max_jerk_y": [ + "8", "8" ], "machine_max_jerk_z": [ + "0.4", "0.4" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "300", "300" ], "machine_max_speed_y": [ + "300", "300" ], "machine_max_speed_z": [ + "10", "10" ], "machine_min_extruding_rate": [ diff --git a/resources/profiles/CoLiDo/machine/CoLiDo X16 0.4 nozzle.json b/resources/profiles/CoLiDo/machine/CoLiDo X16 0.4 nozzle.json index 4110cbe15d..ee232937ba 100644 --- a/resources/profiles/CoLiDo/machine/CoLiDo X16 0.4 nozzle.json +++ b/resources/profiles/CoLiDo/machine/CoLiDo X16 0.4 nozzle.json @@ -57,12 +57,15 @@ "machine_end_gcode": "G1 E-1.0 F2100 ; retract\nG92 E0.0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} E-3.0 F720 ; move print head up & retract filament\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y0 F3000 ; park print head\nM84 ; disable motors", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "1000", "1000" ], "machine_max_acceleration_retracting": [ + "1000", "1000" ], "machine_max_acceleration_travel": [ @@ -70,36 +73,47 @@ "0" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "8", "8" ], "machine_max_jerk_y": [ + "8", "8" ], "machine_max_jerk_z": [ + "0.4", "0.4" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "300", "300" ], "machine_max_speed_y": [ + "300", "300" ], "machine_max_speed_z": [ + "10", "10" ], "machine_min_extruding_rate": [ diff --git a/resources/profiles/Comgrow.json b/resources/profiles/Comgrow.json index e3eb237518..d5e20fc2da 100644 --- a/resources/profiles/Comgrow.json +++ b/resources/profiles/Comgrow.json @@ -1,6 +1,6 @@ { "name": "Comgrow", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Comgrow configurations", "machine_model_list": [ diff --git a/resources/profiles/Comgrow/filament/Generic ABS @Comgrow.json b/resources/profiles/Comgrow/filament/Generic ABS @Comgrow.json index 0494418d88..dd0b824817 100644 --- a/resources/profiles/Comgrow/filament/Generic ABS @Comgrow.json +++ b/resources/profiles/Comgrow/filament/Generic ABS @Comgrow.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Comgrow", - "inherits": "fdm_filament_abs", "renamed_from": "Comgrow Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "jprGDn9oZEZu4N97", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Comgrow/filament/Generic PETG @Comgrow.json b/resources/profiles/Comgrow/filament/Generic PETG @Comgrow.json index 12b29d0b1d..c22a95c514 100644 --- a/resources/profiles/Comgrow/filament/Generic PETG @Comgrow.json +++ b/resources/profiles/Comgrow/filament/Generic PETG @Comgrow.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Comgrow", - "inherits": "fdm_filament_pet", "renamed_from": "Comgrow Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "xi0S7KdXD7lwr3H8", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Comgrow/filament/Generic PLA @Comgrow T300.json b/resources/profiles/Comgrow/filament/Generic PLA @Comgrow T300.json index bde24b8ba0..cf4a01fa4f 100644 --- a/resources/profiles/Comgrow/filament/Generic PLA @Comgrow T300.json +++ b/resources/profiles/Comgrow/filament/Generic PLA @Comgrow T300.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Comgrow T300", - "inherits": "Generic PLA @Comgrow", "renamed_from": "Comgrow T300 PLA", + "inherits": "Generic PLA @Comgrow", "from": "system", "setting_id": "3N6gPGkzpE9CvkVz", "instantiation": "true", diff --git a/resources/profiles/Comgrow/filament/Generic PLA @Comgrow.json b/resources/profiles/Comgrow/filament/Generic PLA @Comgrow.json index 21b8e19d42..c7c5c60ca3 100644 --- a/resources/profiles/Comgrow/filament/Generic PLA @Comgrow.json +++ b/resources/profiles/Comgrow/filament/Generic PLA @Comgrow.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Comgrow", - "inherits": "fdm_filament_pla", "renamed_from": "Comgrow Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "oxIMSlkJ8C40mJIv", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Comgrow/machine/Comgrow T300 0.4 nozzle.json b/resources/profiles/Comgrow/machine/Comgrow T300 0.4 nozzle.json index 2453aefcab..2af8864abf 100644 --- a/resources/profiles/Comgrow/machine/Comgrow T300 0.4 nozzle.json +++ b/resources/profiles/Comgrow/machine/Comgrow T300 0.4 nozzle.json @@ -27,45 +27,59 @@ "0.8" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_x": [ + "12000", "12000" ], "machine_max_acceleration_y": [ + "12000", "12000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.25", "0.25" ], "machine_max_jerk_e": [ + "3", "3" ], "z_hop": [ diff --git a/resources/profiles/Creality.json b/resources/profiles/Creality.json index 11647d86da..f9657c7034 100644 --- a/resources/profiles/Creality.json +++ b/resources/profiles/Creality.json @@ -1,6 +1,6 @@ { "name": "Creality", - "version": "02.03.02.85", + "version": "02.03.02.86", "force_update": "0", "description": "Creality configurations", "machine_model_list": [ diff --git a/resources/profiles/Creality/filament/Generic ABS @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic ABS @Creality Ender-3V3-all.json index 4081db783f..162ef3ddc7 100644 --- a/resources/profiles/Creality/filament/Generic ABS @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic ABS @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Creality Ender-3V3-all", - "inherits": "Generic ABS @Creality", "renamed_from": "Creality Generic ABS @Ender-3V3-all;Creality Generic ABS Ender-3V3-all", + "inherits": "Generic ABS @Creality", "from": "system", "setting_id": "RqMPGyaU3l17zFrA", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ABS @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic ABS @Creality Hi-all.json index aba8475a20..f459b7cc06 100644 --- a/resources/profiles/Creality/filament/Generic ABS @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic ABS @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Creality Hi-all", - "inherits": "Generic ABS @Creality", "renamed_from": "Creality Generic ABS @Hi-all;Creality Generic ABS Hi-all", + "inherits": "Generic ABS @Creality", "from": "system", "setting_id": "W2NhLx7Lw4NxWJY6", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ABS @Creality K1-all.json b/resources/profiles/Creality/filament/Generic ABS @Creality K1-all.json index 0ea7629f24..384b1c3ff0 100644 --- a/resources/profiles/Creality/filament/Generic ABS @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic ABS @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Creality K1-all", - "inherits": "Generic ABS @Creality", "renamed_from": "Creality Generic ABS @K1-all;Creality Generic ABS K1-all", + "inherits": "Generic ABS @Creality", "from": "system", "setting_id": "9hr2XywDT7lTehYd", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ABS @Creality K2-all.json b/resources/profiles/Creality/filament/Generic ABS @Creality K2-all.json index 4aab7d7d0d..0674bc1066 100644 --- a/resources/profiles/Creality/filament/Generic ABS @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic ABS @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Creality K2-all", - "inherits": "Generic ABS @Creality", "renamed_from": "Creality Generic ABS @K2-all;Creality Generic ABS K2-all", + "inherits": "Generic ABS @Creality", "from": "system", "setting_id": "39krWtacUjDnf03V", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ABS @Creality.json b/resources/profiles/Creality/filament/Generic ABS @Creality.json index 2e0bb44fa0..622178222c 100644 --- a/resources/profiles/Creality/filament/Generic ABS @Creality.json +++ b/resources/profiles/Creality/filament/Generic ABS @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Creality", - "inherits": "fdm_filament_abs", "renamed_from": "Creality Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "My3UvJeg30wW7hLq", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Creality/filament/Generic ASA @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic ASA @Creality Ender-3V3-all.json index 0675884518..7b559b188c 100644 --- a/resources/profiles/Creality/filament/Generic ASA @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic ASA @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Creality Ender-3V3-all", - "inherits": "Generic ASA @Creality", "renamed_from": "Creality Generic ASA @Ender-3V3-all;Creality Generic ASA Ender-3V3-all", + "inherits": "Generic ASA @Creality", "from": "system", "setting_id": "LXPKRyWzBzo9nU8k", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ASA @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic ASA @Creality Hi-all.json index e706078d18..525e1682ac 100644 --- a/resources/profiles/Creality/filament/Generic ASA @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic ASA @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Creality Hi-all", - "inherits": "Generic ASA @Creality", "renamed_from": "Creality Generic ASA @Hi-all;Creality Generic ASA Hi-all", + "inherits": "Generic ASA @Creality", "from": "system", "setting_id": "kcMcMJUiRgTRFe8P", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ASA @Creality K1-all.json b/resources/profiles/Creality/filament/Generic ASA @Creality K1-all.json index 91feecf436..c1b8e3e588 100644 --- a/resources/profiles/Creality/filament/Generic ASA @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic ASA @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Creality K1-all", - "inherits": "Generic ASA @Creality", "renamed_from": "Creality Generic ASA @K1-all;Creality Generic ASA K1-all", + "inherits": "Generic ASA @Creality", "from": "system", "setting_id": "GQVdb7ZBWA55Ld0m", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ASA @Creality K2-all.json b/resources/profiles/Creality/filament/Generic ASA @Creality K2-all.json index 510e1d7660..a3b9c1bb98 100644 --- a/resources/profiles/Creality/filament/Generic ASA @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic ASA @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Creality K2-all", - "inherits": "Generic ASA @Creality", "renamed_from": "Creality Generic ASA @K2-all;Creality Generic ASA K2-all", + "inherits": "Generic ASA @Creality", "from": "system", "setting_id": "XJKLmHYbW2ReKSKs", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic ASA @Creality.json b/resources/profiles/Creality/filament/Generic ASA @Creality.json index 0ef5d15433..3b7c470734 100644 --- a/resources/profiles/Creality/filament/Generic ASA @Creality.json +++ b/resources/profiles/Creality/filament/Generic ASA @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Creality", - "inherits": "fdm_filament_asa", "renamed_from": "Creality Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "dCUxfG2JXDg56zTK", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Creality/filament/Generic ASA-CF @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic ASA-CF @Creality Hi-all.json index 7a462cc250..f0fb24f465 100644 --- a/resources/profiles/Creality/filament/Generic ASA-CF @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic ASA-CF @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA-CF @Creality Hi-all", - "inherits": "Generic ASA @Creality Hi-all", "renamed_from": "Creality Generic ASA-CF @Hi-all;Creality Generic ASA-CF Hi-all", + "inherits": "Generic ASA @Creality Hi-all", "from": "system", "setting_id": "MwKV8Lh4XzvMUVYA", "filament_id": "OF53eLVD", diff --git a/resources/profiles/Creality/filament/Generic PA-CF @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic PA-CF @Creality Ender-3V3-all.json index 152c8100d6..4619cbadef 100644 --- a/resources/profiles/Creality/filament/Generic PA-CF @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic PA-CF @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Creality Ender-3V3-all", - "inherits": "Generic PA-CF @Creality", "renamed_from": "Creality Generic PA-CF @Ender-3V3-all;Creality Generic PA-CF Ender-3V3-all", + "inherits": "Generic PA-CF @Creality", "from": "system", "setting_id": "L9lg0gKfwuz9xcs4", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PA-CF @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PA-CF @Creality K1-all.json index 72519b07f2..23927dca0a 100644 --- a/resources/profiles/Creality/filament/Generic PA-CF @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PA-CF @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Creality K1-all", - "inherits": "Generic PA-CF @Creality", "renamed_from": "Creality Generic PA-CF @K1-all;Creality Generic PA-CF K1-all", + "inherits": "Generic PA-CF @Creality", "from": "system", "setting_id": "BkM0CVxYrvFPAbpQ", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PA-CF @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PA-CF @Creality K2-all.json index 932c37b2a2..7b3b8d746c 100644 --- a/resources/profiles/Creality/filament/Generic PA-CF @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PA-CF @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Creality K2-all", - "inherits": "Generic PA-CF @Creality", "renamed_from": "Creality Generic PA-CF @K2-all;Creality Generic PA-CF K2-all", + "inherits": "Generic PA-CF @Creality", "from": "system", "setting_id": "jCFh6dGbNQt7YHNB", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PA-CF @Creality.json b/resources/profiles/Creality/filament/Generic PA-CF @Creality.json index 964672343a..dfc1124f92 100644 --- a/resources/profiles/Creality/filament/Generic PA-CF @Creality.json +++ b/resources/profiles/Creality/filament/Generic PA-CF @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Creality", - "inherits": "fdm_filament_pa", "renamed_from": "Creality Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "JDbda1VeHrPKR0NN", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Creality/filament/Generic PC @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PC @Creality K1-all.json index a73499e2e9..684093851f 100644 --- a/resources/profiles/Creality/filament/Generic PC @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PC @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Creality K1-all", - "inherits": "Generic PC @Creality", "renamed_from": "Creality Generic PC @K1-all;Creality Generic PC K1-all", + "inherits": "Generic PC @Creality", "from": "system", "setting_id": "Jk9yNMEqu4M92edj", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PETG @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic PETG @Creality Ender-3V3-all.json index 5cabe6f64d..039a6143bc 100644 --- a/resources/profiles/Creality/filament/Generic PETG @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic PETG @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Creality Ender-3V3-all", - "inherits": "Generic PETG @Creality", "renamed_from": "Creality Generic PETG @Ender-3V3-all;Creality Generic PETG Ender-3V3-all", + "inherits": "Generic PETG @Creality", "from": "system", "setting_id": "sX2aMXNynDp6VKSR", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PETG @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PETG @Creality Hi-all.json index 0092cf5d12..5558df0d9d 100644 --- a/resources/profiles/Creality/filament/Generic PETG @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PETG @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Creality Hi-all", - "inherits": "Generic PETG @Creality", "renamed_from": "Creality Generic PETG @Hi-all;Creality Generic PETG Hi-all", + "inherits": "Generic PETG @Creality", "from": "system", "setting_id": "QcMkrViYBKh4oISG", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PETG @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PETG @Creality K1-all.json index 06fb485fd0..ca5022fa42 100644 --- a/resources/profiles/Creality/filament/Generic PETG @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PETG @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Creality K1-all", - "inherits": "Generic PETG @Creality", "renamed_from": "Creality Generic PETG @K1-all;Creality Generic PETG K1-all", + "inherits": "Generic PETG @Creality", "from": "system", "setting_id": "YEB1keha4rhCSmq8", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PETG @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PETG @Creality K2-all.json index 87e82d3eb5..45a308e5d0 100644 --- a/resources/profiles/Creality/filament/Generic PETG @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PETG @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Creality K2-all", - "inherits": "Generic PETG @Creality", "renamed_from": "Creality Generic PETG @K2-all;Creality Generic PETG K2-all", + "inherits": "Generic PETG @Creality", "from": "system", "setting_id": "IrbPRxkyhiUXaPEu", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PETG @Creality.json b/resources/profiles/Creality/filament/Generic PETG @Creality.json index d6b81cb3fd..f97d600565 100644 --- a/resources/profiles/Creality/filament/Generic PETG @Creality.json +++ b/resources/profiles/Creality/filament/Generic PETG @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Creality", - "inherits": "fdm_filament_pet", "renamed_from": "Creality Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "B8lWG3jJQ4ar4j70", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Creality/filament/Generic PETG-CF @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PETG-CF @Creality Hi-all.json index 5049c12c57..bf246e0b8d 100644 --- a/resources/profiles/Creality/filament/Generic PETG-CF @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PETG-CF @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Creality Hi-all", - "inherits": "Generic PETG @Creality Hi-all", "renamed_from": "Creality Generic PETG-CF @Hi-all;Creality Generic PETG-CF Hi-all", + "inherits": "Generic PETG @Creality Hi-all", "from": "system", "setting_id": "dWEGZoSVFzj7e9m1", "filament_id": "OFoYSJKi", diff --git a/resources/profiles/Creality/filament/Generic PLA @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic PLA @Creality Ender-3V3-all.json index 3c2e7de2ed..7882700836 100644 --- a/resources/profiles/Creality/filament/Generic PLA @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic PLA @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Creality Ender-3V3-all", - "inherits": "Generic PLA @Creality", "renamed_from": "Creality Generic PLA @Ender-3V3-all;Creality Generic PLA Ender-3V3-all", + "inherits": "Generic PLA @Creality", "from": "system", "setting_id": "uGq3aWYUI2sLJORU", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PLA @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PLA @Creality K1-all.json index ac6f727f02..725d4bbb18 100644 --- a/resources/profiles/Creality/filament/Generic PLA @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PLA @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Creality K1-all", - "inherits": "Generic PLA @Creality", "renamed_from": "Creality Generic PLA @K1-all;Creality Generic PLA K1-all", + "inherits": "Generic PLA @Creality", "from": "system", "setting_id": "oO2HaneRPfqxNQsP", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PLA @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PLA @Creality K2-all.json index bf98b76c5a..125879698b 100644 --- a/resources/profiles/Creality/filament/Generic PLA @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PLA @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Creality K2-all", - "inherits": "Generic PLA @Creality", "renamed_from": "Creality Generic PLA @K2-all;Creality Generic PLA K2-all", + "inherits": "Generic PLA @Creality", "from": "system", "setting_id": "EC0PPocMp0c4O0dK", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PLA @Creality.json b/resources/profiles/Creality/filament/Generic PLA @Creality.json index 248ff78dcb..9ffb7083d7 100644 --- a/resources/profiles/Creality/filament/Generic PLA @Creality.json +++ b/resources/profiles/Creality/filament/Generic PLA @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Creality", - "inherits": "fdm_filament_pla", "renamed_from": "Creality Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "UNUCEjCpe1e4ICT9", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Creality/filament/Generic PLA HF @Creality.json b/resources/profiles/Creality/filament/Generic PLA HF @Creality.json index 235e113a59..84efc28eb7 100644 --- a/resources/profiles/Creality/filament/Generic PLA HF @Creality.json +++ b/resources/profiles/Creality/filament/Generic PLA HF @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Creality", - "inherits": "fdm_filament_pla", "renamed_from": "Creality HF Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "YXqIFmq63jGbN8aZ", "filament_id": "OFZr862X", diff --git a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Ender-3V3-all.json index 21d1029a5d..bd353acb91 100644 --- a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Creality Ender-3V3-all", - "inherits": "Generic PLA @Creality Ender-3V3-all", "renamed_from": "Creality Generic PLA High Speed @Ender-3V3-all;Creality Generic PLA High Speed Ender-3V3-all", + "inherits": "Generic PLA @Creality Ender-3V3-all", "from": "system", "setting_id": "MOH1B7U4Ipv8jw0s", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Hi-all.json index cb184a432a..c1e482601d 100644 --- a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Creality Hi-all", - "inherits": "Generic PLA @Creality Hi-all", "renamed_from": "Creality Generic PLA High Speed @Hi-all;Creality Generic PLA High Speed Hi-all", + "inherits": "Generic PLA @Creality Hi-all", "from": "system", "setting_id": "KJZ1ztg3jL2Cg4fi", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K1-all.json index c7b2bbb03a..26b8cb5669 100644 --- a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Creality K1-all", - "inherits": "Generic PLA @Creality K1-all", "renamed_from": "Creality Generic PLA High Speed @K1-all;Creality Generic PLA High Speed K1-all", + "inherits": "Generic PLA @Creality K1-all", "from": "system", "setting_id": "5HgGIzGuma2z6vD8", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K2-all.json index 9df651b17d..66d24a636e 100644 --- a/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PLA High Speed @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Creality K2-all", - "inherits": "Generic PLA @Creality K2-all", "renamed_from": "Creality Generic PLA High Speed @K2-all;Creality Generic PLA High Speed K2-all", + "inherits": "Generic PLA @Creality K2-all", "from": "system", "setting_id": "Lxp4EwuEZKFHZXWR", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Creality/filament/Generic PLA Matte @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic PLA Matte @Creality Ender-3V3-all.json index 2e561af6b5..660cc0a00d 100644 --- a/resources/profiles/Creality/filament/Generic PLA Matte @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Matte @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Matte @Creality Ender-3V3-all", - "inherits": "Generic PLA @Creality Ender-3V3-all", "renamed_from": "Creality Generic PLA Matte @Ender-3V3-all;Creality Generic PLA Matte Ender-3V3-all", + "inherits": "Generic PLA @Creality Ender-3V3-all", "from": "system", "setting_id": "JlvUB8GxzpAOlgkz", "filament_id": "OFmY0l6t", diff --git a/resources/profiles/Creality/filament/Generic PLA Matte @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PLA Matte @Creality Hi-all.json index 1cff84c8bf..8d2d699ae6 100644 --- a/resources/profiles/Creality/filament/Generic PLA Matte @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Matte @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Matte @Creality Hi-all", - "inherits": "Generic PLA @Creality Hi-all", "renamed_from": "Creality Generic PLA Matte @Hi-all;Creality Generic PLA Matte Hi-all", + "inherits": "Generic PLA @Creality Hi-all", "from": "system", "setting_id": "pFxJgjam0WAeSKqf", "filament_id": "OFmY0l6t", diff --git a/resources/profiles/Creality/filament/Generic PLA Matte @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PLA Matte @Creality K1-all.json index 2a584450f8..77249010d5 100644 --- a/resources/profiles/Creality/filament/Generic PLA Matte @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Matte @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Matte @Creality K1-all", - "inherits": "Generic PLA @Creality K1-all", "renamed_from": "Creality Generic PLA Matte @K1-all;Creality Generic PLA Matte K1-all", + "inherits": "Generic PLA @Creality K1-all", "from": "system", "setting_id": "JJRpJQcHUhelwD02", "filament_id": "OFmY0l6t", diff --git a/resources/profiles/Creality/filament/Generic PLA Matte @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PLA Matte @Creality K2-all.json index 27607938a5..373a18ac1b 100644 --- a/resources/profiles/Creality/filament/Generic PLA Matte @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Matte @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Matte @Creality K2-all", - "inherits": "Generic PLA @Creality K2-all", "renamed_from": "Creality Generic PLA Matte @K2-all;Creality Generic PLA Matte K2-all", + "inherits": "Generic PLA @Creality K2-all", "from": "system", "setting_id": "VVcXNl0Y6B0mLlrb", "filament_id": "OFmY0l6t", diff --git a/resources/profiles/Creality/filament/Generic PLA Silk @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic PLA Silk @Creality Ender-3V3-all.json index 1f528f79fb..d3c281ca9e 100644 --- a/resources/profiles/Creality/filament/Generic PLA Silk @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Silk @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Creality Ender-3V3-all", - "inherits": "Generic PLA @Creality Ender-3V3-all", "renamed_from": "Creality Generic PLA Silk @Ender-3V3-all;Creality Generic PLA Silk Ender-3V3-all", + "inherits": "Generic PLA @Creality Ender-3V3-all", "from": "system", "setting_id": "vPrmBiuBCC8843Jb", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Creality/filament/Generic PLA Silk @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PLA Silk @Creality Hi-all.json index 3358b98c75..3dd93ed1e9 100644 --- a/resources/profiles/Creality/filament/Generic PLA Silk @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Silk @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Creality Hi-all", - "inherits": "Generic PLA @Creality Hi-all", "renamed_from": "Creality Generic PLA Silk @Hi-all;Creality Generic PLA Silk Hi-all", + "inherits": "Generic PLA @Creality Hi-all", "from": "system", "setting_id": "k1ofgUXqhHGSPDPY", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Creality/filament/Generic PLA Silk @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PLA Silk @Creality K1-all.json index 4e8adb2b35..947f98b81c 100644 --- a/resources/profiles/Creality/filament/Generic PLA Silk @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Silk @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Creality K1-all", - "inherits": "Generic PLA @Creality K1-all", "renamed_from": "Creality Generic PLA Silk @K1-all;Creality Generic PLA Silk K1-all", + "inherits": "Generic PLA @Creality K1-all", "from": "system", "setting_id": "JcSq9nar8x5BjFss", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Creality/filament/Generic PLA Silk @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PLA Silk @Creality K2-all.json index 850ea2704b..aa2de4a0bc 100644 --- a/resources/profiles/Creality/filament/Generic PLA Silk @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Silk @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Creality K2-all", - "inherits": "Generic PLA @Creality K2-all", "renamed_from": "Creality Generic PLA Silk @K2-all;Creality Generic PLA Silk K2-all", + "inherits": "Generic PLA @Creality K2-all", "from": "system", "setting_id": "fRyhLWAQiCOaAxKA", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Creality/filament/Generic PLA Wood @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PLA Wood @Creality Hi-all.json index 62f6ddf42c..d42115e997 100644 --- a/resources/profiles/Creality/filament/Generic PLA Wood @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PLA Wood @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Wood @Creality Hi-all", - "inherits": "Generic PLA @Creality Hi-all", "renamed_from": "Creality Generic PLA Wood @Hi-all;Creality Generic PLA Wood Hi-all", + "inherits": "Generic PLA @Creality Hi-all", "from": "system", "setting_id": "PNqfF5ecYqqpobdh", "filament_id": "OFIKZxPF", diff --git a/resources/profiles/Creality/filament/Generic PLA-CF @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic PLA-CF @Creality Hi-all.json index 9bbc7a4433..20e6b62344 100644 --- a/resources/profiles/Creality/filament/Generic PLA-CF @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic PLA-CF @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Creality Hi-all", - "inherits": "Generic PLA-CF @Creality", "renamed_from": "Creality Generic PLA-CF @Hi-all;Creality Generic PLA-CF Hi-all", + "inherits": "Generic PLA-CF @Creality", "from": "system", "setting_id": "MH2pm9wTHLgX9fyq", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PLA-CF @Creality K1-all.json b/resources/profiles/Creality/filament/Generic PLA-CF @Creality K1-all.json index 2e3ed94cb7..5ff14bf8fd 100644 --- a/resources/profiles/Creality/filament/Generic PLA-CF @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic PLA-CF @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Creality K1-all", - "inherits": "Generic PLA-CF @Creality", "renamed_from": "Creality Generic PLA-CF @K1-all;Creality Generic PLA-CF K1-all", + "inherits": "Generic PLA-CF @Creality", "from": "system", "setting_id": "DoyvqW51z3o1vBSa", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PLA-CF @Creality K2-all.json b/resources/profiles/Creality/filament/Generic PLA-CF @Creality K2-all.json index 4cc99c0ff5..e910381ac8 100644 --- a/resources/profiles/Creality/filament/Generic PLA-CF @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic PLA-CF @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Creality K2-all", - "inherits": "Generic PLA-CF @Creality", "renamed_from": "Creality Generic PLA-CF @K2-all;Creality Generic PLA-CF K2-all", + "inherits": "Generic PLA-CF @Creality", "from": "system", "setting_id": "6KqkLBBYBA59h5TA", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic PLA-CF @Creality.json b/resources/profiles/Creality/filament/Generic PLA-CF @Creality.json index e35a839035..b18e953e9b 100644 --- a/resources/profiles/Creality/filament/Generic PLA-CF @Creality.json +++ b/resources/profiles/Creality/filament/Generic PLA-CF @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Creality", - "inherits": "fdm_filament_pla", "renamed_from": "Creality Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "Fn5Z3ccrrRYFkiwT", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Creality/filament/Generic Speed PLA @Creality HF.json b/resources/profiles/Creality/filament/Generic Speed PLA @Creality HF.json index 80e07cfff0..b9f4ef02b3 100644 --- a/resources/profiles/Creality/filament/Generic Speed PLA @Creality HF.json +++ b/resources/profiles/Creality/filament/Generic Speed PLA @Creality HF.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic Speed PLA @Creality HF", - "inherits": "fdm_filament_pla", "renamed_from": "Creality HF Generic Speed PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "pklu1YSwmDOj6gRq", "filament_id": "OFXmv5p0", diff --git a/resources/profiles/Creality/filament/Generic TPU @Creality Ender-3V3-all.json b/resources/profiles/Creality/filament/Generic TPU @Creality Ender-3V3-all.json index 80d3316a76..9ccaba5c4b 100644 --- a/resources/profiles/Creality/filament/Generic TPU @Creality Ender-3V3-all.json +++ b/resources/profiles/Creality/filament/Generic TPU @Creality Ender-3V3-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Creality Ender-3V3-all", - "inherits": "Generic TPU @Creality", "renamed_from": "Creality Generic TPU @Ender-3V3-all;Creality Generic TPU Ender-3V3-all", + "inherits": "Generic TPU @Creality", "from": "system", "setting_id": "ZufJdJseoFNQC66B", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic TPU @Creality Hi-all.json b/resources/profiles/Creality/filament/Generic TPU @Creality Hi-all.json index 1a46bfc0b5..c53515566a 100644 --- a/resources/profiles/Creality/filament/Generic TPU @Creality Hi-all.json +++ b/resources/profiles/Creality/filament/Generic TPU @Creality Hi-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Creality Hi-all", - "inherits": "Generic TPU @Creality", "renamed_from": "Creality Generic TPU @Hi-all;Creality Generic TPU Hi-all", + "inherits": "Generic TPU @Creality", "from": "system", "setting_id": "P42mcGCETNdcZchS", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic TPU @Creality K1-all.json b/resources/profiles/Creality/filament/Generic TPU @Creality K1-all.json index d2cd19bb7c..5474080ad8 100644 --- a/resources/profiles/Creality/filament/Generic TPU @Creality K1-all.json +++ b/resources/profiles/Creality/filament/Generic TPU @Creality K1-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Creality K1-all", - "inherits": "Generic TPU @Creality", "renamed_from": "Creality Generic TPU @K1-all;Creality Generic TPU K1-all", + "inherits": "Generic TPU @Creality", "from": "system", "setting_id": "7zTgnS8bIEkkhqtB", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic TPU @Creality K2-all.json b/resources/profiles/Creality/filament/Generic TPU @Creality K2-all.json index 9a8896ea23..f1d34a4ec7 100644 --- a/resources/profiles/Creality/filament/Generic TPU @Creality K2-all.json +++ b/resources/profiles/Creality/filament/Generic TPU @Creality K2-all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Creality K2-all", - "inherits": "Generic TPU @Creality", "renamed_from": "Creality Generic TPU @K2-all;Creality Generic TPU K2-all", + "inherits": "Generic TPU @Creality", "from": "system", "setting_id": "C9PAmCIDhCAthMuK", "instantiation": "true", diff --git a/resources/profiles/Creality/filament/Generic TPU @Creality.json b/resources/profiles/Creality/filament/Generic TPU @Creality.json index af863c3893..9edbfc1265 100644 --- a/resources/profiles/Creality/filament/Generic TPU @Creality.json +++ b/resources/profiles/Creality/filament/Generic TPU @Creality.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Creality", - "inherits": "fdm_filament_tpu", "renamed_from": "Creality Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "eCzlxPg3piTZEui4", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 KE-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 KE-all.json index 0df433e3db..48af68fefe 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 KE-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 KE-all.json @@ -1,120 +1,120 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @Ender-3 V3 KE-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "eQu3UILWB8OQPf1X", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_max_volumetric_speed": [ - "9" - ], - "filament_retract_before_wipe": [ - "70%" - ], - "filament_retraction_length": [ - "0.8" - ], - "filament_retraction_minimum_travel": [ - "2" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "1" - ], - "filament_z_hop": [ - "0.4" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "240" - ], - "nozzle_temperature_initial_layer": [ - "240" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[1.0,230],[1.2,230],[1.3,240]]", - "pressure_advance": "0.09", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality Ender-3 V3 KE 0.4 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @Ender-3 V3 KE-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "eQu3UILWB8OQPf1X", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_max_volumetric_speed": [ + "9" + ], + "filament_retract_before_wipe": [ + "70%" + ], + "filament_retraction_length": [ + "0.8" + ], + "filament_retraction_minimum_travel": [ + "2" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop": [ + "0.4" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[1.0,230],[1.2,230],[1.3,240]]", + "pressure_advance": "0.09", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality Ender-3 V3 KE 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 Plus-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 Plus-all.json index cfcaf8dcd4..f6942dfe46 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 Plus-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 Plus-all.json @@ -1,122 +1,122 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @Ender-3 V3 Plus-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "uYReKb57FZWbcn66", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "90" - ], - "fan_min_speed": [ - "80" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "70%" - ], - "filament_retraction_length": [ - "1.2" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "1" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "240" - ], - "nozzle_temperature_initial_layer": [ - "240" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "14" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,220],[1.0,220],[1.2,240]]", - "pressure_advance": "0.076", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality Ender-3 V3 Plus 0.4 nozzle", - "Creality Ender-3 V3 Plus 0.6 nozzle", - "Creality Ender-3 V3 Plus 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @Ender-3 V3 Plus-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "uYReKb57FZWbcn66", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "90" + ], + "fan_min_speed": [ + "80" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "70%" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "1" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "14" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,220],[1.0,220],[1.2,240]]", + "pressure_advance": "0.076", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality Ender-3 V3 Plus 0.4 nozzle", + "Creality Ender-3 V3 Plus 0.6 nozzle", + "Creality Ender-3 V3 Plus 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 SE-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 SE-all.json index 07826b7931..3d934dc95b 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 SE-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3 SE-all.json @@ -1,105 +1,105 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @Ender-3 V3 SE-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "IkpZHqKxz3D4DM8n", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_retraction_length": [ - "1.2" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "240" - ], - "nozzle_temperature_initial_layer": [ - "240" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,230],[1.0,230],[1.2,240]]", - "pressure_advance": "0.02", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality Ender-3 V3 SE 0.4 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @Ender-3 V3 SE-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "IkpZHqKxz3D4DM8n", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,230],[1.0,230],[1.2,240]]", + "pressure_advance": "0.02", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality Ender-3 V3 SE 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3-all.json index 6cb9b5389d..ba387ef37f 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @Ender-3 V3-all.json @@ -1,119 +1,119 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @Ender-3 V3-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "VFPEq8OL7ibFlpNn", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "90" - ], - "fan_min_speed": [ - "80" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "30" - ], - "filament_flow_ratio": [ - "0.99" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retraction_length": [ - "1.2" - ], - "filament_retraction_speed": [ - "30" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "1.5" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "240" - ], - "nozzle_temperature_initial_layer": [ - "240" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "14" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,220],[1.0,220],[1.2,240]]", - "pressure_advance": "0.076", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality Ender-3 V3 0.4 nozzle", - "Creality Ender-3 V3 0.6 nozzle", - "Creality Ender-3 V3 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @Ender-3 V3-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "VFPEq8OL7ibFlpNn", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "90" + ], + "fan_min_speed": [ + "80" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.99" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_retraction_speed": [ + "30" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "1.5" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "14" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,220],[1.0,220],[1.2,240]]", + "pressure_advance": "0.076", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality Ender-3 V3 0.4 nozzle", + "Creality Ender-3 V3 0.6 nozzle", + "Creality Ender-3 V3 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @Hi-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @Hi-all.json index 1e77a28ccf..06a6706eeb 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @Hi-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @Hi-all.json @@ -1,127 +1,127 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @Hi-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "sUalM5HH0sDpMOmD", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "80" - ], - "cool_plate_temp_initial_layer": [ - "80" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "80" - ], - "eng_plate_temp_initial_layer": [ - "80" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "60" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "30" - ], - "filament_flow_ratio": [ - "0.96" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "90%" - ], - "filament_retraction_length": [ - "0.4" - ], - "filament_retraction_minimum_travel": [ - "2" - ], - "filament_retraction_speed": [ - "30" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "filament_z_hop_types": [ - "Slope Lift" - ], - "hot_plate_temp": [ - "80" - ], - "hot_plate_temp_initial_layer": [ - "80" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "20" - ], - "textured_plate_temp": [ - "80" - ], - "textured_plate_temp_initial_layer": [ - "80" - ], - "customized_plate_temp": "80", - "customized_plate_temp_initial_layer": "80", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "70", - "epoxy_resin_plate_temp_initial_layer": "70", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.6,220],[1.4,220],[1.7,250]]", - "pressure_advance": "0.06", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality Hi 0.4 nozzle", - "Creality Hi 0.6 nozzle", - "Creality Hi 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @Hi-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "sUalM5HH0sDpMOmD", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "80" + ], + "cool_plate_temp_initial_layer": [ + "80" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "80" + ], + "eng_plate_temp_initial_layer": [ + "80" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.96" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "90%" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_retraction_minimum_travel": [ + "2" + ], + "filament_retraction_speed": [ + "30" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "filament_z_hop_types": [ + "Slope Lift" + ], + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20" + ], + "textured_plate_temp": [ + "80" + ], + "textured_plate_temp_initial_layer": [ + "80" + ], + "customized_plate_temp": "80", + "customized_plate_temp_initial_layer": "80", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "70", + "epoxy_resin_plate_temp_initial_layer": "70", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.6,220],[1.4,220],[1.7,250]]", + "pressure_advance": "0.06", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality Hi 0.4 nozzle", + "Creality Hi 0.6 nozzle", + "Creality Hi 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @K1C-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @K1C-all.json index 626d34362d..267939fa6b 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @K1C-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @K1C-all.json @@ -1,130 +1,130 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @K1C-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "RHcExN6yUArn3nky", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "80" - ], - "cool_plate_temp": [ - "80" - ], - "cool_plate_temp_initial_layer": [ - "80" - ], - "during_print_exhaust_fan_speed": [ - "60" - ], - "eng_plate_temp": [ - "80" - ], - "eng_plate_temp_initial_layer": [ - "80" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "30" - ], - "filament_flow_ratio": [ - "0.97" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "90%" - ], - "filament_retraction_length": [ - "0.4" - ], - "filament_retraction_minimum_travel": [ - "2" - ], - "filament_retraction_speed": [ - "30" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "filament_z_hop_types": [ - "Slope Lift" - ], - "hot_plate_temp": [ - "80" - ], - "hot_plate_temp_initial_layer": [ - "80" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "20" - ], - "textured_plate_temp": [ - "80" - ], - "textured_plate_temp_initial_layer": [ - "80" - ], - "customized_plate_temp": "80", - "customized_plate_temp_initial_layer": "80", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "70", - "epoxy_resin_plate_temp_initial_layer": "70", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.8,220], [1.2,220], [1.3,250]]", - "pressure_advance": "0.054", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K1C 0.4 nozzle", - "Creality K1C 0.6 nozzle", - "Creality K1C 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @K1C-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "RHcExN6yUArn3nky", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "80" + ], + "cool_plate_temp": [ + "80" + ], + "cool_plate_temp_initial_layer": [ + "80" + ], + "during_print_exhaust_fan_speed": [ + "60" + ], + "eng_plate_temp": [ + "80" + ], + "eng_plate_temp_initial_layer": [ + "80" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.97" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "90%" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_retraction_minimum_travel": [ + "2" + ], + "filament_retraction_speed": [ + "30" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "filament_z_hop_types": [ + "Slope Lift" + ], + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20" + ], + "textured_plate_temp": [ + "80" + ], + "textured_plate_temp_initial_layer": [ + "80" + ], + "customized_plate_temp": "80", + "customized_plate_temp_initial_layer": "80", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "70", + "epoxy_resin_plate_temp_initial_layer": "70", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.8,220], [1.2,220], [1.3,250]]", + "pressure_advance": "0.054", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K1C 0.4 nozzle", + "Creality K1C 0.6 nozzle", + "Creality K1C 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Plus-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Plus-all.json index 8d1dc8a1c0..35ffc576d4 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Plus-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Plus-all.json @@ -1,132 +1,132 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @K2 Plus-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "w8SHt6Slm8uIqTbh", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_flow_ratio": [ - "0.98" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "90%" - ], - "filament_retraction_minimum_travel": [ - "1" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "filament_z_hop_types": [ - "Slope Lift" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "250" - ], - "nozzle_temperature_range_low": [ - "230" - ], - "overhang_fan_speed": [ - "80" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "20" - ], - "temperature_vitrification": [ - "80" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "activate_chamber_temp_control": "1", - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,230],[1.2,230],[1.2,250]]", - "pressure_advance": "0.074", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Plus 0.4 nozzle", - "Creality K2 Plus 0.6 nozzle", - "Creality K2 Plus 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @K2 Plus-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "w8SHt6Slm8uIqTbh", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "90%" + ], + "filament_retraction_minimum_travel": [ + "1" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "filament_z_hop_types": [ + "Slope Lift" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20" + ], + "temperature_vitrification": [ + "80" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "activate_chamber_temp_control": "1", + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,230],[1.2,230],[1.2,250]]", + "pressure_advance": "0.074", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Plus 0.4 nozzle", + "Creality K2 Plus 0.6 nozzle", + "Creality K2 Plus 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Pro-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Pro-all.json index fca00e01ab..c2d411ef34 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Pro-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @K2 Pro-all.json @@ -1,132 +1,132 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @K2 Pro-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "vI7ThHCwOBfts0NQ", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "90%" - ], - "filament_retraction_minimum_travel": [ - "1" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "filament_z_hop_types": [ - "Slope Lift" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "250" - ], - "nozzle_temperature_range_low": [ - "230" - ], - "overhang_fan_speed": [ - "80" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "20" - ], - "temperature_vitrification": [ - "80" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "activate_chamber_temp_control": "1", - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,220],[1.2,220],[1.2,250]]", - "pressure_advance": "0.08", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Pro 0.4 nozzle", - "Creality K2 Pro 0.6 nozzle", - "Creality K2 Pro 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @K2 Pro-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "vI7ThHCwOBfts0NQ", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "90%" + ], + "filament_retraction_minimum_travel": [ + "1" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "filament_z_hop_types": [ + "Slope Lift" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20" + ], + "temperature_vitrification": [ + "80" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "activate_chamber_temp_control": "1", + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,220],[1.2,220],[1.2,250]]", + "pressure_advance": "0.08", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Pro 0.4 nozzle", + "Creality K2 Pro 0.6 nozzle", + "Creality K2 Pro 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @K2-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @K2-all.json index da86d9e27e..c244600091 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @K2-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @K2-all.json @@ -1,132 +1,132 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @K2-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "nqr9TMlkS8nLVGhG", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "90%" - ], - "filament_retraction_minimum_travel": [ - "1" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "filament_z_hop_types": [ - "Slope Lift" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "250" - ], - "nozzle_temperature_range_low": [ - "230" - ], - "overhang_fan_speed": [ - "80" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "20" - ], - "temperature_vitrification": [ - "80" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "activate_chamber_temp_control": "1", - "chamber_temperature": "35", - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,230],[1.2,230],[1.2,250]]", - "pressure_advance": "0.08", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 0.4 nozzle", - "Creality K2 0.6 nozzle", - "Creality K2 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @K2-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "nqr9TMlkS8nLVGhG", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "90%" + ], + "filament_retraction_minimum_travel": [ + "1" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "filament_z_hop_types": [ + "Slope Lift" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20" + ], + "temperature_vitrification": [ + "80" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "activate_chamber_temp_control": "1", + "chamber_temperature": "35", + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,230],[1.2,230],[1.2,250]]", + "pressure_advance": "0.08", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 0.4 nozzle", + "Creality K2 0.6 nozzle", + "Creality K2 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @SPARKX i7-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @SPARKX i7-all.json index 79b83b8e69..b3b56aab4b 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @SPARKX i7-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @SPARKX i7-all.json @@ -1,122 +1,122 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @SPARKX i7-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "yWR45TQhsN5eYgCu", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "80" - ], - "cool_plate_temp_initial_layer": [ - "80" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "80" - ], - "eng_plate_temp_initial_layer": [ - "80" - ], - "fan_cooling_layer_time": [ - "80" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_flow_ratio": [ - "0.98" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_retract_before_wipe": [ - "100%" - ], - "filament_retraction_minimum_travel": [ - "2" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "hot_plate_temp": [ - "80" - ], - "hot_plate_temp_initial_layer": [ - "80" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "250" - ], - "nozzle_temperature_range_low": [ - "230" - ], - "overhang_fan_speed": [ - "80" - ], - "overhang_fan_threshold": [ - "25%" - ], - "slow_down_layer_time": [ - "14" - ], - "slow_down_min_speed": [ - "20" - ], - "temperature_vitrification": [ - "90" - ], - "textured_plate_temp": [ - "80" - ], - "textured_plate_temp_initial_layer": [ - "80" - ], - "customized_plate_temp": "80", - "customized_plate_temp_initial_layer": "80", - "enable_pressure_advance": "1", - "epoxy_resin_plate_temp": "70", - "epoxy_resin_plate_temp_initial_layer": "70", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.6,240],[1.2,250]]", - "pressure_advance": "0.054", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality SPARKX i7 0.4 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @SPARKX i7-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "yWR45TQhsN5eYgCu", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "80" + ], + "cool_plate_temp_initial_layer": [ + "80" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "80" + ], + "eng_plate_temp_initial_layer": [ + "80" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_retract_before_wipe": [ + "100%" + ], + "filament_retraction_minimum_travel": [ + "2" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "14" + ], + "slow_down_min_speed": [ + "20" + ], + "temperature_vitrification": [ + "90" + ], + "textured_plate_temp": [ + "80" + ], + "textured_plate_temp_initial_layer": [ + "80" + ], + "customized_plate_temp": "80", + "customized_plate_temp_initial_layer": "80", + "enable_pressure_advance": "1", + "epoxy_resin_plate_temp": "70", + "epoxy_resin_plate_temp_initial_layer": "70", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.6,240],[1.2,250]]", + "pressure_advance": "0.054", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality SPARKX i7 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/Soleyin Basic PETG @Sermoon M300-all.json b/resources/profiles/Creality/filament/Soleyin Basic PETG @Sermoon M300-all.json index ee7263427c..52f0f070bb 100644 --- a/resources/profiles/Creality/filament/Soleyin Basic PETG @Sermoon M300-all.json +++ b/resources/profiles/Creality/filament/Soleyin Basic PETG @Sermoon M300-all.json @@ -1,124 +1,124 @@ { - "type": "filament", - "name": "Soleyin Basic PETG @Sermoon M300-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "oKRNh6oI0CNy6guE", - "instantiation": "true", - "complete_print_exhaust_fan_speed": [ - "0" - ], - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "15.9" - ], - "filament_density": [ - "1.25" - ], - "filament_deretraction_speed": [ - "40" - ], - "filament_flow_ratio": [ - "0.97" - ], - "filament_max_volumetric_speed": [ - "16" - ], - "filament_retract_before_wipe": [ - "90%" - ], - "filament_retraction_minimum_travel": [ - "1" - ], - "filament_retraction_speed": [ - "40" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "Creality" - ], - "filament_wipe_distance": [ - "2" - ], - "filament_z_hop_types": [ - "Slope Lift" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "nozzle_temperature_range_low": [ - "220" - ], - "overhang_fan_speed": [ - "80" - ], - "overhang_fan_threshold": [ - "25%" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "20" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "enable_pressure_advance": "0", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "filament_retract_lift_above": "nil", - "filament_retract_lift_below": "nil", - "filament_retract_lift_enforce": "nil", - "material_flow_temp_graph": "[[0.5,230],[1.0,230],[1.2,250]]", - "pressure_advance": "0.075", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality Sermoon M300 0.4 nozzle", - "Creality Sermoon M300 0.6 nozzle", - "Creality Sermoon M300 0.8 nozzle" - ], - "filament_id": "OFBLktDy" -} \ No newline at end of file + "type": "filament", + "name": "Soleyin Basic PETG @Sermoon M300-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "oKRNh6oI0CNy6guE", + "filament_id": "OFBLktDy", + "instantiation": "true", + "complete_print_exhaust_fan_speed": [ + "0" + ], + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "during_print_exhaust_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "15.9" + ], + "filament_density": [ + "1.25" + ], + "filament_deretraction_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.97" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retract_before_wipe": [ + "90%" + ], + "filament_retraction_minimum_travel": [ + "1" + ], + "filament_retraction_speed": [ + "40" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "Creality" + ], + "filament_wipe_distance": [ + "2" + ], + "filament_z_hop_types": [ + "Slope Lift" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_speed": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "enable_pressure_advance": "0", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "filament_retract_lift_above": "nil", + "filament_retract_lift_below": "nil", + "filament_retract_lift_enforce": "nil", + "material_flow_temp_graph": "[[0.5,230],[1.0,230],[1.2,250]]", + "pressure_advance": "0.075", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality Sermoon M300 0.4 nozzle", + "Creality Sermoon M300 0.6 nozzle", + "Creality Sermoon M300 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/eSUN PETG @K2 Plus-all.json b/resources/profiles/Creality/filament/eSUN PETG @K2 Plus-all.json index 745ca87011..dfc4bb69a7 100644 --- a/resources/profiles/Creality/filament/eSUN PETG @K2 Plus-all.json +++ b/resources/profiles/Creality/filament/eSUN PETG @K2 Plus-all.json @@ -1,87 +1,87 @@ { - "type": "filament", - "name": "eSUN PETG @K2 Plus-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "BHCutIIr9w5Lg1DM", - "instantiation": "true", - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "22" - ], - "filament_density": [ - "1.27" - ], - "filament_flow_ratio": [ - "0.98" - ], - "filament_max_volumetric_speed": [ - "5" - ], - "filament_retract_before_wipe": [ - "70%" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "eSUN" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "255" - ], - "nozzle_temperature_initial_layer": [ - "255" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" - ], - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "pressure_advance": "0.1", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Plus 0.4 nozzle" - ], - "filament_id": "OF3kBrdA" -} \ No newline at end of file + "type": "filament", + "name": "eSUN PETG @K2 Plus-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "BHCutIIr9w5Lg1DM", + "filament_id": "OF3kBrdA", + "instantiation": "true", + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "22" + ], + "filament_density": [ + "1.27" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_max_volumetric_speed": [ + "5" + ], + "filament_retract_before_wipe": [ + "70%" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "eSUN" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "255" + ], + "nozzle_temperature_initial_layer": [ + "255" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" + ], + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "pressure_advance": "0.1", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Plus 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/eSUN PETG+HS @K2 Plus-all.json b/resources/profiles/Creality/filament/eSUN PETG+HS @K2 Plus-all.json index db95688083..8862af8bdf 100644 --- a/resources/profiles/Creality/filament/eSUN PETG+HS @K2 Plus-all.json +++ b/resources/profiles/Creality/filament/eSUN PETG+HS @K2 Plus-all.json @@ -1,84 +1,84 @@ { - "type": "filament", - "name": "eSUN PETG+HS @K2 Plus-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "2hnUQwzB9vx9ZUOG", - "instantiation": "true", - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "22" - ], - "filament_density": [ - "1.26" - ], - "filament_max_volumetric_speed": [ - "7" - ], - "filament_retract_before_wipe": [ - "70%" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "eSUN" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" - ], - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "pressure_advance": "0.1", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Plus 0.4 nozzle" - ], - "filament_id": "OFrdZ0cK" -} \ No newline at end of file + "type": "filament", + "name": "eSUN PETG+HS @K2 Plus-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "2hnUQwzB9vx9ZUOG", + "filament_id": "OFrdZ0cK", + "instantiation": "true", + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "22" + ], + "filament_density": [ + "1.26" + ], + "filament_max_volumetric_speed": [ + "7" + ], + "filament_retract_before_wipe": [ + "70%" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "eSUN" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" + ], + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "pressure_advance": "0.1", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Plus 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/eSUN PETG-Basic @K2 Plus-all.json b/resources/profiles/Creality/filament/eSUN PETG-Basic @K2 Plus-all.json index 4885eb89a0..df6a63898a 100644 --- a/resources/profiles/Creality/filament/eSUN PETG-Basic @K2 Plus-all.json +++ b/resources/profiles/Creality/filament/eSUN PETG-Basic @K2 Plus-all.json @@ -1,87 +1,87 @@ { - "type": "filament", - "name": "eSUN PETG-Basic @K2 Plus-all", - "inherits": "fdm_filament_petg", - "from": "system", - "setting_id": "YxOoppTAD5GAFwyM", - "instantiation": "true", - "cool_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "80" - ], - "fan_min_speed": [ - "40" - ], - "filament_cost": [ - "22" - ], - "filament_density": [ - "1.27" - ], - "filament_flow_ratio": [ - "0.98" - ], - "filament_max_volumetric_speed": [ - "8" - ], - "filament_retract_before_wipe": [ - "70%" - ], - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "eSUN" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "250" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" - ], - "customized_plate_temp": "70", - "customized_plate_temp_initial_layer": "70", - "epoxy_resin_plate_temp": "60", - "epoxy_resin_plate_temp_initial_layer": "60", - "pressure_advance": "0.1", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Plus 0.4 nozzle" - ], - "filament_id": "OFFbQscs" -} \ No newline at end of file + "type": "filament", + "name": "eSUN PETG-Basic @K2 Plus-all", + "inherits": "fdm_filament_petg", + "from": "system", + "setting_id": "YxOoppTAD5GAFwyM", + "filament_id": "OFFbQscs", + "instantiation": "true", + "cool_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "40" + ], + "filament_cost": [ + "22" + ], + "filament_density": [ + "1.27" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "filament_retract_before_wipe": [ + "70%" + ], + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "eSUN" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" + ], + "customized_plate_temp": "70", + "customized_plate_temp_initial_layer": "70", + "epoxy_resin_plate_temp": "60", + "epoxy_resin_plate_temp_initial_layer": "60", + "pressure_advance": "0.1", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Plus 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/eSUN PLA-CF @K2 Plus-all.json b/resources/profiles/Creality/filament/eSUN PLA-CF @K2 Plus-all.json index e76dc3d1fa..11b8d9448e 100644 --- a/resources/profiles/Creality/filament/eSUN PLA-CF @K2 Plus-all.json +++ b/resources/profiles/Creality/filament/eSUN PLA-CF @K2 Plus-all.json @@ -1,78 +1,78 @@ { - "type": "filament", - "name": "eSUN PLA-CF @K2 Plus-all", - "inherits": "fdm_filament_pla", - "from": "system", - "setting_id": "DYF2ppm40yQWEtnp", - "instantiation": "true", - "additional_cooling_fan_speed": [ - "80" - ], - "cool_plate_temp": [ - "50" - ], - "cool_plate_temp_initial_layer": [ - "50" - ], - "filament_cost": [ - "28" - ], - "filament_density": [ - "1.21" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "11" - ], - "filament_retract_before_wipe": [ - "100" - ], - "filament_retraction_length": [ - "1.2" - ], - "filament_type": [ - "PLA-CF" - ], - "filament_vendor": [ - "eSUN" - ], - "hot_plate_temp": [ - "50" - ], - "hot_plate_temp_initial_layer": [ - "50" - ], - "nozzle_temperature": [ - "230" - ], - "nozzle_temperature_initial_layer": [ - "230" - ], - "slow_down_layer_time": [ - "6" - ], - "slow_down_min_speed": [ - "20" - ], - "textured_plate_temp": [ - "50" - ], - "textured_plate_temp_initial_layer": [ - "50" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" - ], - "customized_plate_temp": "50", - "customized_plate_temp_initial_layer": "50", - "epoxy_resin_plate_temp": "40", - "epoxy_resin_plate_temp_initial_layer": "40", - "pressure_advance": "0.04", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Plus 0.4 nozzle" - ], - "filament_id": "OFnHc3D6" -} \ No newline at end of file + "type": "filament", + "name": "eSUN PLA-CF @K2 Plus-all", + "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "DYF2ppm40yQWEtnp", + "filament_id": "OFnHc3D6", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "80" + ], + "cool_plate_temp": [ + "50" + ], + "cool_plate_temp_initial_layer": [ + "50" + ], + "filament_cost": [ + "28" + ], + "filament_density": [ + "1.21" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "11" + ], + "filament_retract_before_wipe": [ + "100" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_type": [ + "PLA-CF" + ], + "filament_vendor": [ + "eSUN" + ], + "hot_plate_temp": [ + "50" + ], + "hot_plate_temp_initial_layer": [ + "50" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "20" + ], + "textured_plate_temp": [ + "50" + ], + "textured_plate_temp_initial_layer": [ + "50" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" + ], + "customized_plate_temp": "50", + "customized_plate_temp_initial_layer": "50", + "epoxy_resin_plate_temp": "40", + "epoxy_resin_plate_temp_initial_layer": "40", + "pressure_advance": "0.04", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Plus 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/eSUN PLA-HS @K2 Plus-all.json b/resources/profiles/Creality/filament/eSUN PLA-HS @K2 Plus-all.json index 0c540de90b..5acf20e255 100644 --- a/resources/profiles/Creality/filament/eSUN PLA-HS @K2 Plus-all.json +++ b/resources/profiles/Creality/filament/eSUN PLA-HS @K2 Plus-all.json @@ -1,69 +1,69 @@ { - "type": "filament", - "name": "eSUN PLA-HS @K2 Plus-all", - "inherits": "fdm_filament_pla", - "from": "system", - "setting_id": "lJaXWbmrBmg87yhI", - "instantiation": "true", - "additional_cooling_fan_speed": [ - "80" - ], - "cool_plate_temp": [ - "50" - ], - "cool_plate_temp_initial_layer": [ - "50" - ], - "filament_cost": [ - "25" - ], - "filament_density": [ - "1.25" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "18" - ], - "filament_retract_before_wipe": [ - "100" - ], - "filament_retraction_length": [ - "1.2" - ], - "filament_vendor": [ - "eSUN" - ], - "hot_plate_temp": [ - "50" - ], - "hot_plate_temp_initial_layer": [ - "50" - ], - "slow_down_layer_time": [ - "6" - ], - "slow_down_min_speed": [ - "20" - ], - "textured_plate_temp": [ - "50" - ], - "textured_plate_temp_initial_layer": [ - "50" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" - ], - "customized_plate_temp": "50", - "customized_plate_temp_initial_layer": "50", - "epoxy_resin_plate_temp": "40", - "epoxy_resin_plate_temp_initial_layer": "40", - "pressure_advance": "0.04", - "default_filament_colour": "\"\"", - "compatible_printers": [ - "Creality K2 Plus 0.4 nozzle" - ], - "filament_id": "OFOHOf2F" -} \ No newline at end of file + "type": "filament", + "name": "eSUN PLA-HS @K2 Plus-all", + "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "lJaXWbmrBmg87yhI", + "filament_id": "OFOHOf2F", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "80" + ], + "cool_plate_temp": [ + "50" + ], + "cool_plate_temp_initial_layer": [ + "50" + ], + "filament_cost": [ + "25" + ], + "filament_density": [ + "1.25" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retract_before_wipe": [ + "100" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_vendor": [ + "eSUN" + ], + "hot_plate_temp": [ + "50" + ], + "hot_plate_temp_initial_layer": [ + "50" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "20" + ], + "textured_plate_temp": [ + "50" + ], + "textured_plate_temp_initial_layer": [ + "50" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (layer_z > first_layer_height) }\nM104 S[nozzle_temperature]\n{else} \nM104 S[first_layer_temperature]\n{endif}" + ], + "customized_plate_temp": "50", + "customized_plate_temp_initial_layer": "50", + "epoxy_resin_plate_temp": "40", + "epoxy_resin_plate_temp_initial_layer": "40", + "pressure_advance": "0.04", + "default_filament_colour": "\"\"", + "compatible_printers": [ + "Creality K2 Plus 0.4 nozzle" + ] +} diff --git a/resources/profiles/Creality/filament/fdm_filament_hips.json b/resources/profiles/Creality/filament/fdm_filament_hips.json index c1de1560e8..a65b1977b9 100644 --- a/resources/profiles/Creality/filament/fdm_filament_hips.json +++ b/resources/profiles/Creality/filament/fdm_filament_hips.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "fdm_filament_hips", + "from": "system", "instantiation": "false", "close_fan_the_first_x_layers": [ "3" @@ -137,7 +138,6 @@ "filament_end_gcode": [ "; filament end gcode \n" ], - "from": "system", "filament_adhesiveness_category": [ "798" ], diff --git a/resources/profiles/Creality/filament/fdm_filament_petg.json b/resources/profiles/Creality/filament/fdm_filament_petg.json index c99fcf9b4e..0dcde20293 100644 --- a/resources/profiles/Creality/filament/fdm_filament_petg.json +++ b/resources/profiles/Creality/filament/fdm_filament_petg.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "fdm_filament_petg", + "from": "system", "instantiation": "false", "close_fan_the_first_x_layers": [ "3" @@ -137,7 +138,6 @@ "filament_end_gcode": [ "; filament end gcode \n" ], - "from": "system", "filament_adhesiveness_category": [ "300" ], diff --git a/resources/profiles/Creality/filament/fdm_filament_pp.json b/resources/profiles/Creality/filament/fdm_filament_pp.json index 6568654ba3..0624152b80 100644 --- a/resources/profiles/Creality/filament/fdm_filament_pp.json +++ b/resources/profiles/Creality/filament/fdm_filament_pp.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "fdm_filament_pp", + "from": "system", "instantiation": "false", "close_fan_the_first_x_layers": [ "3" @@ -137,7 +138,6 @@ "filament_end_gcode": [ "; filament end gcode \n" ], - "from": "system", "filament_adhesiveness_category": [ "902" ], diff --git a/resources/profiles/Creality/filament/fdm_filament_pps.json b/resources/profiles/Creality/filament/fdm_filament_pps.json index 65be9d03f6..62be4e2d2b 100644 --- a/resources/profiles/Creality/filament/fdm_filament_pps.json +++ b/resources/profiles/Creality/filament/fdm_filament_pps.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "fdm_filament_pps", + "from": "system", "instantiation": "false", "close_fan_the_first_x_layers": [ "3" @@ -137,7 +138,6 @@ "filament_end_gcode": [ "; filament end gcode \n" ], - "from": "system", "filament_adhesiveness_category": [ "801" ], diff --git a/resources/profiles/Creality/filament/fdm_filament_pva.json b/resources/profiles/Creality/filament/fdm_filament_pva.json index ab1694031f..c0101e0c81 100644 --- a/resources/profiles/Creality/filament/fdm_filament_pva.json +++ b/resources/profiles/Creality/filament/fdm_filament_pva.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "fdm_filament_pva", + "from": "system", "instantiation": "false", "close_fan_the_first_x_layers": [ "3" @@ -137,7 +138,6 @@ "filament_end_gcode": [ "; filament end gcode \n" ], - "from": "system", "filament_adhesiveness_category": [ "704" ], diff --git a/resources/profiles/Creality/machine/Creality CR-10 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality CR-10 0.4 nozzle.json index 5da636490c..014578b914 100644 --- a/resources/profiles/Creality/machine/Creality CR-10 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-10 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit
\nG1 E-2 Z1 F2400 ;Retract and raise Z
\nG1 X5 Y5 F3000 ;Wipe out
\nG1 Z10 ;Raise Z more
\nG90 ;Absolute positionning

\nG1 X0 Y0 ;Present print
\nM106 S0 ;Turn-off fan
\nM104 S0 ;Turn-off hotend
\nM140 S0 ;Turn-off bed

\nM84 X Y E ;Disable all steppers but Z
", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000,5000", - "machine_max_acceleration_extruding": "500,500", - "machine_max_acceleration_retracting": "500,1000", - "machine_max_acceleration_travel": "500,500", - "machine_max_acceleration_x": "500,500", - "machine_max_acceleration_y": "500,500", - "machine_max_acceleration_z": "500,500", - "machine_max_jerk_e": "5,5", - "machine_max_jerk_x": "10,8", - "machine_max_jerk_y": "10,8", - "machine_max_jerk_z": "0.4,0.4", - "machine_max_speed_e": "50,60", - "machine_max_speed_x": "500,500", - "machine_max_speed_y": "500,500", - "machine_max_speed_z": "10,10", + "machine_max_acceleration_e": ["5000,5000", "5000,5000"], + "machine_max_acceleration_extruding": ["500,500", "500,500"], + "machine_max_acceleration_retracting": ["500,1000", "500,1000"], + "machine_max_acceleration_travel": ["500,500", "500,500"], + "machine_max_acceleration_x": ["500,500", "500,500"], + "machine_max_acceleration_y": ["500,500", "500,500"], + "machine_max_acceleration_z": ["500,500", "500,500"], + "machine_max_jerk_e": ["5,5", "5,5"], + "machine_max_jerk_x": ["10,8", "10,8"], + "machine_max_jerk_y": ["10,8", "10,8"], + "machine_max_jerk_z": ["0.4,0.4", "0.4,0.4"], + "machine_max_speed_e": ["50,60", "50,60"], + "machine_max_speed_x": ["500,500", "500,500"], + "machine_max_speed_y": ["500,500", "500,500"], + "machine_max_speed_z": ["10,10", "10,10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25 ;pause print", diff --git a/resources/profiles/Creality/machine/Creality CR-10 Smart 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality CR-10 Smart 0.4 nozzle.json index f7d9b8167e..70c7b43293 100644 --- a/resources/profiles/Creality/machine/Creality CR-10 Smart 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-10 Smart 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit
\nG1 E-2 Z1 F2400 ;Retract and raise Z
\nG1 X5 Y5 F3000 ;Wipe out
\nG1 Z10 ;Raise Z more
\nG90 ;Absolute positionning

\nG1 X0 Y0 ;Present print
\nM106 S0 ;Turn-off fan
\nM104 S0 ;Turn-off hotend
\nM140 S0 ;Turn-off bed

\nM84 X Y E ;Disable all steppers but Z
", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000,5000", - "machine_max_acceleration_extruding": "500,500", - "machine_max_acceleration_retracting": "500,1000", - "machine_max_acceleration_travel": "500,500", - "machine_max_acceleration_x": "500,500", - "machine_max_acceleration_y": "500,500", - "machine_max_acceleration_z": "500,500", - "machine_max_jerk_e": "5,5", - "machine_max_jerk_x": "10,8", - "machine_max_jerk_y": "10,8", - "machine_max_jerk_z": "0.4,0.4", - "machine_max_speed_e": "50,60", - "machine_max_speed_x": "500,500", - "machine_max_speed_y": "500,500", - "machine_max_speed_z": "10,10", + "machine_max_acceleration_e": ["5000,5000", "5000,5000"], + "machine_max_acceleration_extruding": ["500,500", "500,500"], + "machine_max_acceleration_retracting": ["500,1000", "500,1000"], + "machine_max_acceleration_travel": ["500,500", "500,500"], + "machine_max_acceleration_x": ["500,500", "500,500"], + "machine_max_acceleration_y": ["500,500", "500,500"], + "machine_max_acceleration_z": ["500,500", "500,500"], + "machine_max_jerk_e": ["5,5", "5,5"], + "machine_max_jerk_x": ["10,8", "10,8"], + "machine_max_jerk_y": ["10,8", "10,8"], + "machine_max_jerk_z": ["0.4,0.4", "0.4,0.4"], + "machine_max_speed_e": ["50,60", "50,60"], + "machine_max_speed_x": ["500,500", "500,500"], + "machine_max_speed_y": ["500,500", "500,500"], + "machine_max_speed_z": ["10,10", "10,10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25 ;pause print", diff --git a/resources/profiles/Creality/machine/Creality CR-10 Smart Pro 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality CR-10 Smart Pro 0.4 nozzle.json index c7db2ac74f..3a65d1a6e7 100644 --- a/resources/profiles/Creality/machine/Creality CR-10 Smart Pro 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-10 Smart Pro 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit
\nG1 E-2 Z1 F2400 ;Retract and raise Z
\nG1 X5 Y5 F3000 ;Wipe out
\nG1 Z10 ;Raise Z more
\nG90 ;Absolute positionning

\nG1 X0 Y0 ;Present print
\nM106 S0 ;Turn-off fan
\nM104 S0 ;Turn-off hotend
\nM140 S0 ;Turn-off bed

\nM84 X Y E ;Disable all steppers but Z
", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000,5000", - "machine_max_acceleration_extruding": "500,500", - "machine_max_acceleration_retracting": "500,1000", - "machine_max_acceleration_travel": "500,500", - "machine_max_acceleration_x": "500,500", - "machine_max_acceleration_y": "500,500", - "machine_max_acceleration_z": "500,500", - "machine_max_jerk_e": "5,5", - "machine_max_jerk_x": "10,8", - "machine_max_jerk_y": "10,8", - "machine_max_jerk_z": "0.4,0.4", - "machine_max_speed_e": "50,60", - "machine_max_speed_x": "500,500", - "machine_max_speed_y": "500,500", - "machine_max_speed_z": "10,10", + "machine_max_acceleration_e": ["5000,5000", "5000,5000"], + "machine_max_acceleration_extruding": ["500,500", "500,500"], + "machine_max_acceleration_retracting": ["500,1000", "500,1000"], + "machine_max_acceleration_travel": ["500,500", "500,500"], + "machine_max_acceleration_x": ["500,500", "500,500"], + "machine_max_acceleration_y": ["500,500", "500,500"], + "machine_max_acceleration_z": ["500,500", "500,500"], + "machine_max_jerk_e": ["5,5", "5,5"], + "machine_max_jerk_x": ["10,8", "10,8"], + "machine_max_jerk_y": ["10,8", "10,8"], + "machine_max_jerk_z": ["0.4,0.4", "0.4,0.4"], + "machine_max_speed_e": ["50,60", "50,60"], + "machine_max_speed_x": ["500,500", "500,500"], + "machine_max_speed_y": ["500,500", "500,500"], + "machine_max_speed_z": ["10,10", "10,10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25 ;pause print", diff --git a/resources/profiles/Creality/machine/Creality CR-10S Pro V2 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality CR-10S Pro V2 0.4 nozzle.json index 04fe4b7cfd..cd56ba7dfb 100644 --- a/resources/profiles/Creality/machine/Creality CR-10S Pro V2 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-10S Pro V2 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit
\nG1 E-2 Z1 F2400 ;Retract and raise Z
\nG1 X5 Y5 F3000 ;Wipe out
\nG1 Z10 ;Raise Z more
\nG90 ;Absolute positionning

\nG1 X0 Y0 ;Present print
\nM106 S0 ;Turn-off fan
\nM104 S0 ;Turn-off hotend
\nM140 S0 ;Turn-off bed

\nM84 X Y E ;Disable all steppers but Z
", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000,5000", - "machine_max_acceleration_extruding": "500,500", - "machine_max_acceleration_retracting": "500,1000", - "machine_max_acceleration_travel": "500,500", - "machine_max_acceleration_x": "500,500", - "machine_max_acceleration_y": "500,500", - "machine_max_acceleration_z": "500,500", - "machine_max_jerk_e": "5,5", - "machine_max_jerk_x": "10,8", - "machine_max_jerk_y": "10,8", - "machine_max_jerk_z": "0.4,0.4", - "machine_max_speed_e": "50,60", - "machine_max_speed_x": "500,500", - "machine_max_speed_y": "500,500", - "machine_max_speed_z": "10,10", + "machine_max_acceleration_e": ["5000,5000", "5000,5000"], + "machine_max_acceleration_extruding": ["500,500", "500,500"], + "machine_max_acceleration_retracting": ["500,1000", "500,1000"], + "machine_max_acceleration_travel": ["500,500", "500,500"], + "machine_max_acceleration_x": ["500,500", "500,500"], + "machine_max_acceleration_y": ["500,500", "500,500"], + "machine_max_acceleration_z": ["500,500", "500,500"], + "machine_max_jerk_e": ["5,5", "5,5"], + "machine_max_jerk_x": ["10,8", "10,8"], + "machine_max_jerk_y": ["10,8", "10,8"], + "machine_max_jerk_z": ["0.4,0.4", "0.4,0.4"], + "machine_max_speed_e": ["50,60", "50,60"], + "machine_max_speed_x": ["500,500", "500,500"], + "machine_max_speed_y": ["500,500", "500,500"], + "machine_max_speed_z": ["10,10", "10,10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25 ;pause print", diff --git a/resources/profiles/Creality/machine/Creality CR-20 Pro 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality CR-20 Pro 0.4 nozzle.json index 49f85b6acc..9740c97a1a 100644 --- a/resources/profiles/Creality/machine/Creality CR-20 Pro 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-20 Pro 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "500", - "machine_max_acceleration_retracting": "500", - "machine_max_acceleration_travel": "500", - "machine_max_acceleration_x": "500", - "machine_max_acceleration_y": "500", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["500", "500"], + "machine_max_acceleration_retracting": ["500", "500"], + "machine_max_acceleration_travel": ["500", "500"], + "machine_max_acceleration_x": ["500", "500"], + "machine_max_acceleration_y": ["500", "500"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Creality/machine/Creality CR-M4 SE 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality CR-M4 SE 0.4 nozzle.json index 1a6ac10bea..ca875c8184 100644 --- a/resources/profiles/Creality/machine/Creality CR-M4 SE 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-M4 SE 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \nG1 X5 Y5 F3000 ;Wipe out \nG1 Z4.5 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X2 Y218 F3000 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "11", - "machine_max_acceleration_e": "8000", - "machine_max_acceleration_extruding": "8000", - "machine_max_acceleration_retracting": "8000", - "machine_max_acceleration_travel": "8000", - "machine_max_acceleration_x": "8000", - "machine_max_acceleration_y": "8000", - "machine_max_acceleration_z": "2000", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "100", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["8000", "8000"], + "machine_max_acceleration_extruding": ["8000", "8000"], + "machine_max_acceleration_retracting": ["8000", "8000"], + "machine_max_acceleration_travel": ["8000", "8000"], + "machine_max_acceleration_x": ["8000", "8000"], + "machine_max_acceleration_y": ["8000", "8000"], + "machine_max_acceleration_z": ["2000", "2000"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Ender-2 Pro 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-2 Pro 0.4 nozzle.json index 8aa0ce3cb3..0ca93a00bf 100644 --- a/resources/profiles/Creality/machine/Creality Ender-2 Pro 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-2 Pro 0.4 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "500", - "machine_max_acceleration_retracting": "500", - "machine_max_acceleration_travel": "500", - "machine_max_acceleration_x": "500", - "machine_max_acceleration_y": "500", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["500", "500"], + "machine_max_acceleration_retracting": ["500", "500"], + "machine_max_acceleration_travel": ["500", "500"], + "machine_max_acceleration_x": ["500", "500"], + "machine_max_acceleration_y": ["500", "500"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 Max 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 Max 0.4 nozzle.json index 2c0f280ae7..dd07893bca 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 Max 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 Max 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "500", - "machine_max_acceleration_retracting": "500", - "machine_max_acceleration_travel": "500", - "machine_max_acceleration_x": "500", - "machine_max_acceleration_y": "500", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["500", "500"], + "machine_max_acceleration_retracting": ["500", "500"], + "machine_max_acceleration_travel": ["500", "500"], + "machine_max_acceleration_x": ["500", "500"], + "machine_max_acceleration_y": ["500", "500"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 Max Neo 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 Max Neo 0.4 nozzle.json index 8db6b4d5cc..88eaf0af7b 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 Max Neo 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 Max Neo 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "500", - "machine_max_acceleration_retracting": "500", - "machine_max_acceleration_travel": "500", - "machine_max_acceleration_x": "500", - "machine_max_acceleration_y": "500", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["500", "500"], + "machine_max_acceleration_retracting": ["500", "500"], + "machine_max_acceleration_travel": ["500", "500"], + "machine_max_acceleration_x": ["500", "500"], + "machine_max_acceleration_y": ["500", "500"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 Neo 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 Neo 0.4 nozzle.json index d401e149e5..4ad35f9bc1 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 Neo 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 Neo 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit
\nG1 E-2 Z1 F2400 ;Retract and raise Z
\nG1 X5 Y5 F3000 ;Wipe out
\nG1 Z10 ;Raise Z more
\nG90 ;Absolute positionning

\nG1 X0 Y0 ;Present print
\nM106 S0 ;Turn-off fan
\nM104 S0 ;Turn-off hotend
\nM140 S0 ;Turn-off bed

\nM84 X Y E ;Disable all steppers but Z
", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000,5000", - "machine_max_acceleration_extruding": "500,500", - "machine_max_acceleration_retracting": "500,1000", - "machine_max_acceleration_travel": "500,500", - "machine_max_acceleration_x": "500,500", - "machine_max_acceleration_y": "500,500", - "machine_max_acceleration_z": "500,500", - "machine_max_jerk_e": "5,5", - "machine_max_jerk_x": "10,8", - "machine_max_jerk_y": "10,8", - "machine_max_jerk_z": "0.4,0.4", - "machine_max_speed_e": "50,60", - "machine_max_speed_x": "500,500", - "machine_max_speed_y": "500,500", - "machine_max_speed_z": "10,10", + "machine_max_acceleration_e": ["5000,5000", "5000,5000"], + "machine_max_acceleration_extruding": ["500,500", "500,500"], + "machine_max_acceleration_retracting": ["500,1000", "500,1000"], + "machine_max_acceleration_travel": ["500,500", "500,500"], + "machine_max_acceleration_x": ["500,500", "500,500"], + "machine_max_acceleration_y": ["500,500", "500,500"], + "machine_max_acceleration_z": ["500,500", "500,500"], + "machine_max_jerk_e": ["5,5", "5,5"], + "machine_max_jerk_x": ["10,8", "10,8"], + "machine_max_jerk_y": ["10,8", "10,8"], + "machine_max_jerk_z": ["0.4,0.4", "0.4,0.4"], + "machine_max_speed_e": ["50,60", "50,60"], + "machine_max_speed_x": ["500,500", "500,500"], + "machine_max_speed_y": ["500,500", "500,500"], + "machine_max_speed_z": ["10,10", "10,10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25 ;pause print", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 S1 Sonic 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 S1 Sonic 0.4 nozzle.json index c0bc21cedf..88a92fadca 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 S1 Sonic 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 S1 Sonic 0.4 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "3000", - "machine_max_acceleration_extruding": "10000", - "machine_max_acceleration_retracting": "3000", - "machine_max_acceleration_travel": "5000", - "machine_max_acceleration_x": "10000", - "machine_max_acceleration_y": "10000", - "machine_max_acceleration_z": "200", - "machine_max_jerk_e": "2.5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "2", - "machine_max_speed_e": "80", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["3000", "3000"], + "machine_max_acceleration_extruding": ["10000", "10000"], + "machine_max_acceleration_retracting": ["3000", "3000"], + "machine_max_acceleration_travel": ["5000", "5000"], + "machine_max_acceleration_x": ["10000", "10000"], + "machine_max_acceleration_y": ["10000", "10000"], + "machine_max_acceleration_z": ["200", "200"], + "machine_max_jerk_e": ["2.5", "2.5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["2", "2"], + "machine_max_speed_e": ["80", "80"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 0.8 nozzle.json index d075f13e04..ff02afcd42 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 0.8 nozzle.json @@ -31,21 +31,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "10000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "2.5", - "machine_max_jerk_x": "50", - "machine_max_jerk_y": "50", - "machine_max_jerk_z": "2", - "machine_max_speed_e": "100", - "machine_max_speed_x": "600", - "machine_max_speed_y": "600", - "machine_max_speed_z": "500", + "machine_max_acceleration_e": ["10000", "10000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["2.5", "2.5"], + "machine_max_jerk_x": ["50", "50"], + "machine_max_jerk_y": ["50", "50"], + "machine_max_jerk_z": ["2", "2"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["600", "600"], + "machine_max_speed_y": ["600", "600"], + "machine_max_speed_z": ["500", "500"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE\n", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 Plus 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 Plus 0.8 nozzle.json index 713d45e321..8bc845ee6a 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 Plus 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 Plus 0.8 nozzle.json @@ -32,21 +32,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "10000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "2.5", - "machine_max_jerk_x": "50", - "machine_max_jerk_y": "50", - "machine_max_jerk_z": "2", - "machine_max_speed_e": "100", - "machine_max_speed_x": "600", - "machine_max_speed_y": "600", - "machine_max_speed_z": "500", + "machine_max_acceleration_e": ["10000", "10000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["2.5", "2.5"], + "machine_max_jerk_x": ["50", "50"], + "machine_max_jerk_y": ["50", "50"], + "machine_max_jerk_z": ["2", "2"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["600", "600"], + "machine_max_speed_y": ["600", "600"], + "machine_max_speed_z": ["500", "500"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE\n", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.2 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.2 nozzle.json index 378dca3a2d..46d9ce1085 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.2 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.2 nozzle.json @@ -121,7 +121,7 @@ "Generic PLA @Creality Ender-3V3-all" ], "file_start_gcode": ";FLAVOR:Marlin\\n;TIME:{print_time_total_sec}\\n;Filament used:{used_filament_length}m\\n;Layer height:{layer_height}", - "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", + "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nG90 ;Absolute positioning \nM82 ;Absolute extrusion mode \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \nG1 X5 Y5 F3000 ;Wipe out \nG1 Z10 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X0 Y220 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "scan_first_layer": "0", "disable_m73": "1", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.4 nozzle.json index 97ef822dc7..b905be8d39 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.4 nozzle.json @@ -121,7 +121,7 @@ "Generic PLA @Creality Ender-3V3-all" ], "file_start_gcode": ";FLAVOR:Marlin\\n;TIME:{print_time_total_sec}\\n;Filament used:{used_filament_length}m\\n;Layer height:{layer_height}", - "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", + "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nG90 ;Absolute positioning \nM82 ;Absolute extrusion mode \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \nG1 X5 Y5 F3000 ;Wipe out \nG1 Z10 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X0 Y220 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "scan_first_layer": "0", "disable_m73": "1", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.6 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.6 nozzle.json index 7023c5a95a..40ad654754 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.6 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.6 nozzle.json @@ -121,7 +121,7 @@ "Generic PLA @Creality Ender-3V3-all" ], "file_start_gcode": ";FLAVOR:Marlin\\n;TIME:{print_time_total_sec}\\n;Filament used:{used_filament_length}m\\n;Layer height:{layer_height}", - "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", + "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nG90 ;Absolute positioning \nM82 ;Absolute extrusion mode \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \nG1 X5 Y5 F3000 ;Wipe out \nG1 Z10 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X0 Y220 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "scan_first_layer": "0", "disable_m73": "1", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.8 nozzle.json index acec590a1f..1b6053bd36 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V3 SE 0.8 nozzle.json @@ -121,7 +121,7 @@ "Generic PLA @Creality Ender-3V3-all" ], "file_start_gcode": ";FLAVOR:Marlin\\n;TIME:{print_time_total_sec}\\n;Filament used:{used_filament_length}m\\n;Layer height:{layer_height}", - "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", + "machine_start_gcode": "M220 S100 ;Reset Feedrate \nM221 S100 ;Reset Flowrate \n \nG90 ;Absolute positioning \nM82 ;Absolute extrusion mode \n \nM104 S[nozzle_temperature_initial_layer] ;Set final nozzle temp \nM190 S[bed_temperature_initial_layer_single] ;Set and wait for bed temp to stabilize \nG28 ;Home \nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X-2.1 Y20 Z0.28 F5000.0 ;Move to start position \nM109 S[nozzle_temperature_initial_layer] ;Wait for nozzle temp to stabilize \nG1 X-2.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line \nG1 X-2.4 Y145.0 Z0.28 F5000.0 ;Move to side a little \nG1 X-2.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line \nG92 E0 ;Reset Extruder \nG1 E-1.0000 F1800 ;Retract a bit \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 E0.0000 F1800", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \nG1 X5 Y5 F3000 ;Wipe out \nG1 Z10 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X0 Y220 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "scan_first_layer": "0", "disable_m73": "1", diff --git a/resources/profiles/Creality/machine/Creality Ender-3 V4 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-3 V4 0.4 nozzle.json index ce5d13c8d9..035bbf87a6 100644 --- a/resources/profiles/Creality/machine/Creality Ender-3 V4 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-3 V4 0.4 nozzle.json @@ -35,21 +35,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "126", - "machine_max_acceleration_e": "2400", - "machine_max_acceleration_extruding": "12000", - "machine_max_acceleration_retracting": "2400", - "machine_max_acceleration_travel": "12000", - "machine_max_acceleration_x": "12000", - "machine_max_acceleration_y": "12000", - "machine_max_acceleration_z": "1000", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "100", - "machine_max_jerk_y": "100", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "40", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["2400", "2400"], + "machine_max_acceleration_extruding": ["12000", "12000"], + "machine_max_acceleration_retracting": ["2400", "2400"], + "machine_max_acceleration_travel": ["12000", "12000"], + "machine_max_acceleration_x": ["12000", "12000"], + "machine_max_acceleration_y": ["12000", "12000"], + "machine_max_acceleration_z": ["1000", "1000"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["100", "100"], + "machine_max_jerk_y": ["100", "100"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["40", "40"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Ender-5 Max 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-5 Max 0.4 nozzle.json index 496a977127..b4e435461b 100644 --- a/resources/profiles/Creality/machine/Creality Ender-5 Max 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-5 Max 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \n \nG1 Z5 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X395 Y395 F6000 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "11", - "machine_max_acceleration_e": "30000", - "machine_max_acceleration_extruding": "50000", - "machine_max_acceleration_retracting": "50000", - "machine_max_acceleration_travel": "50000", - "machine_max_acceleration_x": "50000", - "machine_max_acceleration_y": "50000", - "machine_max_acceleration_z": "1000", - "machine_max_jerk_e": "100", - "machine_max_jerk_x": "100", - "machine_max_jerk_y": "100", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "1000", - "machine_max_speed_x": "1000", - "machine_max_speed_y": "1000", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["30000", "30000"], + "machine_max_acceleration_extruding": ["50000", "50000"], + "machine_max_acceleration_retracting": ["50000", "50000"], + "machine_max_acceleration_travel": ["50000", "50000"], + "machine_max_acceleration_x": ["50000", "50000"], + "machine_max_acceleration_y": ["50000", "50000"], + "machine_max_acceleration_z": ["1000", "1000"], + "machine_max_jerk_e": ["100", "100"], + "machine_max_jerk_x": ["100", "100"], + "machine_max_jerk_y": ["100", "100"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["1000", "1000"], + "machine_max_speed_x": ["1000", "1000"], + "machine_max_speed_y": ["1000", "1000"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Ender-5 Max 0.6 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-5 Max 0.6 nozzle.json index 59d08460d5..8bf84b5292 100644 --- a/resources/profiles/Creality/machine/Creality Ender-5 Max 0.6 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-5 Max 0.6 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \n \nG1 Z5 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X395 Y395 F6000 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "11", - "machine_max_acceleration_e": "30000", - "machine_max_acceleration_extruding": "12000", - "machine_max_acceleration_retracting": "12000", - "machine_max_acceleration_travel": "50000", - "machine_max_acceleration_x": "12000", - "machine_max_acceleration_y": "12000", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "6", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "4", - "machine_max_speed_e": "30", - "machine_max_speed_x": "1000", - "machine_max_speed_y": "1000", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["30000", "30000"], + "machine_max_acceleration_extruding": ["12000", "12000"], + "machine_max_acceleration_retracting": ["12000", "12000"], + "machine_max_acceleration_travel": ["50000", "50000"], + "machine_max_acceleration_x": ["12000", "12000"], + "machine_max_acceleration_y": ["12000", "12000"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["6", "6"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["4", "4"], + "machine_max_speed_e": ["30", "30"], + "machine_max_speed_x": ["1000", "1000"], + "machine_max_speed_y": ["1000", "1000"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Ender-5 Max 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-5 Max 0.8 nozzle.json index fcfa26e790..d01635c614 100644 --- a/resources/profiles/Creality/machine/Creality Ender-5 Max 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-5 Max 0.8 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning \nG1 E-2 F2700 ;Retract a bit \nG1 E-2 Z0.2 F2400 ;Retract and raise Z \n \nG1 Z5 ;Raise Z more \nG90 ;Absolute positionning \n \nG1 X395 Y395 F6000 ;Present print \nM106 S0 ;Turn-off fan \nM104 S0 ;Turn-off hotend \nM140 S0 ;Turn-off bed \n \nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "11", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "12000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "50000", - "machine_max_acceleration_x": "12000", - "machine_max_acceleration_y": "12000", - "machine_max_acceleration_z": "200", - "machine_max_jerk_e": "3", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "3", - "machine_max_speed_e": "30", - "machine_max_speed_x": "1000", - "machine_max_speed_y": "1000", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["12000", "12000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["50000", "50000"], + "machine_max_acceleration_x": ["12000", "12000"], + "machine_max_acceleration_y": ["12000", "12000"], + "machine_max_acceleration_z": ["200", "200"], + "machine_max_jerk_e": ["3", "3"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["3", "3"], + "machine_max_speed_e": ["30", "30"], + "machine_max_speed_x": ["1000", "1000"], + "machine_max_speed_y": ["1000", "1000"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Ender-5 Plus 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-5 Plus 0.4 nozzle.json index 66fea8f254..03a8e00895 100644 --- a/resources/profiles/Creality/machine/Creality Ender-5 Plus 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-5 Plus 0.4 nozzle.json @@ -20,6 +20,7 @@ "nozzle_type": "undefine", "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "1000", "1000" ], "machine_max_acceleration_extruding": [ diff --git a/resources/profiles/Creality/machine/Creality Ender-5 S1 Sonic 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Ender-5 S1 Sonic 0.4 nozzle.json index c290f9bb9a..06c6ed6e99 100644 --- a/resources/profiles/Creality/machine/Creality Ender-5 S1 Sonic 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Ender-5 S1 Sonic 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "2000", - "machine_max_acceleration_extruding": "2500", - "machine_max_acceleration_retracting": "1000", - "machine_max_acceleration_travel": "2000", - "machine_max_acceleration_x": "2500", - "machine_max_acceleration_y": "2500", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "12", - "machine_max_jerk_y": "12", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "100", - "machine_max_speed_x": "250", - "machine_max_speed_y": "250", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["2000", "2000"], + "machine_max_acceleration_extruding": ["2500", "2500"], + "machine_max_acceleration_retracting": ["1000", "1000"], + "machine_max_acceleration_travel": ["2000", "2000"], + "machine_max_acceleration_x": ["2500", "2500"], + "machine_max_acceleration_y": ["2500", "2500"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["12", "12"], + "machine_max_jerk_y": ["12", "12"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["250", "250"], + "machine_max_speed_y": ["250", "250"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Hi 0.2 nozzle.json b/resources/profiles/Creality/machine/Creality Hi 0.2 nozzle.json index 2acc80fe3d..4bc5847408 100644 --- a/resources/profiles/Creality/machine/Creality Hi 0.2 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Hi 0.2 nozzle.json @@ -39,21 +39,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G1 X0 Y180 F8000\nEND_PRINT", "machine_load_filament_time": "105", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "12000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "12000", - "machine_max_acceleration_y": "12000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "2.5", - "machine_max_jerk_x": "12", - "machine_max_jerk_y": "12", - "machine_max_jerk_z": "2", - "machine_max_speed_e": "50", - "machine_max_speed_x": "300", - "machine_max_speed_y": "300", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["12000", "12000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["12000", "12000"], + "machine_max_acceleration_y": ["12000", "12000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["2.5", "2.5"], + "machine_max_jerk_x": ["12", "12"], + "machine_max_jerk_y": ["12", "12"], + "machine_max_jerk_z": ["2", "2"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["300", "300"], + "machine_max_speed_y": ["300", "300"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Hi 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Hi 0.8 nozzle.json index dcf32371d4..74126664e2 100644 --- a/resources/profiles/Creality/machine/Creality Hi 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Hi 0.8 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G1 X0 Y180 F8000\nEND_PRINT", "machine_load_filament_time": "105", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "12000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "12000", - "machine_max_acceleration_y": "12000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "2.5", - "machine_max_jerk_x": "12", - "machine_max_jerk_y": "12", - "machine_max_jerk_z": "2", - "machine_max_speed_e": "50", - "machine_max_speed_x": "300", - "machine_max_speed_y": "300", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["12000", "12000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["12000", "12000"], + "machine_max_acceleration_y": ["12000", "12000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["2.5", "2.5"], + "machine_max_jerk_x": ["12", "12"], + "machine_max_jerk_y": ["12", "12"], + "machine_max_jerk_z": ["2", "2"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["300", "300"], + "machine_max_speed_y": ["300", "300"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K1 Max_CFS-C 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality K1 Max_CFS-C 0.4 nozzle.json index 2e96b092ab..f30d670e49 100644 --- a/resources/profiles/Creality/machine/Creality K1 Max_CFS-C 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K1 Max_CFS-C 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "119", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "300", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["300", "300"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K1 SE 0.6 nozzle.json b/resources/profiles/Creality/machine/Creality K1 SE 0.6 nozzle.json index e1212431e2..0dbe9552e5 100644 --- a/resources/profiles/Creality/machine/Creality K1 SE 0.6 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K1 SE 0.6 nozzle.json @@ -38,21 +38,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "119", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K1 SE 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality K1 SE 0.8 nozzle.json index e17cfbaee4..fb2ae7bc58 100644 --- a/resources/profiles/Creality/machine/Creality K1 SE 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K1 SE 0.8 nozzle.json @@ -38,21 +38,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "119", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K1 SE_CFS-C 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality K1 SE_CFS-C 0.4 nozzle.json index aff5f6df86..1cce21a968 100644 --- a/resources/profiles/Creality/machine/Creality K1 SE_CFS-C 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K1 SE_CFS-C 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "119", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K1C_CFS-C 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality K1C_CFS-C 0.4 nozzle.json index 3c21fddd9e..6d51a3cea8 100644 --- a/resources/profiles/Creality/machine/Creality K1C_CFS-C 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K1C_CFS-C 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "119", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "300", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "600", - "machine_max_speed_y": "600", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["300", "300"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["600", "600"], + "machine_max_speed_y": ["600", "600"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K1_CFS-C 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality K1_CFS-C 0.4 nozzle.json index c19ca981f8..f53f11a029 100644 --- a/resources/profiles/Creality/machine/Creality K1_CFS-C 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K1_CFS-C 0.4 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "119", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "300", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["300", "300"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality K2 SE 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality K2 SE 0.4 nozzle.json index a1c33a0026..2005444a7b 100644 --- a/resources/profiles/Creality/machine/Creality K2 SE 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality K2 SE 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "135", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "20", - "machine_max_jerk_y": "20", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "100", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "30", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["20", "20"], + "machine_max_jerk_y": ["20", "20"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["100", "100"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["30", "30"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality SPARKX i7 0.2 nozzle.json b/resources/profiles/Creality/machine/Creality SPARKX i7 0.2 nozzle.json index 146628aded..8f622d072d 100644 --- a/resources/profiles/Creality/machine/Creality SPARKX i7 0.2 nozzle.json +++ b/resources/profiles/Creality/machine/Creality SPARKX i7 0.2 nozzle.json @@ -39,21 +39,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G1 E-0.8 F2400 ; retract\nG2 Z{position[2]+3} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift\nG92 E0 ; zero the extruder\n{if print_sequence == \"by object\"}\nG0 Z{max_layer_z + 1} F1800\n{endif}\nG1 X0 Y180 F8000\nEND_PRINT", "machine_load_filament_time": "30", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "10000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "30000", - "machine_max_acceleration_x": "10000", - "machine_max_acceleration_y": "10000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "3", - "machine_max_jerk_x": "9", - "machine_max_jerk_y": "9", - "machine_max_jerk_z": "3", - "machine_max_speed_e": "14", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["10000", "10000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["30000", "30000"], + "machine_max_acceleration_x": ["10000", "10000"], + "machine_max_acceleration_y": ["10000", "10000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["3", "3"], + "machine_max_jerk_x": ["9", "9"], + "machine_max_jerk_y": ["9", "9"], + "machine_max_jerk_z": ["3", "3"], + "machine_max_speed_e": ["14", "14"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality SPARKX i7 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality SPARKX i7 0.4 nozzle.json index bf30a2ce49..34f9781bab 100644 --- a/resources/profiles/Creality/machine/Creality SPARKX i7 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality SPARKX i7 0.4 nozzle.json @@ -39,21 +39,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G1 E-0.8 F2400 ; retract\nG2 Z{position[2]+3} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift\nG92 E0 ; zero the extruder\n{if print_sequence == \"by object\"}\nG0 Z{max_layer_z + 1} F1800\n{endif}\nG1 X0 Y180 F8000\nEND_PRINT", "machine_load_filament_time": "30", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "10000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "30000", - "machine_max_acceleration_x": "10000", - "machine_max_acceleration_y": "10000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "3", - "machine_max_jerk_x": "9", - "machine_max_jerk_y": "9", - "machine_max_jerk_z": "3", - "machine_max_speed_e": "14", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["10000", "10000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["30000", "30000"], + "machine_max_acceleration_x": ["10000", "10000"], + "machine_max_acceleration_y": ["10000", "10000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["3", "3"], + "machine_max_jerk_x": ["9", "9"], + "machine_max_jerk_y": ["9", "9"], + "machine_max_jerk_z": ["3", "3"], + "machine_max_speed_e": ["14", "14"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality SPARKX i7 0.6 nozzle.json b/resources/profiles/Creality/machine/Creality SPARKX i7 0.6 nozzle.json index e327895da7..406e50f45f 100644 --- a/resources/profiles/Creality/machine/Creality SPARKX i7 0.6 nozzle.json +++ b/resources/profiles/Creality/machine/Creality SPARKX i7 0.6 nozzle.json @@ -39,21 +39,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G1 E-0.8 F2400 ; retract\nG2 Z{position[2]+3} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift\nG92 E0 ; zero the extruder\n{if print_sequence == \"by object\"}\nG0 Z{max_layer_z + 1} F1800\n{endif}\nG1 X0 Y180 F8000\nEND_PRINT", "machine_load_filament_time": "30", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "10000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "30000", - "machine_max_acceleration_x": "10000", - "machine_max_acceleration_y": "10000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "3", - "machine_max_jerk_x": "9", - "machine_max_jerk_y": "9", - "machine_max_jerk_z": "3", - "machine_max_speed_e": "14", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["10000", "10000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["30000", "30000"], + "machine_max_acceleration_x": ["10000", "10000"], + "machine_max_acceleration_y": ["10000", "10000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["3", "3"], + "machine_max_jerk_x": ["9", "9"], + "machine_max_jerk_y": ["9", "9"], + "machine_max_jerk_z": ["3", "3"], + "machine_max_speed_e": ["14", "14"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality SPARKX i7 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality SPARKX i7 0.8 nozzle.json index a3fad94bab..0c4e269ea0 100644 --- a/resources/profiles/Creality/machine/Creality SPARKX i7 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality SPARKX i7 0.8 nozzle.json @@ -39,21 +39,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G1 E-0.8 F2400 ; retract\nG2 Z{position[2]+3} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift\nG92 E0 ; zero the extruder\n{if print_sequence == \"by object\"}\nG0 Z{max_layer_z + 1} F1800\n{endif}\nG1 X0 Y180 F8000\nEND_PRINT", "machine_load_filament_time": "30", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "10000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "30000", - "machine_max_acceleration_x": "10000", - "machine_max_acceleration_y": "10000", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "3", - "machine_max_jerk_x": "9", - "machine_max_jerk_y": "9", - "machine_max_jerk_z": "3", - "machine_max_speed_e": "14", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "20", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["10000", "10000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["30000", "30000"], + "machine_max_acceleration_x": ["10000", "10000"], + "machine_max_acceleration_y": ["10000", "10000"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["3", "3"], + "machine_max_jerk_x": ["9", "9"], + "machine_max_jerk_y": ["9", "9"], + "machine_max_jerk_z": ["3", "3"], + "machine_max_speed_e": ["14", "14"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["20", "20"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Sermoon D3 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Sermoon D3 0.4 nozzle.json index aafe573db7..cc5faa2e2e 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon D3 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Sermoon D3 0.4 nozzle.json @@ -38,21 +38,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "500", - "machine_max_acceleration_retracting": "500", - "machine_max_acceleration_travel": "500", - "machine_max_acceleration_x": "500", - "machine_max_acceleration_y": "500", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["500", "500"], + "machine_max_acceleration_retracting": ["500", "500"], + "machine_max_acceleration_travel": ["500", "500"], + "machine_max_acceleration_x": ["500", "500"], + "machine_max_acceleration_y": ["500", "500"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Creality/machine/Creality Sermoon D3 Pro 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Sermoon D3 Pro 0.4 nozzle.json index e82ab42245..4c19dc813d 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon D3 Pro 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Sermoon D3 Pro 0.4 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\n;G1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "5000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "3000", - "machine_max_acceleration_y": "3000", - "machine_max_acceleration_z": "100", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["5000", "5000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["3000", "3000"], + "machine_max_acceleration_y": ["3000", "3000"], + "machine_max_acceleration_z": ["100", "100"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Creality/machine/Creality Sermoon M300 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Sermoon M300 0.4 nozzle.json index bd52ae171a..05720901ca 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon M300 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Sermoon M300 0.4 nozzle.json @@ -36,21 +36,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "128", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "300", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "100", - "machine_max_jerk_y": "100", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "50", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["300", "300"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["100", "100"], + "machine_max_jerk_y": ["100", "100"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Sermoon M300 0.6 nozzle.json b/resources/profiles/Creality/machine/Creality Sermoon M300 0.6 nozzle.json index e8cd96e845..8263db1d97 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon M300 0.6 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Sermoon M300 0.6 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "128", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "300", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "100", - "machine_max_jerk_y": "100", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "50", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["300", "300"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["100", "100"], + "machine_max_jerk_y": ["100", "100"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Sermoon M300 0.8 nozzle.json b/resources/profiles/Creality/machine/Creality Sermoon M300 0.8 nozzle.json index 299bb1679b..7daddf2688 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon M300 0.8 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Sermoon M300 0.8 nozzle.json @@ -37,21 +37,21 @@ "machine_LED_light_exist": "0", "machine_end_gcode": "END_PRINT", "machine_load_filament_time": "128", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "20000", - "machine_max_acceleration_retracting": "5000", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "20000", - "machine_max_acceleration_y": "20000", - "machine_max_acceleration_z": "300", - "machine_max_jerk_e": "10", - "machine_max_jerk_x": "100", - "machine_max_jerk_y": "100", - "machine_max_jerk_z": "5", - "machine_max_speed_e": "50", - "machine_max_speed_x": "800", - "machine_max_speed_y": "800", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["20000", "20000"], + "machine_max_acceleration_retracting": ["5000", "5000"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["20000", "20000"], + "machine_max_acceleration_y": ["20000", "20000"], + "machine_max_acceleration_z": ["300", "300"], + "machine_max_jerk_e": ["10", "10"], + "machine_max_jerk_x": ["100", "100"], + "machine_max_jerk_y": ["100", "100"], + "machine_max_jerk_z": ["5", "5"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["800", "800"], + "machine_max_speed_y": ["800", "800"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Creality/machine/Creality Sermoon V1 Pro 0.4 nozzle.json b/resources/profiles/Creality/machine/Creality Sermoon V1 Pro 0.4 nozzle.json index 036ec9c791..ffa05ac323 100644 --- a/resources/profiles/Creality/machine/Creality Sermoon V1 Pro 0.4 nozzle.json +++ b/resources/profiles/Creality/machine/Creality Sermoon V1 Pro 0.4 nozzle.json @@ -38,21 +38,21 @@ "machine_LED_light_exist": "1", "machine_end_gcode": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z", "machine_load_filament_time": "0", - "machine_max_acceleration_e": "5000", - "machine_max_acceleration_extruding": "500", - "machine_max_acceleration_retracting": "500", - "machine_max_acceleration_travel": "20000", - "machine_max_acceleration_x": "500", - "machine_max_acceleration_y": "500", - "machine_max_acceleration_z": "500", - "machine_max_jerk_e": "5", - "machine_max_jerk_x": "10", - "machine_max_jerk_y": "10", - "machine_max_jerk_z": "0.4", - "machine_max_speed_e": "50", - "machine_max_speed_x": "500", - "machine_max_speed_y": "500", - "machine_max_speed_z": "10", + "machine_max_acceleration_e": ["5000", "5000"], + "machine_max_acceleration_extruding": ["500", "500"], + "machine_max_acceleration_retracting": ["500", "500"], + "machine_max_acceleration_travel": ["20000", "20000"], + "machine_max_acceleration_x": ["500", "500"], + "machine_max_acceleration_y": ["500", "500"], + "machine_max_acceleration_z": ["500", "500"], + "machine_max_jerk_e": ["5", "5"], + "machine_max_jerk_x": ["10", "10"], + "machine_max_jerk_y": ["10", "10"], + "machine_max_jerk_z": ["0.4", "0.4"], + "machine_max_speed_e": ["50", "50"], + "machine_max_speed_x": ["500", "500"], + "machine_max_speed_y": ["500", "500"], + "machine_max_speed_z": ["10", "10"], "machine_min_extruding_rate": "0,0", "machine_min_travel_rate": "0,0", "machine_pause_gcode": "M25", diff --git a/resources/profiles/Cubicon.json b/resources/profiles/Cubicon.json index 81601bc83e..b50c3be4b7 100644 --- a/resources/profiles/Cubicon.json +++ b/resources/profiles/Cubicon.json @@ -1,6 +1,6 @@ { "name": "Cubicon", - "version": "02.04.00.07", + "version": "02.04.00.08", "force_update": "0", "description": "Cubicon configurations", "machine_model_list": [ diff --git a/resources/profiles/Cubicon/filament/Cubicon ABS @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon ABS @Cubicon xCeler-I 0.4 nozzle.json index 93949a7c80..03721728c7 100644 --- a/resources/profiles/Cubicon/filament/Cubicon ABS @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon ABS @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon ABS @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon ABS @base", "renamed_from": "Cubicon ABS @base", + "inherits": "Cubicon ABS @base", "setting_id": "VJEyK87ZYvHmamB9", "filament_id": "OFpDo5Ix", "instantiation": "true", diff --git a/resources/profiles/Cubicon/filament/Cubicon ABS-A100 @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon ABS-A100 @Cubicon xCeler-I 0.4 nozzle.json index 2788688e1b..ab66e1a8f5 100644 --- a/resources/profiles/Cubicon/filament/Cubicon ABS-A100 @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon ABS-A100 @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon ABS-A100 @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon ABS-A100 @base", "renamed_from": "Cubicon ABS-A100 @base", + "inherits": "Cubicon ABS-A100 @base", "setting_id": "OfiOryklf7FDVCz8", "filament_id": "OFy8tYJE", "instantiation": "true", diff --git a/resources/profiles/Cubicon/filament/Cubicon ABSk @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon ABSk @Cubicon xCeler-I 0.4 nozzle.json index cdb6324af1..913a98cfed 100644 --- a/resources/profiles/Cubicon/filament/Cubicon ABSk @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon ABSk @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon ABSk @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon ABSk @base", "renamed_from": "Cubicon ABSk @base", + "inherits": "Cubicon ABSk @base", "setting_id": "TXcodZkab4fofnEn", "filament_id": "OForhBi4", "instantiation": "true", diff --git a/resources/profiles/Cubicon/filament/Cubicon PA-CF @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon PA-CF @Cubicon xCeler-I 0.4 nozzle.json index 09a5d917f4..7999bdd8e2 100644 --- a/resources/profiles/Cubicon/filament/Cubicon PA-CF @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon PA-CF @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon PA-CF @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon PA-CF @base", "renamed_from": "Cubicon PA-CF @base", + "inherits": "Cubicon PA-CF @base", "setting_id": "nupuIJggdc1EKDqG", "filament_id": "OFiEz2XI", "instantiation": "true", diff --git a/resources/profiles/Cubicon/filament/Cubicon PC @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon PC @Cubicon xCeler-I 0.4 nozzle.json index e37f5f063c..6a4347591a 100644 --- a/resources/profiles/Cubicon/filament/Cubicon PC @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon PC @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon PC @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon PC @base", "renamed_from": "Cubicon PC @base", + "inherits": "Cubicon PC @base", "setting_id": "c0sUPS0SRYUNjEpB", "filament_id": "OFEj7sca", "instantiation": "true", diff --git a/resources/profiles/Cubicon/filament/Cubicon PETG @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon PETG @Cubicon xCeler-I 0.4 nozzle.json index db9a90c42d..d5fcedfa96 100644 --- a/resources/profiles/Cubicon/filament/Cubicon PETG @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon PETG @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon PETG @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon PETG @base", "renamed_from": "Cubicon PETG @base", + "inherits": "Cubicon PETG @base", "setting_id": "dsX01tCkd2Usk104", "filament_id": "OFoBTKmn", "instantiation": "true", diff --git a/resources/profiles/Cubicon/filament/Cubicon PLA @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon PLA @Cubicon xCeler-I 0.4 nozzle.json index 3b3c9b1d4c..154c8c664f 100644 --- a/resources/profiles/Cubicon/filament/Cubicon PLA @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon PLA @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon PLA @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon PLA @base", "renamed_from": "Cubicon PLA @base", + "inherits": "Cubicon PLA @base", "from": "system", "setting_id": "xXJgHAeNf1JdCitr", "filament_id": "OFEwRwmL", diff --git a/resources/profiles/Cubicon/filament/Cubicon PLA+ @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon PLA+ @Cubicon xCeler-I 0.4 nozzle.json index 3674c61e3f..eba57450e5 100644 --- a/resources/profiles/Cubicon/filament/Cubicon PLA+ @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon PLA+ @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon PLA+ @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon PLA+ @base", "renamed_from": "Cubicon PLA+ @base", + "inherits": "Cubicon PLA+ @base", "from": "system", "setting_id": "fNR2Bw3e4TGcWhq0", "filament_id": "OF7tt7DO", diff --git a/resources/profiles/Cubicon/filament/Cubicon PLAi21 @Cubicon xCeler-I 0.4 nozzle.json b/resources/profiles/Cubicon/filament/Cubicon PLAi21 @Cubicon xCeler-I 0.4 nozzle.json index 74bff5f995..374e068198 100644 --- a/resources/profiles/Cubicon/filament/Cubicon PLAi21 @Cubicon xCeler-I 0.4 nozzle.json +++ b/resources/profiles/Cubicon/filament/Cubicon PLAi21 @Cubicon xCeler-I 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Cubicon PLAi21 @Cubicon xCeler-I 0.4 nozzle", - "inherits": "Cubicon PLAi21 @base", "renamed_from": "Cubicon PLAi21 @base", + "inherits": "Cubicon PLAi21 @base", "from": "system", "setting_id": "vcLVF3cglagBfVAF", "filament_id": "OFRhBryT", diff --git a/resources/profiles/Custom.json b/resources/profiles/Custom.json index aceecc557a..afbcdacbe8 100644 --- a/resources/profiles/Custom.json +++ b/resources/profiles/Custom.json @@ -1,6 +1,6 @@ { "name": "Custom Printer", - "version": "02.04.00.05", + "version": "02.04.00.07", "force_update": "0", "description": "My configurations", "machine_model_list": [ diff --git a/resources/profiles/Custom/filament/Generic ABS @MyToolChanger.json b/resources/profiles/Custom/filament/Generic ABS @MyToolChanger.json index 615d3aafa4..3b55c98554 100644 --- a/resources/profiles/Custom/filament/Generic ABS @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic ABS @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "h83PqSYsAi8yZyg0", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "0.926", + "0.926", + "0.926" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "20", + "25" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "260", + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260", + "260" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic ASA @MyToolChanger.json b/resources/profiles/Custom/filament/Generic ASA @MyToolChanger.json index cef361767f..d5d74a280c 100644 --- a/resources/profiles/Custom/filament/Generic ASA @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic ASA @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "WllFTKxFejz4prhD", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "0.926", + "0.926", + "0.926" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "20", + "25" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "260", + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260", + "260" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PA @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PA @MyToolChanger.json index f8a3f9d4ff..047a5f4584 100644 --- a/resources/profiles/Custom/filament/Generic PA @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PA @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "Lw6e7YMy0J5Flnjj", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "1", + "1", + "1" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "8", + "12", + "12" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "280", + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280", + "280" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PA-CF @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PA-CF @MyToolChanger.json index 3db93c2e10..cc86241941 100644 --- a/resources/profiles/Custom/filament/Generic PA-CF @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PA-CF @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "0NPQJ9aRrfjAqLeX", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "1", + "1", + "1" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "8", + "8", + "8" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "280", + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280", + "280" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PC @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PC @MyToolChanger.json index 8fbc18b513..310d50a16d 100644 --- a/resources/profiles/Custom/filament/Generic PC @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PC @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "HMOa2jbj19Xjipt5", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "0.94", + "0.94", + "0.94" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "20", + "30" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "280", + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270", + "270" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PETG @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PETG @MyToolChanger.json index faba4cf7cb..ebe6728fe9 100644 --- a/resources/profiles/Custom/filament/Generic PETG @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PETG @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "4qShNrl9EWAVBfeG", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "1", + "1", + "1" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "10", + "18", + "21" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "255", + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255", + "255" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PLA @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PLA @MyToolChanger.json index 5f20b83ec5..557e432016 100644 --- a/resources/profiles/Custom/filament/Generic PLA @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PLA @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "WbAYFZdqFwEZnNAX", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "21", + "40" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "220", + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220", + "220" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PLA-CF @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PLA-CF @MyToolChanger.json index ccfc71ebb7..f7df427b1e 100644 --- a/resources/profiles/Custom/filament/Generic PLA-CF @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PLA-CF @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "53UFt3Q63NB0ztlP", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "18", + "18" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "220", + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220", + "220" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic PVA @MyToolChanger.json b/resources/profiles/Custom/filament/Generic PVA @MyToolChanger.json index 67a46e0129..dce39dc311 100644 --- a/resources/profiles/Custom/filament/Generic PVA @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic PVA @MyToolChanger.json @@ -6,6 +6,111 @@ "from": "system", "setting_id": "dyOUyXNOKP1VmSal", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "4", + "4", + "4" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "220", + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220", + "220" + ], "filament_cooling_final_speed": [ "3.5" ], diff --git a/resources/profiles/Custom/filament/Generic TPU @MyToolChanger.json b/resources/profiles/Custom/filament/Generic TPU @MyToolChanger.json index 2527ff824e..175174d72b 100644 --- a/resources/profiles/Custom/filament/Generic TPU @MyToolChanger.json +++ b/resources/profiles/Custom/filament/Generic TPU @MyToolChanger.json @@ -6,7 +6,109 @@ "from": "system", "setting_id": "H45dfn4BGdLAx9nN", "instantiation": "true", + "activate_air_filtration": [ + "0", + "0", + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70", + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "filament_flow_ratio": [ + "1", + "1", + "1" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "nil" + ], + "nozzle_temperature": [ + "240", + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240", + "240" + ], "filament_max_volumetric_speed": [ + "3.2", + "3.2", "3.2" ], "compatible_printers": [ diff --git a/resources/profiles/Custom/machine/MyKlipper 0.2 nozzle.json b/resources/profiles/Custom/machine/MyKlipper 0.2 nozzle.json index c7686998c0..a692f178f8 100644 --- a/resources/profiles/Custom/machine/MyKlipper 0.2 nozzle.json +++ b/resources/profiles/Custom/machine/MyKlipper 0.2 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "FONwo6mjzIUC1Jfw", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic Klipper Printer", "nozzle_diameter": [ "0.2" diff --git a/resources/profiles/Custom/machine/MyKlipper 0.4 nozzle.json b/resources/profiles/Custom/machine/MyKlipper 0.4 nozzle.json index 6c5bd3fc83..20468e270a 100644 --- a/resources/profiles/Custom/machine/MyKlipper 0.4 nozzle.json +++ b/resources/profiles/Custom/machine/MyKlipper 0.4 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "h7lWobw9IAl6rIFf", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic Klipper Printer", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/Custom/machine/MyKlipper 0.6 nozzle.json b/resources/profiles/Custom/machine/MyKlipper 0.6 nozzle.json index 35a5ca033f..19dd3981dc 100644 --- a/resources/profiles/Custom/machine/MyKlipper 0.6 nozzle.json +++ b/resources/profiles/Custom/machine/MyKlipper 0.6 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "ealoRWEBVYdKQwY4", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic Klipper Printer", "nozzle_diameter": [ "0.6" diff --git a/resources/profiles/Custom/machine/MyKlipper 0.8 nozzle.json b/resources/profiles/Custom/machine/MyKlipper 0.8 nozzle.json index 1dd4e563cf..249dd7f0b3 100644 --- a/resources/profiles/Custom/machine/MyKlipper 0.8 nozzle.json +++ b/resources/profiles/Custom/machine/MyKlipper 0.8 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "ameNjll5Z5Ptmvko", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic Klipper Printer", "nozzle_diameter": [ "0.8" diff --git a/resources/profiles/Custom/machine/MyMarlin 0.4 nozzle.json b/resources/profiles/Custom/machine/MyMarlin 0.4 nozzle.json index a8cff74ece..333e6359ac 100644 --- a/resources/profiles/Custom/machine/MyMarlin 0.4 nozzle.json +++ b/resources/profiles/Custom/machine/MyMarlin 0.4 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "80333z8YjBojDweT", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic Marlin Printer", "gcode_flavor": "marlin", "machine_end_gcode": "G1 E-1.0 F2100 ; retract\nG92 E0.0\nG1{if max_layer_z < max_print_height} Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} E-34.0 F720 ; move print head up & retract filament\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y105 F3000 ; park print head\nM84 ; disable motors", @@ -13,21 +32,33 @@ "0.32" ], "retraction_length": [ + "0.9", + "0.9", "0.9" ], "retraction_minimum_travel": [ + "1", + "1", "1" ], "retraction_speed": [ + "45", + "45", "45" ], "deretraction_speed": [ + "35", + "35", "35" ], "wipe": [ + "0", + "0", "0" ], "z_hop": [ + "0.4", + "0.4", "0.4" ], "nozzle_diameter": [ diff --git a/resources/profiles/Custom/machine/MyRRF 0.4 nozzle.json b/resources/profiles/Custom/machine/MyRRF 0.4 nozzle.json index 492f696697..17c5735fa5 100644 --- a/resources/profiles/Custom/machine/MyRRF 0.4 nozzle.json +++ b/resources/profiles/Custom/machine/MyRRF 0.4 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "eweNs9Rgfgftu6Nw", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic RRF Printer", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/Custom/machine/MyRepetier 0.4 nozzle.json b/resources/profiles/Custom/machine/MyRepetier 0.4 nozzle.json index 0c06ed2dbe..585b444582 100644 --- a/resources/profiles/Custom/machine/MyRepetier 0.4 nozzle.json +++ b/resources/profiles/Custom/machine/MyRepetier 0.4 nozzle.json @@ -5,6 +5,25 @@ "from": "system", "setting_id": "DQo4iCTagLKPE8Kv", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic Repetier Printer", "nozzle_diameter": [ "0.4" @@ -17,4 +36,4 @@ "0x250" ], "printable_height": "250" -} \ No newline at end of file +} diff --git a/resources/profiles/Custom/machine/MyRepetier.json b/resources/profiles/Custom/machine/MyRepetier.json index 7b5a291c72..2cb389a660 100644 --- a/resources/profiles/Custom/machine/MyRepetier.json +++ b/resources/profiles/Custom/machine/MyRepetier.json @@ -9,4 +9,4 @@ "bed_texture": "orcaslicer_bed_texture.svg", "hotend_model": "", "default_materials": "Generic ABS @System;Generic PLA @System;Generic PLA-CF @System;Generic PETG @System;Generic TPU @System;Generic ASA @System;Generic PC @System;Generic PVA @System;Generic PA @System;Generic PA-CF @System" -} \ No newline at end of file +} diff --git a/resources/profiles/Custom/machine/MyToolChanger 0.2 nozzle.json b/resources/profiles/Custom/machine/MyToolChanger 0.2 nozzle.json index 0e7d56e99a..1cf35f8809 100644 --- a/resources/profiles/Custom/machine/MyToolChanger 0.2 nozzle.json +++ b/resources/profiles/Custom/machine/MyToolChanger 0.2 nozzle.json @@ -5,6 +5,61 @@ "from": "system", "setting_id": "BFnMQPzSH6GHG60z", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard", + "Standard", + "Standard", + "Standard", + "Standard" + ], + "extruder_type": [ + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic ToolChanger Printer", "nozzle_diameter": [ "0.2", diff --git a/resources/profiles/Custom/machine/MyToolChanger 0.4 nozzle.json b/resources/profiles/Custom/machine/MyToolChanger 0.4 nozzle.json index 64a50ed44e..b44db48b01 100644 --- a/resources/profiles/Custom/machine/MyToolChanger 0.4 nozzle.json +++ b/resources/profiles/Custom/machine/MyToolChanger 0.4 nozzle.json @@ -5,6 +5,61 @@ "from": "system", "setting_id": "tJ98aJdTqDwMfyZd", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard", + "Standard", + "Standard", + "Standard", + "Standard" + ], + "extruder_type": [ + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic ToolChanger Printer", "nozzle_diameter": [ "0.4", diff --git a/resources/profiles/Custom/machine/MyToolChanger 0.6 nozzle.json b/resources/profiles/Custom/machine/MyToolChanger 0.6 nozzle.json index fc615ac3d9..d15c22ef43 100644 --- a/resources/profiles/Custom/machine/MyToolChanger 0.6 nozzle.json +++ b/resources/profiles/Custom/machine/MyToolChanger 0.6 nozzle.json @@ -5,6 +5,61 @@ "from": "system", "setting_id": "rhZgOdaU0sJu9aYF", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard", + "Standard", + "Standard", + "Standard", + "Standard" + ], + "extruder_type": [ + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic ToolChanger Printer", "nozzle_diameter": [ "0.6", diff --git a/resources/profiles/Custom/machine/MyToolChanger 0.8 nozzle.json b/resources/profiles/Custom/machine/MyToolChanger 0.8 nozzle.json index c019a13181..a9ac3fe999 100644 --- a/resources/profiles/Custom/machine/MyToolChanger 0.8 nozzle.json +++ b/resources/profiles/Custom/machine/MyToolChanger 0.8 nozzle.json @@ -5,6 +5,61 @@ "from": "system", "setting_id": "2rsBSbB6oAgBhyy0", "instantiation": "true", + "default_nozzle_volume_type": [ + "Standard", + "Standard", + "Standard", + "Standard", + "Standard" + ], + "extruder_type": [ + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_model": "Generic ToolChanger Printer", "nozzle_diameter": [ "0.8", diff --git a/resources/profiles/Custom/machine/fdm_klipper_common.json b/resources/profiles/Custom/machine/fdm_klipper_common.json index 0080d0ebb0..96e8888c7c 100644 --- a/resources/profiles/Custom/machine/fdm_klipper_common.json +++ b/resources/profiles/Custom/machine/fdm_klipper_common.json @@ -4,64 +4,143 @@ "inherits": "fdm_machine_common", "from": "system", "instantiation": "false", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "gcode_flavor": "klipper", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_e": [ + "25", + "25", + "25", + "25", "25", "25" ], "machine_max_speed_x": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "0.2", + "0.4", + "0.2", + "0.4", "0.2", "0.4" ], @@ -87,39 +166,65 @@ "printer_technology": "FFF", "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", + "1", "1" ], "retract_before_wipe": [ + "70%", + "70%", "70%" ], "retract_when_changing_layer": [ + "1", + "1", "1" ], "retraction_length": [ + "0.8", + "0.8", "0.8" ], "retract_length_toolchange": [ + "2", + "2", "2" ], "z_hop": [ + "0.4", + "0.4", "0.4" ], "retract_restart_extra": [ + "0", + "0", "0" ], "retract_restart_extra_toolchange": [ + "0", + "0", "0" ], "retraction_speed": [ + "30", + "30", "30" ], "deretraction_speed": [ + "30", + "30", "30" ], - "z_hop_types": "Slope Lift", + "z_hop_types": [ + "Slope Lift", + "Slope Lift", + "Slope Lift" + ], "single_extruder_multi_material": "1", "change_filament_gcode": "", "wipe": [ + "1", + "1", "1" ], "default_filament_profile": [ @@ -135,6 +240,10 @@ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", "machine_pause_gcode": "PAUSE", "scan_first_layer": "0", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine", + "undefine" + ], "auxiliary_fan": "0" } diff --git a/resources/profiles/Custom/machine/fdm_machine_common.json b/resources/profiles/Custom/machine/fdm_machine_common.json index bf8f2249cf..10f65cdf80 100644 --- a/resources/profiles/Custom/machine/fdm_machine_common.json +++ b/resources/profiles/Custom/machine/fdm_machine_common.json @@ -3,8 +3,29 @@ "name": "fdm_machine_common", "from": "system", "instantiation": "false", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "printer_technology": "FFF", "deretraction_speed": [ + "40", + "40", "40" ], "extruder_colour": [ @@ -15,45 +36,115 @@ ], "gcode_flavor": "marlin", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "10000", + "10000", + "10000", + "10000", + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "1000", + "1000", + "1000", + "1000", + "1000", "1000" ], "machine_max_acceleration_x": [ + "10000", + "10000", + "10000", + "10000", + "10000", "10000" ], "machine_max_acceleration_y": [ + "10000", + "10000", + "10000", + "10000", + "10000", "10000" ], "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", "500" ], "machine_max_speed_e": [ + "60", + "60", + "60", + "60", + "60", "60" ], "machine_max_speed_x": [ + "500", + "500", + "500", + "500", + "500", "500" ], "machine_max_speed_y": [ + "500", + "500", + "500", + "500", + "500", "500" ], "machine_max_speed_z": [ + "10", + "10", + "10", + "10", + "10", "10" ], "machine_max_jerk_e": [ + "5", + "5", + "5", + "5", + "5", "5" ], "machine_max_jerk_x": [ + "8", + "8", + "8", + "8", + "8", "8" ], "machine_max_jerk_y": [ + "8", + "8", + "8", + "8", + "8", "8" ], "machine_max_jerk_z": [ + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", "0.4" ], "machine_min_extruding_rate": [ @@ -78,35 +169,55 @@ "printer_settings_id": "", "printer_variant": "0.4", "retraction_minimum_travel": [ + "2", + "2", "2" ], "retract_before_wipe": [ + "70%", + "70%", "70%" ], "retract_when_changing_layer": [ + "1", + "1", "1" ], "retraction_length": [ + "1", + "1", "1" ], "retract_length_toolchange": [ + "1", + "1", "1" ], "z_hop": [ + "0", + "0", "0" ], "retract_restart_extra": [ + "0", + "0", "0" ], "retract_restart_extra_toolchange": [ + "0", + "0", "0" ], "retraction_speed": [ + "60", + "60", "60" ], "single_extruder_multi_material": "1", "change_filament_gcode": "", "wipe": [ + "1", + "1", "1" ], "default_print_profile": "", diff --git a/resources/profiles/Custom/machine/fdm_repetier_common.json b/resources/profiles/Custom/machine/fdm_repetier_common.json index 27b4dd7741..7cb3faf648 100644 --- a/resources/profiles/Custom/machine/fdm_repetier_common.json +++ b/resources/profiles/Custom/machine/fdm_repetier_common.json @@ -4,66 +4,145 @@ "inherits": "fdm_machine_common", "from": "system", "instantiation": "false", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "gcode_flavor": "repetier", "disable_m73": "1", "emit_machine_limits_to_gcode": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_e": [ + "25", + "25", + "25", + "25", "25", "25" ], "machine_max_speed_x": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "0.2", + "0.4", + "0.2", + "0.4", "0.2", "0.4" ], @@ -89,39 +168,65 @@ "printer_technology": "FFF", "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", + "1", "1" ], "retract_before_wipe": [ + "70%", + "70%", "70%" ], "retract_when_changing_layer": [ + "1", + "1", "1" ], "retraction_length": [ + "0.8", + "0.8", "0.8" ], "retract_length_toolchange": [ + "2", + "2", "2" ], "z_hop": [ + "0.4", + "0.4", "0.4" ], "retract_restart_extra": [ + "0", + "0", "0" ], "retract_restart_extra_toolchange": [ + "0", + "0", "0" ], "retraction_speed": [ + "30", + "30", "30" ], "deretraction_speed": [ + "30", + "30", "30" ], - "z_hop_types": "Slope Lift", + "z_hop_types": [ + "Slope Lift", + "Slope Lift", + "Slope Lift" + ], "single_extruder_multi_material": "1", "change_filament_gcode": "", "wipe": [ + "1", + "1", "1" ], "default_filament_profile": [ @@ -137,6 +242,10 @@ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", "machine_pause_gcode": "G91\nG1 Z10 F900\nG90\nG1 X0 Y0 F6000\n", "scan_first_layer": "0", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine", + "undefine" + ], "auxiliary_fan": "0" } diff --git a/resources/profiles/Custom/machine/fdm_rrf_common.json b/resources/profiles/Custom/machine/fdm_rrf_common.json index e9a1301622..e85c6977ad 100644 --- a/resources/profiles/Custom/machine/fdm_rrf_common.json +++ b/resources/profiles/Custom/machine/fdm_rrf_common.json @@ -4,64 +4,143 @@ "inherits": "fdm_machine_common", "from": "system", "instantiation": "false", + "default_nozzle_volume_type": [ + "Standard" + ], + "extruder_type": [ + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "printer_extruder_id": [ + "1", + "1", + "1" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "gcode_flavor": "reprapfirmware", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_e": [ + "25", + "25", + "25", + "25", "25", "25" ], "machine_max_speed_x": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "0.2", + "0.4", + "0.2", + "0.4", "0.2", "0.4" ], @@ -87,39 +166,65 @@ "printer_technology": "FFF", "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", + "1", "1" ], "retract_before_wipe": [ + "70%", + "70%", "70%" ], "retract_when_changing_layer": [ + "1", + "1", "1" ], "retraction_length": [ + "0.8", + "0.8", "0.8" ], "retract_length_toolchange": [ + "2", + "2", "2" ], "z_hop": [ + "0.4", + "0.4", "0.4" ], "retract_restart_extra": [ + "0", + "0", "0" ], "retract_restart_extra_toolchange": [ + "0", + "0", "0" ], "retraction_speed": [ + "30", + "30", "30" ], "deretraction_speed": [ + "30", + "30", "30" ], - "z_hop_types": "Slope Lift", + "z_hop_types": [ + "Slope Lift", + "Slope Lift", + "Slope Lift" + ], "single_extruder_multi_material": "1", "change_filament_gcode": "", "wipe": [ + "1", + "1", "1" ], "default_filament_profile": [ @@ -130,7 +235,11 @@ "0x0" ], "scan_first_layer": "0", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine", + "undefine" + ], "auxiliary_fan": "0", "machine_start_gcode": "; Prime Filament Sensor for Runout\nM581 P1 T2 S-1 R0\nM950 J1 C\"nil\" ; Input 1 e0 Filament Sensor \nM591 D0 P2 C\"e0stop\" S1 ; Filament Runout Sensor\n\nM83 ; extruder relative mode\n\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 S140 ; Set extruder temp 140C before bed level\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\n;G28 W\nG32 ; Levels Z Tilt and probes Z=0\nG29 S0 ; mesh bed leveling\nG1 X0 Y0 Z2 F2000\nM109 S[first_layer_temperature] ; wait for extruder temp\n\nG1 X10 Y-7 Z0.3 F1000.0 ; go outside print area\nG92 E0.0\nG1 Z0.2 E8 ; Purge Bubble\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0", "machine_end_gcode": "{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nG1 X0 Y200 F3600 ; park\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+49, max_print_height)} F720 ; Move print head further up{endif}\nM221 S100 ; reset flow\nM900 K0 ; reset LA\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM84 ; disable motors", diff --git a/resources/profiles/Custom/machine/fdm_toolchanger_common.json b/resources/profiles/Custom/machine/fdm_toolchanger_common.json index 55f1b2cadb..3efd27245a 100644 --- a/resources/profiles/Custom/machine/fdm_toolchanger_common.json +++ b/resources/profiles/Custom/machine/fdm_toolchanger_common.json @@ -4,6 +4,541 @@ "inherits": "fdm_klipper_common", "from": "system", "instantiation": "false", + "default_nozzle_volume_type": [ + "Standard", + "Standard", + "Standard", + "Standard", + "Standard" + ], + "extruder_type": [ + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive", + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive Extra High Flow" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4", + "0.2", + "0.4" + ], + "machine_max_speed_e": [ + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25", + "25" + ], + "machine_max_speed_x": [ + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200" + ], + "machine_max_speed_y": [ + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200", + "500", + "200" + ], + "machine_max_speed_z": [ + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12", + "12" + ], + "printer_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "gcode_flavor": "klipper", "single_extruder_multi_material": "0", "wait_for_temp_on_wipe_tower": "1", @@ -26,6 +561,16 @@ "0.08" ], "deretraction_speed": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", "30", "30", "30", @@ -47,6 +592,16 @@ "0x0" ], "long_retractions_when_cut": [ + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", "0", "0", "0", @@ -61,6 +616,16 @@ "0.4" ], "retract_before_wipe": [ + "70%", + "70%", + "70%", + "70%", + "70%", + "70%", + "70%", + "70%", + "70%", + "70%", "70%", "70%", "70%", @@ -68,6 +633,16 @@ "70%" ], "retract_length_toolchange": [ + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", "2", "2", "2", @@ -75,6 +650,16 @@ "2" ], "retract_lift_above": [ + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", "0", "0", "0", @@ -82,6 +667,16 @@ "0" ], "retract_lift_below": [ + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", "0", "0", "0", @@ -89,6 +684,16 @@ "0" ], "retract_lift_enforce": [ + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", + "All Surfaces", "All Surfaces", "All Surfaces", "All Surfaces", @@ -96,6 +701,16 @@ "All Surfaces" ], "retract_restart_extra": [ + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", "0", "0", "0", @@ -103,6 +718,16 @@ "0" ], "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", "0", "0", "0", @@ -110,6 +735,16 @@ "0" ], "retract_when_changing_layer": [ + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", "1", "1", "1", @@ -117,6 +752,16 @@ "1" ], "retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", + "18", + "18", + "18", + "18", + "18", "18", "18", "18", @@ -124,6 +769,16 @@ "18" ], "retraction_length": [ + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", "0.8", "0.8", "0.8", @@ -131,6 +786,16 @@ "0.8" ], "retraction_minimum_travel": [ + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", "1", "1", "1", @@ -138,6 +803,16 @@ "1" ], "retraction_speed": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", "30", "30", "30", @@ -145,6 +820,16 @@ "30" ], "travel_slope": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", "3", "3", "3", @@ -152,6 +837,16 @@ "3" ], "wipe": [ + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", "1", "1", "1", @@ -159,6 +854,16 @@ "1" ], "wipe_distance": [ + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", "1", "1", "1", @@ -166,6 +871,16 @@ "1" ], "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", + "0.4", "0.4", "0.4", "0.4", @@ -173,6 +888,16 @@ "0.4" ], "z_hop_types": [ + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", + "Slope Lift", "Slope Lift", "Slope Lift", "Slope Lift", @@ -184,6 +909,22 @@ "change_filament_gcode": "", "machine_start_gcode": "PRINT_START TOOL_TEMP={first_layer_temperature[initial_tool]} {if is_extruder_used[0]}T0_TEMP={first_layer_temperature[0]}{endif} {if is_extruder_used[1]}T1_TEMP={first_layer_temperature[1]}{endif} {if is_extruder_used[2]}T2_TEMP={first_layer_temperature[2]}{endif} {if is_extruder_used[3]}T3_TEMP={first_layer_temperature[3]}{endif} {if is_extruder_used[4]}T4_TEMP={first_layer_temperature[4]}{endif} {if is_extruder_used[5]}T5_TEMP={first_layer_temperature[5]}{endif} BED_TEMP=[first_layer_bed_temperature] TOOL=[initial_tool]\n\nM83\n; set extruder temp\n{if first_layer_temperature[0] > 0 and (is_extruder_used[0])}M104 T0 S{first_layer_temperature[0]}{endif}\n{if first_layer_temperature[1] > 0 and (is_extruder_used[1])}M104 T1 S{first_layer_temperature[1]}{endif}\n{if first_layer_temperature[2] > 0 and (is_extruder_used[2])}M104 T2 S{first_layer_temperature[2]}{endif}\n{if first_layer_temperature[3] > 0 and (is_extruder_used[3])}M104 T3 S{first_layer_temperature[3]}{endif}\n{if first_layer_temperature[4] > 0 and (is_extruder_used[4])}M104 T4 S{first_layer_temperature[4]}{endif}\n{if (is_extruder_used[0]) and initial_tool != 0}\n;\n; purge first tool\n;\nG1 F{travel_speed * 60}\nM109 T0 S{first_layer_temperature[0]}\nT0; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(0 == 0 ? 0 : (0 == 1 ? 120 : (0 == 2 ? 180 : 300)))} Y{(0 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[0]}10{else}30{endif} X40 Z0.2 F{if filament_multitool_ramming[0]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X40 E9 F800 ; continue purging and wipe the nozzle\nG0 X{40 + 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{40 + 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[0]} F2400 ; retract\n{e_retracted[0] = 1.5 * retract_length[0]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[0] == 0 ? (first_layer_temperature[0] + standby_temperature_delta) : (idle_temperature[0]))} T0\n{endif}\n{if (is_extruder_used[1]) and initial_tool != 1}\n;\n; purge second tool\n;\nG1 F{travel_speed * 60}\nM109 T1 S{first_layer_temperature[1]}\nT1; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(1 == 0 ? 0 : (1 == 1 ? 120 : (1 == 2 ? 180 : 300)))} Y{(1 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[1]}10{else}30{endif} X120 Z0.2 F{if filament_multitool_ramming[1]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X80 E9 F800 ; continue purging and wipe the nozzle\nG0 X{80 - 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{80 - 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[1]} F2400 ; retract\n{e_retracted[1] = 1.5 * retract_length[1]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[1] == 0 ? (first_layer_temperature[1] + standby_temperature_delta) : (idle_temperature[1]))} T1\n{endif}\n{if (is_extruder_used[2]) and initial_tool != 2}\n;\n; purge third tool\n;\nG1 F{travel_speed * 60}\nM109 T2 S{first_layer_temperature[2]}\nT2; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(2 == 0 ? 0 : (2 == 1 ? 120 : (2 == 2 ? 180 : 300)))} Y{(2 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[2]}10{else}30{endif} X220 Z0.2 F{if filament_multitool_ramming[2]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X220 E9 F800 ; continue purging and wipe the nozzle\nG0 X{220 + 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{220 + 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[2]} F2400 ; retract\n{e_retracted[2] = 1.5 * retract_length[2]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[2] == 0 ? (first_layer_temperature[2] + standby_temperature_delta) : (idle_temperature[2]))} T2\n{endif}\n{if (is_extruder_used[3]) and initial_tool != 3}\n;\n; purge fourth tool\n;\nG1 F{travel_speed * 60}\nM109 T3 S{first_layer_temperature[3]}\nT3; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(3 == 0 ? 0 : (3 == 1 ? 120 : (3 == 2 ? 180 : 300)))} Y{(3 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[3]}10{else}30{endif} X290 Z0.2 F{if filament_multitool_ramming[3]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X260 E9 F800 ; continue purging and wipe the nozzle\nG0 X{260 - 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{260 - 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[3]} F2400 ; retract\n{e_retracted[3] = 1.5 * retract_length[3]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[3] == 0 ? (first_layer_temperature[3] + standby_temperature_delta) : (idle_temperature[3]))} T3\n{endif}\n{if (is_extruder_used[4]) and initial_tool != 4}\n;\n; purge fifth tool\n;\nG1 F{travel_speed * 60}\nM109 T4 S{first_layer_temperature[4]}\nT4; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(4 == 0 ? 0 : (4 == 1 ? 120 : (4 == 2 ? 180 : 300)))} Y{(4 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[4]}10{else}30{endif} X290 Z0.2 F{if filament_multitool_ramming[4]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X260 E9 F800 ; continue purging and wipe the nozzle\nG0 X{260 - 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{260 - 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[4]} F2400 ; retract\n{e_retracted[4] = 1.5 * retract_length[4]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[4] == 0 ? (first_layer_temperature[4] + standby_temperature_delta) : (idle_temperature[4]))} T4\n{endif}\n;\n; purge initial tool\n;\nG1 F{travel_speed * 60}\nM109 T{initial_tool} S{first_layer_temperature[initial_tool]}\nT{initial_tool}; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300)))} Y{(initial_tool < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[initial_tool]}10{else}30{endif} X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 10)} Z0.2 F{if filament_multitool_ramming[initial_tool]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 40)} E9 F800 ; continue purging and wipe the nozzle\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 40) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 3)} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 40) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 3 * 2)} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[initial_tool]} F2400 ; retract\n{e_retracted[initial_tool] = 1.5 * retract_length[initial_tool]}\nG92 E0 ; reset extruder position\n", "scan_first_layer": "0", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine", + "undefine" + ], "auxiliary_fan": "0" } diff --git a/resources/profiles/Custom/process/0.08mm Extra Fine @MyKlipper.json b/resources/profiles/Custom/process/0.08mm Extra Fine @MyKlipper.json index 4cebf36eaa..1c52b7de5d 100644 --- a/resources/profiles/Custom/process/0.08mm Extra Fine @MyKlipper.json +++ b/resources/profiles/Custom/process/0.08mm Extra Fine @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "qC4SXEgZNVB9eWNQ", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.08", "bottom_shell_layers": "7", "top_shell_layers": "9", diff --git a/resources/profiles/Custom/process/0.08mm Extra Fine @MyMarlin.json b/resources/profiles/Custom/process/0.08mm Extra Fine @MyMarlin.json index 70c78226a5..5c7847846e 100644 --- a/resources/profiles/Custom/process/0.08mm Extra Fine @MyMarlin.json +++ b/resources/profiles/Custom/process/0.08mm Extra Fine @MyMarlin.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "F0QIJviBIYDJjJe2", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.08", "bottom_shell_layers": "7", "top_shell_layers": "9" diff --git a/resources/profiles/Custom/process/0.08mm Extra Fine @MyRRF.json b/resources/profiles/Custom/process/0.08mm Extra Fine @MyRRF.json index 1c5392cae6..54085435ad 100644 --- a/resources/profiles/Custom/process/0.08mm Extra Fine @MyRRF.json +++ b/resources/profiles/Custom/process/0.08mm Extra Fine @MyRRF.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "zhi1tw9y210xSTmh", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.08", "bottom_shell_layers": "7", "top_shell_layers": "9" diff --git a/resources/profiles/Custom/process/0.08mm Extra Fine @MyToolChanger.json b/resources/profiles/Custom/process/0.08mm Extra Fine @MyToolChanger.json index 17f9df6cac..d1576584e6 100644 --- a/resources/profiles/Custom/process/0.08mm Extra Fine @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.08mm Extra Fine @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "Xt1tNqoffQCMWaDF", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.08", "bottom_shell_layers": "7", "top_shell_layers": "9", diff --git a/resources/profiles/Custom/process/0.12mm Fine @MyKlipper.json b/resources/profiles/Custom/process/0.12mm Fine @MyKlipper.json index e275ffeb1a..6cfed675ba 100644 --- a/resources/profiles/Custom/process/0.12mm Fine @MyKlipper.json +++ b/resources/profiles/Custom/process/0.12mm Fine @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "guUxwo1j4TPACM0Z", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.12", "bottom_shell_layers": "5", "top_shell_layers": "6", diff --git a/resources/profiles/Custom/process/0.12mm Fine @MyMarlin.json b/resources/profiles/Custom/process/0.12mm Fine @MyMarlin.json index 64916a585a..6cc4a2520f 100644 --- a/resources/profiles/Custom/process/0.12mm Fine @MyMarlin.json +++ b/resources/profiles/Custom/process/0.12mm Fine @MyMarlin.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "p7cD7BCjLQtah9z8", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.12", "bottom_shell_layers": "5", "top_shell_layers": "6" diff --git a/resources/profiles/Custom/process/0.12mm Fine @MyRRF.json b/resources/profiles/Custom/process/0.12mm Fine @MyRRF.json index 2d30168abf..99d504fda5 100644 --- a/resources/profiles/Custom/process/0.12mm Fine @MyRRF.json +++ b/resources/profiles/Custom/process/0.12mm Fine @MyRRF.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "Zj9uGAyf8yYuHwRQ", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.12", "bottom_shell_layers": "5", "top_shell_layers": "6" diff --git a/resources/profiles/Custom/process/0.12mm Fine @MyToolChanger.json b/resources/profiles/Custom/process/0.12mm Fine @MyToolChanger.json index 5e3e23f000..840eb680c4 100644 --- a/resources/profiles/Custom/process/0.12mm Fine @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.12mm Fine @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "RjRwftLktZM6uz3u", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.12", "bottom_shell_layers": "5", "top_shell_layers": "6", diff --git a/resources/profiles/Custom/process/0.15mm Optimal @MyKlipper.json b/resources/profiles/Custom/process/0.15mm Optimal @MyKlipper.json index 9036023f45..dd8ff191cb 100644 --- a/resources/profiles/Custom/process/0.15mm Optimal @MyKlipper.json +++ b/resources/profiles/Custom/process/0.15mm Optimal @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "CiHtbxYtXnT5bdRM", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "bottom_shell_layers": "4", "top_shell_layers": "5", "layer_height": "0.15", diff --git a/resources/profiles/Custom/process/0.15mm Optimal @MyMarlin.json b/resources/profiles/Custom/process/0.15mm Optimal @MyMarlin.json index 13236b3640..1c3dfa5239 100644 --- a/resources/profiles/Custom/process/0.15mm Optimal @MyMarlin.json +++ b/resources/profiles/Custom/process/0.15mm Optimal @MyMarlin.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "gkXHi7QQxtxIy9V9", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "bottom_shell_layers": "4", "top_shell_layers": "5", "layer_height": "0.15" diff --git a/resources/profiles/Custom/process/0.15mm Optimal @MyRRF.json b/resources/profiles/Custom/process/0.15mm Optimal @MyRRF.json index dd2d25490e..9d2ba95304 100644 --- a/resources/profiles/Custom/process/0.15mm Optimal @MyRRF.json +++ b/resources/profiles/Custom/process/0.15mm Optimal @MyRRF.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "TcZOJuBSFK5kB1H8", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "bottom_shell_layers": "4", "top_shell_layers": "5", "layer_height": "0.15" diff --git a/resources/profiles/Custom/process/0.15mm Optimal @MyToolChanger.json b/resources/profiles/Custom/process/0.15mm Optimal @MyToolChanger.json index 67c34009a8..6758afab14 100644 --- a/resources/profiles/Custom/process/0.15mm Optimal @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.15mm Optimal @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "kZG2HcARq8ZFzUk9", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "bottom_shell_layers": "4", "top_shell_layers": "5", "layer_height": "0.15", diff --git a/resources/profiles/Custom/process/0.16mm Optimal @MyKlipper.json b/resources/profiles/Custom/process/0.16mm Optimal @MyKlipper.json index 1a1d9a60b1..1718a8a931 100644 --- a/resources/profiles/Custom/process/0.16mm Optimal @MyKlipper.json +++ b/resources/profiles/Custom/process/0.16mm Optimal @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "qMjBH8WRooCfhtTP", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "bottom_shell_layers": "4", "top_shell_layers": "5", "support_top_z_distance": "0.16", diff --git a/resources/profiles/Custom/process/0.16mm Optimal @MyToolChanger.json b/resources/profiles/Custom/process/0.16mm Optimal @MyToolChanger.json index fd035549f6..683c8d29e9 100644 --- a/resources/profiles/Custom/process/0.16mm Optimal @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.16mm Optimal @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "99y1EZwxDuKQwzv3", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "bottom_shell_layers": "4", "top_shell_layers": "5", "support_top_z_distance": "0.16", diff --git a/resources/profiles/Custom/process/0.20mm Standard @MyKlipper.json b/resources/profiles/Custom/process/0.20mm Standard @MyKlipper.json index bb7c196823..34266e7168 100644 --- a/resources/profiles/Custom/process/0.20mm Standard @MyKlipper.json +++ b/resources/profiles/Custom/process/0.20mm Standard @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "UkxcnbdZ2LeRvO4x", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.2", "compatible_printers": [ "MyKlipper 0.4 nozzle", diff --git a/resources/profiles/Custom/process/0.20mm Standard @MyMarlin.json b/resources/profiles/Custom/process/0.20mm Standard @MyMarlin.json index 9ea731097b..78b61e3610 100644 --- a/resources/profiles/Custom/process/0.20mm Standard @MyMarlin.json +++ b/resources/profiles/Custom/process/0.20mm Standard @MyMarlin.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "zZztMlYzzLA0KiTz", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.2", "bottom_shell_layers": "3", "top_shell_layers": "4" diff --git a/resources/profiles/Custom/process/0.20mm Standard @MyRRF.json b/resources/profiles/Custom/process/0.20mm Standard @MyRRF.json index 4c17f18134..ad41f0b413 100644 --- a/resources/profiles/Custom/process/0.20mm Standard @MyRRF.json +++ b/resources/profiles/Custom/process/0.20mm Standard @MyRRF.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "UFkBAddrcwXsuoVt", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.2", "bottom_shell_layers": "3", "top_shell_layers": "4" diff --git a/resources/profiles/Custom/process/0.20mm Standard @MyRepetier.json b/resources/profiles/Custom/process/0.20mm Standard @MyRepetier.json index 63023f1cb5..735b628335 100644 --- a/resources/profiles/Custom/process/0.20mm Standard @MyRepetier.json +++ b/resources/profiles/Custom/process/0.20mm Standard @MyRepetier.json @@ -5,7 +5,17 @@ "from": "system", "setting_id": "Ny9kvyQ0UjkVAUiY", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.2", "bottom_shell_layers": "3", "top_shell_layers": "4" -} \ No newline at end of file +} diff --git a/resources/profiles/Custom/process/0.20mm Standard @MyToolChanger.json b/resources/profiles/Custom/process/0.20mm Standard @MyToolChanger.json index 53dc9dc6c7..9706cd10b5 100644 --- a/resources/profiles/Custom/process/0.20mm Standard @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.20mm Standard @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "MHpNmkShui6fTwVu", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.2", "compatible_printers": [ "MyToolChanger 0.4 nozzle", diff --git a/resources/profiles/Custom/process/0.24mm Draft @MyKlipper.json b/resources/profiles/Custom/process/0.24mm Draft @MyKlipper.json index f54829e461..80191bedea 100644 --- a/resources/profiles/Custom/process/0.24mm Draft @MyKlipper.json +++ b/resources/profiles/Custom/process/0.24mm Draft @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "E5SAhAOy240BOYOB", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.2", "support_bottom_z_distance": "0.2", "layer_height": "0.24", diff --git a/resources/profiles/Custom/process/0.24mm Draft @MyMarlin.json b/resources/profiles/Custom/process/0.24mm Draft @MyMarlin.json index 2f75b3af69..c3ab4c7dcf 100644 --- a/resources/profiles/Custom/process/0.24mm Draft @MyMarlin.json +++ b/resources/profiles/Custom/process/0.24mm Draft @MyMarlin.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "HjdvHJl5dBqwwOiq", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.24", "top_surface_line_width": "0.45", "bottom_shell_layers": "3", diff --git a/resources/profiles/Custom/process/0.24mm Draft @MyRRF.json b/resources/profiles/Custom/process/0.24mm Draft @MyRRF.json index 4da6be51ee..0561313f06 100644 --- a/resources/profiles/Custom/process/0.24mm Draft @MyRRF.json +++ b/resources/profiles/Custom/process/0.24mm Draft @MyRRF.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "lh4F2302iVSyXP0D", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.24", "top_surface_line_width": "0.45", "bottom_shell_layers": "3", diff --git a/resources/profiles/Custom/process/0.24mm Draft @MyToolChanger.json b/resources/profiles/Custom/process/0.24mm Draft @MyToolChanger.json index b16f1bcf0c..b3d7f7c91d 100644 --- a/resources/profiles/Custom/process/0.24mm Draft @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.24mm Draft @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "2V93QpRMBE9OU5Ak", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.2", "support_bottom_z_distance": "0.2", "layer_height": "0.24", diff --git a/resources/profiles/Custom/process/0.28mm Extra Draft @MyKlipper.json b/resources/profiles/Custom/process/0.28mm Extra Draft @MyKlipper.json index 0a9a9c3316..6c7aeb10fd 100644 --- a/resources/profiles/Custom/process/0.28mm Extra Draft @MyKlipper.json +++ b/resources/profiles/Custom/process/0.28mm Extra Draft @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "Wxgntm1oFqaS5sSD", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.28", "initial_layer_print_height": "0.2", "compatible_printers": [ diff --git a/resources/profiles/Custom/process/0.28mm Extra Draft @MyMarlin.json b/resources/profiles/Custom/process/0.28mm Extra Draft @MyMarlin.json index dc59a3bc35..4bbb83dcd2 100644 --- a/resources/profiles/Custom/process/0.28mm Extra Draft @MyMarlin.json +++ b/resources/profiles/Custom/process/0.28mm Extra Draft @MyMarlin.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "FPRthCpiEQtZgF7W", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.28", "top_surface_line_width": "0.45", "bottom_shell_layers": "3", diff --git a/resources/profiles/Custom/process/0.28mm Extra Draft @MyRRF.json b/resources/profiles/Custom/process/0.28mm Extra Draft @MyRRF.json index 09c9dba77c..f41c7a1b13 100644 --- a/resources/profiles/Custom/process/0.28mm Extra Draft @MyRRF.json +++ b/resources/profiles/Custom/process/0.28mm Extra Draft @MyRRF.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "KWkOr3YqJ2Jf3UAF", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.28", "top_surface_line_width": "0.45", "bottom_shell_layers": "3", diff --git a/resources/profiles/Custom/process/0.28mm Extra Draft @MyToolChanger.json b/resources/profiles/Custom/process/0.28mm Extra Draft @MyToolChanger.json index d069bcc819..2fab506db7 100644 --- a/resources/profiles/Custom/process/0.28mm Extra Draft @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.28mm Extra Draft @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "q6Bc7ar365O7vKe3", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "layer_height": "0.28", "initial_layer_print_height": "0.2", "compatible_printers": [ diff --git a/resources/profiles/Custom/process/0.32mm Extra Draft @MyKlipper.json b/resources/profiles/Custom/process/0.32mm Extra Draft @MyKlipper.json index 4db0c96be0..57ac63f76b 100644 --- a/resources/profiles/Custom/process/0.32mm Extra Draft @MyKlipper.json +++ b/resources/profiles/Custom/process/0.32mm Extra Draft @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "b3MuRrAWKYtKZM79", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "layer_height": "0.32", diff --git a/resources/profiles/Custom/process/0.32mm Extra Draft @MyToolChanger.json b/resources/profiles/Custom/process/0.32mm Extra Draft @MyToolChanger.json index 0dcd2fb762..df929ad1b7 100644 --- a/resources/profiles/Custom/process/0.32mm Extra Draft @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.32mm Extra Draft @MyToolChanger.json @@ -6,6 +6,40 @@ "from": "system", "setting_id": "7cM9iT4GyGhmfwHu", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "layer_height": "0.32", diff --git a/resources/profiles/Custom/process/0.40mm Extra Draft @MyKlipper.json b/resources/profiles/Custom/process/0.40mm Extra Draft @MyKlipper.json index 74bce75980..eb66511d10 100644 --- a/resources/profiles/Custom/process/0.40mm Extra Draft @MyKlipper.json +++ b/resources/profiles/Custom/process/0.40mm Extra Draft @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "bc0WLUlEcdg9LWE5", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "layer_height": "0.40", diff --git a/resources/profiles/Custom/process/0.40mm Extra Draft @MyToolChanger.json b/resources/profiles/Custom/process/0.40mm Extra Draft @MyToolChanger.json index 4922fdb747..365fc27fd9 100644 --- a/resources/profiles/Custom/process/0.40mm Extra Draft @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.40mm Extra Draft @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "BnN85WtRYfMwpdV0", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "layer_height": "0.40", diff --git a/resources/profiles/Custom/process/0.56mm Extra Draft @MyKlipper.json b/resources/profiles/Custom/process/0.56mm Extra Draft @MyKlipper.json index f470958a24..f81887191a 100644 --- a/resources/profiles/Custom/process/0.56mm Extra Draft @MyKlipper.json +++ b/resources/profiles/Custom/process/0.56mm Extra Draft @MyKlipper.json @@ -5,6 +5,16 @@ "from": "system", "setting_id": "ivoHEUPxZxSxGmrh", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "layer_height": "0.56", diff --git a/resources/profiles/Custom/process/0.56mm Extra Draft @MyToolChanger.json b/resources/profiles/Custom/process/0.56mm Extra Draft @MyToolChanger.json index 226610bfc2..3b380c1868 100644 --- a/resources/profiles/Custom/process/0.56mm Extra Draft @MyToolChanger.json +++ b/resources/profiles/Custom/process/0.56mm Extra Draft @MyToolChanger.json @@ -5,6 +5,40 @@ "from": "system", "setting_id": "Pky5GvEuSlaG1Lvm", "instantiation": "true", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "layer_height": "0.56", diff --git a/resources/profiles/Custom/process/fdm_process_common.json b/resources/profiles/Custom/process/fdm_process_common.json index 0d558129af..55b4a58665 100644 --- a/resources/profiles/Custom/process/fdm_process_common.json +++ b/resources/profiles/Custom/process/fdm_process_common.json @@ -3,22 +3,60 @@ "name": "fdm_process_common", "from": "system", "instantiation": "false", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "reduce_crossing_wall": "0", "max_travel_detour_distance": "0", "bottom_surface_pattern": "monotonic", "bottom_shell_thickness": "0", - "bridge_speed": "50", + "bridge_speed": [ + "50", + "50", + "50" + ], "brim_width": "5", "brim_object_gap": "0.1", "compatible_printers": [], "compatible_printers_condition": "", "print_sequence": "by layer", - "default_acceleration": "1000", - "initial_layer_acceleration": "500", - "top_surface_acceleration": "1000", - "travel_acceleration": "1000", - "inner_wall_acceleration": "1000", - "outer_wall_acceleration": "700", + "default_acceleration": [ + "1000", + "1000", + "1000" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500" + ], + "top_surface_acceleration": [ + "1000", + "1000", + "1000" + ], + "travel_acceleration": [ + "1000", + "1000", + "1000" + ], + "inner_wall_acceleration": [ + "1000", + "1000", + "1000" + ], + "outer_wall_acceleration": [ + "700", + "700", + "700" + ], "bridge_no_support": "0", "draft_shield": "disabled", "elefant_foot_compensation": "0", @@ -38,11 +76,31 @@ "reduce_infill_retraction": "1", "filename_format": "{input_filename_base}_{layer_height}mm_{filament_type[initial_tool]}_{printer_model}_{print_time}.gcode", "detect_overhang_wall": "1", - "slowdown_for_curled_perimeters": "1", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", + "slowdown_for_curled_perimeters": [ + "1", + "1", + "1" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10" + ], "line_width": "110%", "inner_wall_line_width": "110%", "outer_wall_line_width": "100%", @@ -74,10 +132,18 @@ "support_interface_top_layers": "2", "support_interface_bottom_layers": "2", "support_interface_spacing": "0.5", - "support_interface_speed": "80", + "support_interface_speed": [ + "80", + "80", + "80" + ], "support_base_pattern": "default", "support_base_pattern_spacing": "2.5", - "support_speed": "150", + "support_speed": [ + "150", + "150", + "150" + ], "support_threshold_angle": "30", "support_object_xy_distance": "0.35", "tree_support_branch_angle": "30", @@ -94,13 +160,49 @@ "bottom_shell_layers": "3", "top_shell_layers": "4", "bridge_flow": "1", - "initial_layer_speed": "45", - "initial_layer_infill_speed": "45", - "outer_wall_speed": "45", - "inner_wall_speed": "80", - "sparse_infill_speed": "150", - "internal_solid_infill_speed": "150", - "top_surface_speed": "50", - "gap_infill_speed": "30", - "travel_speed": "200" + "initial_layer_speed": [ + "45", + "45", + "45" + ], + "initial_layer_infill_speed": [ + "45", + "45", + "45" + ], + "outer_wall_speed": [ + "45", + "45", + "45" + ], + "inner_wall_speed": [ + "80", + "80", + "80" + ], + "sparse_infill_speed": [ + "150", + "150", + "150" + ], + "internal_solid_infill_speed": [ + "150", + "150", + "150" + ], + "top_surface_speed": [ + "50", + "50", + "50" + ], + "gap_infill_speed": [ + "30", + "30", + "30" + ], + "travel_speed": [ + "200", + "200", + "200" + ] } diff --git a/resources/profiles/Custom/process/fdm_process_klipper_common.json b/resources/profiles/Custom/process/fdm_process_klipper_common.json index 2977d9392a..d24268b0c6 100644 --- a/resources/profiles/Custom/process/fdm_process_klipper_common.json +++ b/resources/profiles/Custom/process/fdm_process_klipper_common.json @@ -4,20 +4,90 @@ "inherits": "fdm_process_common", "from": "system", "instantiation": "false", - "default_acceleration": "5000", - "top_surface_acceleration": "3000", - "travel_acceleration": "7000", - "inner_wall_acceleration": "5000", - "outer_wall_acceleration": "3000", - "initial_layer_acceleration": "500", - "initial_layer_speed": "50", - "initial_layer_infill_speed": "105", - "outer_wall_speed": "120", - "inner_wall_speed": "200", - "internal_solid_infill_speed": "200", - "top_surface_speed": "100", - "gap_infill_speed": "100", - "sparse_infill_speed": "200", - "travel_speed": "350", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "default_acceleration": [ + "5000", + "5000", + "5000" + ], + "top_surface_acceleration": [ + "3000", + "3000", + "3000" + ], + "travel_acceleration": [ + "7000", + "7000", + "7000" + ], + "inner_wall_acceleration": [ + "5000", + "5000", + "5000" + ], + "outer_wall_acceleration": [ + "3000", + "3000", + "3000" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500" + ], + "initial_layer_speed": [ + "50", + "50", + "50" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105" + ], + "outer_wall_speed": [ + "120", + "120", + "120" + ], + "inner_wall_speed": [ + "200", + "200", + "200" + ], + "internal_solid_infill_speed": [ + "200", + "200", + "200" + ], + "top_surface_speed": [ + "100", + "100", + "100" + ], + "gap_infill_speed": [ + "100", + "100", + "100" + ], + "sparse_infill_speed": [ + "200", + "200", + "200" + ], + "travel_speed": [ + "350", + "350", + "350" + ], "exclude_object": "1" } diff --git a/resources/profiles/Custom/process/fdm_process_marlin_common.json b/resources/profiles/Custom/process/fdm_process_marlin_common.json index 5f5c10f173..f15c13984b 100644 --- a/resources/profiles/Custom/process/fdm_process_marlin_common.json +++ b/resources/profiles/Custom/process/fdm_process_marlin_common.json @@ -4,22 +4,56 @@ "inherits": "fdm_process_common", "from": "system", "instantiation": "false", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "reduce_crossing_wall": "0", "max_travel_detour_distance": "0", "bottom_surface_pattern": "monotonic", "bottom_shell_layers": "3", "bottom_shell_thickness": "0", "bridge_flow": "0.95", - "bridge_speed": "50", + "bridge_speed": [ + "50", + "50", + "50" + ], "brim_width": "5", "brim_object_gap": "0.1", "compatible_printers_condition": "", "print_sequence": "by layer", - "default_acceleration": "1000", - "top_surface_acceleration": "1000", - "travel_acceleration": "1000", - "inner_wall_acceleration": "1000", - "outer_wall_acceleration": "1000", + "default_acceleration": [ + "1000", + "1000", + "1000" + ], + "top_surface_acceleration": [ + "1000", + "1000", + "1000" + ], + "travel_acceleration": [ + "1000", + "1000", + "1000" + ], + "inner_wall_acceleration": [ + "1000", + "1000", + "1000" + ], + "outer_wall_acceleration": [ + "1000", + "1000", + "1000" + ], "bridge_no_support": "0", "draft_shield": "disabled", "elefant_foot_compensation": "0", @@ -29,7 +63,11 @@ "infill_direction": "45", "sparse_infill_density": "15%", "sparse_infill_pattern": "crosshatch", - "initial_layer_acceleration": "500", + "initial_layer_acceleration": [ + "500", + "500", + "500" + ], "initial_layer_line_width": "0.5", "initial_layer_print_height": "0.2", "infill_combination": "0", @@ -44,10 +82,26 @@ "reduce_infill_retraction": "1", "filename_format": "{input_filename_base}_{filament_type[initial_tool]}_{print_time}.gcode", "detect_overhang_wall": "1", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", + "overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10" + ], "inner_wall_line_width": "0.45", "wall_loops": "3", "print_settings_id": "", @@ -73,10 +127,18 @@ "support_interface_top_layers": "2", "support_interface_bottom_layers": "2", "support_interface_spacing": "0.5", - "support_interface_speed": "40", + "support_interface_speed": [ + "40", + "40", + "40" + ], "support_base_pattern": "rectilinear", "support_base_pattern_spacing": "2.5", - "support_speed": "60", + "support_speed": [ + "60", + "60", + "60" + ], "support_threshold_angle": "30", "support_object_xy_distance": "0.35", "tree_support_branch_angle": "45", @@ -86,15 +148,51 @@ "top_surface_line_width": "0.4", "top_shell_layers": "3", "top_shell_thickness": "0.8", - "initial_layer_speed": "45", - "initial_layer_infill_speed": "60", - "outer_wall_speed": "60", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "top_surface_speed": "50", - "gap_infill_speed": "80", - "sparse_infill_speed": "80", - "travel_speed": "150", + "initial_layer_speed": [ + "45", + "45", + "45" + ], + "initial_layer_infill_speed": [ + "60", + "60", + "60" + ], + "outer_wall_speed": [ + "60", + "60", + "60" + ], + "inner_wall_speed": [ + "80", + "80", + "80" + ], + "internal_solid_infill_speed": [ + "80", + "80", + "80" + ], + "top_surface_speed": [ + "50", + "50", + "50" + ], + "gap_infill_speed": [ + "80", + "80", + "80" + ], + "sparse_infill_speed": [ + "80", + "80", + "80" + ], + "travel_speed": [ + "150", + "150", + "150" + ], "enable_prime_tower": "1", "wipe_tower_no_sparse_layers": "0", "prime_tower_width": "60", diff --git a/resources/profiles/Custom/process/fdm_process_mytoolchanger_common.json b/resources/profiles/Custom/process/fdm_process_mytoolchanger_common.json index 95b1b8b497..764a2220c6 100644 --- a/resources/profiles/Custom/process/fdm_process_mytoolchanger_common.json +++ b/resources/profiles/Custom/process/fdm_process_mytoolchanger_common.json @@ -4,21 +4,431 @@ "inherits": "fdm_process_klipper_common", "from": "system", "instantiation": "false", - "default_acceleration": "5000", - "top_surface_acceleration": "3000", - "travel_acceleration": "7000", - "inner_wall_acceleration": "5000", - "outer_wall_acceleration": "3000", - "initial_layer_acceleration": "500", - "initial_layer_speed": "50", - "initial_layer_infill_speed": "105", - "outer_wall_speed": "120", - "inner_wall_speed": "200", - "internal_solid_infill_speed": "200", - "top_surface_speed": "100", - "gap_infill_speed": "100", - "sparse_infill_speed": "200", - "travel_speed": "350", + "print_extruder_id": [ + "1", + "1", + "1", + "2", + "2", + "2", + "3", + "3", + "3", + "4", + "4", + "4", + "5", + "5", + "5" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], + "default_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "top_surface_acceleration": [ + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000" + ], + "travel_acceleration": [ + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000", + "7000" + ], + "inner_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "outer_wall_acceleration": [ + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000", + "3000" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105", + "105" + ], + "outer_wall_speed": [ + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120", + "120" + ], + "inner_wall_speed": [ + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200" + ], + "internal_solid_infill_speed": [ + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200" + ], + "top_surface_speed": [ + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100" + ], + "gap_infill_speed": [ + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100", + "100" + ], + "sparse_infill_speed": [ + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350", + "350" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "slowdown_for_curled_perimeters": [ + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10", + "10" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150", + "150" + ], "exclude_object": "1", "enable_prime_tower": "1", "wipe_tower_cone_angle": "25", diff --git a/resources/profiles/Custom/process/fdm_process_repetier_common.json b/resources/profiles/Custom/process/fdm_process_repetier_common.json index 66df7ad018..daeab13e8e 100644 --- a/resources/profiles/Custom/process/fdm_process_repetier_common.json +++ b/resources/profiles/Custom/process/fdm_process_repetier_common.json @@ -4,22 +4,56 @@ "inherits": "fdm_process_common", "from": "system", "instantiation": "false", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "reduce_crossing_wall": "0", "max_travel_detour_distance": "0", "bottom_surface_pattern": "monotonic", "bottom_shell_layers": "3", "bottom_shell_thickness": "0", "bridge_flow": "0.95", - "bridge_speed": "50", + "bridge_speed": [ + "50", + "50", + "50" + ], "brim_width": "5", "brim_object_gap": "0.1", "compatible_printers_condition": "", "print_sequence": "by layer", - "default_acceleration": "1000", - "top_surface_acceleration": "1000", - "travel_acceleration": "1000", - "inner_wall_acceleration": "1000", - "outer_wall_acceleration": "1000", + "default_acceleration": [ + "1000", + "1000", + "1000" + ], + "top_surface_acceleration": [ + "1000", + "1000", + "1000" + ], + "travel_acceleration": [ + "1000", + "1000", + "1000" + ], + "inner_wall_acceleration": [ + "1000", + "1000", + "1000" + ], + "outer_wall_acceleration": [ + "1000", + "1000", + "1000" + ], "bridge_no_support": "0", "draft_shield": "disabled", "elefant_foot_compensation": "0", @@ -29,7 +63,11 @@ "infill_direction": "45", "sparse_infill_density": "15%", "sparse_infill_pattern": "crosshatch", - "initial_layer_acceleration": "500", + "initial_layer_acceleration": [ + "500", + "500", + "500" + ], "initial_layer_line_width": "0.5", "initial_layer_print_height": "0.2", "infill_combination": "0", @@ -44,10 +82,26 @@ "reduce_infill_retraction": "1", "filename_format": "{input_filename_base}_{filament_type[initial_tool]}_{print_time}.gcode", "detect_overhang_wall": "1", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", + "overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10" + ], "inner_wall_line_width": "0.45", "wall_loops": "3", "print_settings_id": "", @@ -73,10 +127,18 @@ "support_interface_top_layers": "2", "support_interface_bottom_layers": "2", "support_interface_spacing": "0.5", - "support_interface_speed": "40", + "support_interface_speed": [ + "40", + "40", + "40" + ], "support_base_pattern": "rectilinear", "support_base_pattern_spacing": "2.5", - "support_speed": "60", + "support_speed": [ + "60", + "60", + "60" + ], "support_threshold_angle": "30", "support_object_xy_distance": "0.35", "tree_support_branch_angle": "45", @@ -86,15 +148,51 @@ "top_surface_line_width": "0.4", "top_shell_layers": "3", "top_shell_thickness": "0.8", - "initial_layer_speed": "45", - "initial_layer_infill_speed": "60", - "outer_wall_speed": "60", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "top_surface_speed": "50", - "gap_infill_speed": "80", - "sparse_infill_speed": "80", - "travel_speed": "150", + "initial_layer_speed": [ + "45", + "45", + "45" + ], + "initial_layer_infill_speed": [ + "60", + "60", + "60" + ], + "outer_wall_speed": [ + "60", + "60", + "60" + ], + "inner_wall_speed": [ + "80", + "80", + "80" + ], + "internal_solid_infill_speed": [ + "80", + "80", + "80" + ], + "top_surface_speed": [ + "50", + "50", + "50" + ], + "gap_infill_speed": [ + "80", + "80", + "80" + ], + "sparse_infill_speed": [ + "80", + "80", + "80" + ], + "travel_speed": [ + "150", + "150", + "150" + ], "enable_prime_tower": "1", "wipe_tower_no_sparse_layers": "0", "prime_tower_width": "60", diff --git a/resources/profiles/Custom/process/fdm_process_rrf_common.json b/resources/profiles/Custom/process/fdm_process_rrf_common.json index 469ca6ecfd..a87cc59602 100644 --- a/resources/profiles/Custom/process/fdm_process_rrf_common.json +++ b/resources/profiles/Custom/process/fdm_process_rrf_common.json @@ -4,22 +4,56 @@ "inherits": "fdm_process_common", "from": "system", "instantiation": "false", + "print_extruder_id": [ + "1", + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow" + ], "reduce_crossing_wall": "0", "max_travel_detour_distance": "0", "bottom_surface_pattern": "monotonic", "bottom_shell_layers": "3", "bottom_shell_thickness": "0", "bridge_flow": "0.95", - "bridge_speed": "50", + "bridge_speed": [ + "50", + "50", + "50" + ], "brim_width": "5", "brim_object_gap": "0.1", "compatible_printers_condition": "", "print_sequence": "by layer", - "default_acceleration": "5000", - "top_surface_acceleration": "3000", - "travel_acceleration": "7000", - "inner_wall_acceleration": "5000", - "outer_wall_acceleration": "3000", + "default_acceleration": [ + "5000", + "5000", + "5000" + ], + "top_surface_acceleration": [ + "3000", + "3000", + "3000" + ], + "travel_acceleration": [ + "7000", + "7000", + "7000" + ], + "inner_wall_acceleration": [ + "5000", + "5000", + "5000" + ], + "outer_wall_acceleration": [ + "3000", + "3000", + "3000" + ], "bridge_no_support": "0", "draft_shield": "disabled", "elefant_foot_compensation": "0", @@ -29,7 +63,11 @@ "infill_direction": "45", "sparse_infill_density": "15%", "sparse_infill_pattern": "crosshatch", - "initial_layer_acceleration": "500", + "initial_layer_acceleration": [ + "500", + "500", + "500" + ], "initial_layer_line_width": "0.5", "initial_layer_print_height": "0.2", "infill_combination": "0", @@ -44,10 +82,26 @@ "reduce_infill_retraction": "1", "filename_format": "{input_filename_base}_{filament_type[initial_tool]}_{print_time}.gcode", "detect_overhang_wall": "1", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", + "overhang_1_4_speed": [ + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10" + ], "inner_wall_line_width": "0.45", "wall_loops": "3", "print_settings_id": "", @@ -73,10 +127,18 @@ "support_interface_top_layers": "2", "support_interface_bottom_layers": "2", "support_interface_spacing": "0.5", - "support_interface_speed": "80", + "support_interface_speed": [ + "80", + "80", + "80" + ], "support_base_pattern": "rectilinear", "support_base_pattern_spacing": "2.5", - "support_speed": "150", + "support_speed": [ + "150", + "150", + "150" + ], "support_threshold_angle": "30", "support_object_xy_distance": "0.35", "tree_support_branch_angle": "45", @@ -86,15 +148,51 @@ "top_surface_line_width": "0.4", "top_shell_layers": "3", "top_shell_thickness": "0.8", - "initial_layer_speed": "50", - "initial_layer_infill_speed": "105", - "outer_wall_speed": "120", - "inner_wall_speed": "200", - "internal_solid_infill_speed": "200", - "top_surface_speed": "100", - "gap_infill_speed": "100", - "sparse_infill_speed": "200", - "travel_speed": "350", + "initial_layer_speed": [ + "50", + "50", + "50" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105" + ], + "outer_wall_speed": [ + "120", + "120", + "120" + ], + "inner_wall_speed": [ + "200", + "200", + "200" + ], + "internal_solid_infill_speed": [ + "200", + "200", + "200" + ], + "top_surface_speed": [ + "100", + "100", + "100" + ], + "gap_infill_speed": [ + "100", + "100", + "100" + ], + "sparse_infill_speed": [ + "200", + "200", + "200" + ], + "travel_speed": [ + "350", + "350", + "350" + ], "enable_prime_tower": "1", "wipe_tower_no_sparse_layers": "0", "prime_tower_width": "60", diff --git a/resources/profiles/DeltaMaker.json b/resources/profiles/DeltaMaker.json index 6ef943d248..b65109ef68 100755 --- a/resources/profiles/DeltaMaker.json +++ b/resources/profiles/DeltaMaker.json @@ -1,7 +1,7 @@ { "name": "DeltaMaker", "url": "", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "DeltaMaker configurations", "machine_model_list": [ diff --git a/resources/profiles/DeltaMaker/filament/Generic PETG @DeltaMaker.json b/resources/profiles/DeltaMaker/filament/Generic PETG @DeltaMaker.json index a31ad9aec5..a6a788e47e 100755 --- a/resources/profiles/DeltaMaker/filament/Generic PETG @DeltaMaker.json +++ b/resources/profiles/DeltaMaker/filament/Generic PETG @DeltaMaker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @DeltaMaker", - "inherits": "fdm_filament_pet", "renamed_from": "DeltaMaker Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "XmKr3I3RjeI3hm6F", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/DeltaMaker/filament/Generic PLA @DeltaMaker.json b/resources/profiles/DeltaMaker/filament/Generic PLA @DeltaMaker.json index 2e2b626feb..7c448a26f4 100755 --- a/resources/profiles/DeltaMaker/filament/Generic PLA @DeltaMaker.json +++ b/resources/profiles/DeltaMaker/filament/Generic PLA @DeltaMaker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @DeltaMaker", - "inherits": "fdm_filament_pla", "renamed_from": "DeltaMaker Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "ITJo0Cig9myqk1uB", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/DeltaMaker/filament/Generic TPU @DeltaMaker.json b/resources/profiles/DeltaMaker/filament/Generic TPU @DeltaMaker.json index edfc8a1cd2..94a62d4d78 100755 --- a/resources/profiles/DeltaMaker/filament/Generic TPU @DeltaMaker.json +++ b/resources/profiles/DeltaMaker/filament/Generic TPU @DeltaMaker.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @DeltaMaker", - "inherits": "fdm_filament_tpu", "renamed_from": "DeltaMaker Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "uWHBbbhFzvWq0qUP", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Dremel.json b/resources/profiles/Dremel.json index 3d804f6a1b..a57e18fcad 100644 --- a/resources/profiles/Dremel.json +++ b/resources/profiles/Dremel.json @@ -1,6 +1,6 @@ { "name": "Dremel", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "Dremel configurations", "machine_model_list": [ diff --git a/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D20 all.json b/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D20 all.json index 2dbcc6184e..9c3d6d69af 100644 --- a/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D20 all.json +++ b/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D20 all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Dremel 3D20 all", - "inherits": "fdm_filament_pla", "renamed_from": "Dremel Generic PLA @3D20 all;Dremel Generic PLA 3D20 all", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "UggXEvCig0b6S8Vx", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D40 all.json b/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D40 all.json index 03704ce5e9..2a2c9dfa6b 100644 --- a/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D40 all.json +++ b/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D40 all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Dremel 3D40 all", - "inherits": "fdm_filament_pla", "renamed_from": "Dremel Generic PLA @3D40 all;Dremel Generic PLA 3D40 all", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "VUOtsWfy46cvAyBT", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D45 all.json b/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D45 all.json index 78f747e0f9..9b44661579 100644 --- a/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D45 all.json +++ b/resources/profiles/Dremel/filament/Generic PLA @Dremel 3D45 all.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Dremel 3D45 all", - "inherits": "fdm_filament_pla", "renamed_from": "Dremel Generic PLA @3D45 all;Dremel Generic PLA 3D45 all", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "qEeBb3Pix2iDT3SD", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Elegoo.json b/resources/profiles/Elegoo.json index e0580014a9..e85c442406 100644 --- a/resources/profiles/Elegoo.json +++ b/resources/profiles/Elegoo.json @@ -1,6 +1,6 @@ { "name": "Elegoo", - "version": "02.04.00.11", + "version": "02.04.00.12", "force_update": "0", "description": "Elegoo configurations", "machine_model_list": [ diff --git a/resources/profiles/Elegoo/filament/ELEGOO_02_NOZZLE/Elegoo PLA @0.2 nozzle.json b/resources/profiles/Elegoo/filament/ELEGOO_02_NOZZLE/Elegoo PLA @0.2 nozzle.json index 9bfeb0529c..489de9c25e 100644 --- a/resources/profiles/Elegoo/filament/ELEGOO_02_NOZZLE/Elegoo PLA @0.2 nozzle.json +++ b/resources/profiles/Elegoo/filament/ELEGOO_02_NOZZLE/Elegoo PLA @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Elegoo PLA @0.2 nozzle", + "inherits": "Elegoo PLA @base", "from": "system", "setting_id": "g5M60iK3oBpmDv68", "instantiation": "true", - "inherits": "Elegoo PLA @base", "filament_max_volumetric_speed": [ "3.2" ], diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo ASA @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo ASA @Elegoo Giga.json index fca1b001a8..186df48f9d 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo ASA @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo ASA @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo ASA @Elegoo Giga", + "renamed_from": "Elegoo ASA @EOS Giga", "inherits": "Elegoo ASA @base", "from": "system", "setting_id": "YEKtGrB8gsvKz8XQ", @@ -19,6 +20,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo ASA @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG @Elegoo Giga.json index fa02324356..eb3d9bddbe 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PETG @Elegoo Giga", + "renamed_from": "Elegoo PETG @EOS Giga", "inherits": "Elegoo PETG @base", "from": "system", "setting_id": "7XyTDotf1zFmCPTV", @@ -25,6 +26,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PETG @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG PRO @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG PRO @Elegoo Giga.json index bf3942c6c9..63daca52b0 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG PRO @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG PRO @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PETG PRO @Elegoo Giga", + "renamed_from": "Elegoo PETG PRO @EOS Giga", "inherits": "Elegoo PETG PRO @base", "from": "system", "setting_id": "cO87yMETWbUTIweN", @@ -13,6 +14,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PETG PRO @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG Translucent @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG Translucent @Elegoo Giga.json index 89b17d0d8c..5ecda636ba 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG Translucent @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG Translucent @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PETG Translucent @Elegoo Giga", + "renamed_from": "Elegoo PETG Translucent @EOS Giga", "inherits": "Elegoo PETG Translucent @base", "from": "system", "setting_id": "fkE2LCMu63t1NQtI", @@ -25,6 +26,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PETG Translucent @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-CF @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-CF @Elegoo Giga.json index 633fee4d01..38129125b9 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-CF @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-CF @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PETG-CF @Elegoo Giga", + "renamed_from": "Elegoo PETG-CF @EOS Giga", "inherits": "Elegoo PETG-CF @base", "from": "system", "setting_id": "uGF6puqnX1jW2pmn", @@ -40,6 +41,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PETG-CF @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-GF @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-GF @Elegoo Giga.json index 085eba8e80..dce4172270 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-GF @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PETG-GF @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PETG-GF @Elegoo Giga", + "renamed_from": "Elegoo PETG-GF @EOS Giga", "inherits": "Elegoo PETG-GF @base", "from": "system", "setting_id": "S4ZpKZDyr5g5HMPi", @@ -40,6 +41,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PETG-GF @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA @Elegoo Giga.json index 32d6f6a1eb..40a421724c 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA @Elegoo Giga", + "renamed_from": "Elegoo PLA @EOS Giga", "inherits": "Elegoo PLA @base", "from": "system", "setting_id": "DzHDGa5SJa8wdZkD", @@ -13,6 +14,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Basic @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Basic @Elegoo Giga.json index 345eb9b131..0cc99c36ef 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Basic @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Basic @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Basic @Elegoo Giga", + "renamed_from": "Elegoo PLA Basic @EOS Giga", "inherits": "Elegoo PLA Basic @base", "from": "system", "setting_id": "vdtyGUjloveBjsGV", @@ -28,6 +29,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA Basic @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Galaxy @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Galaxy @Elegoo Giga.json index 4c6df1a2ac..41da71fe96 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Galaxy @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Galaxy @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Galaxy @Elegoo Giga", + "renamed_from": "Elegoo PLA Galaxy @EOS Giga", "inherits": "Elegoo PLA Galaxy @base", "from": "system", "setting_id": "Nq1YaFeJ6Osr7OZ9", @@ -31,6 +32,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA Galaxy @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Marble @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Marble @Elegoo Giga.json index a76087fb41..e4eaa97f9b 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Marble @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Marble @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Marble @Elegoo Giga", + "renamed_from": "Elegoo PLA Marble @EOS Giga", "inherits": "Elegoo PLA Marble @base", "from": "system", "setting_id": "6mfjc7t9ntuG1ZKW", @@ -31,6 +32,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA Marble @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Matte @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Matte @Elegoo Giga.json index ebc4a86a33..2699fa1860 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Matte @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Matte @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Matte @Elegoo Giga", + "renamed_from": "Elegoo PLA Matte @EOS Giga", "inherits": "Elegoo PLA Matte @base", "from": "system", "setting_id": "mHbvYB78eds96SH8", @@ -37,6 +38,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA Matte @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Sparkle @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Sparkle @Elegoo Giga.json index 68ad38e31a..e744828b49 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Sparkle @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Sparkle @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Sparkle @Elegoo Giga", + "renamed_from": "Elegoo PLA Sparkle @EOS Giga", "inherits": "Elegoo PLA Sparkle @base", "from": "system", "setting_id": "pgsOuYMxtcm3Fkar", @@ -31,6 +32,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA Sparkle @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Wood @Elegoo Giga.json b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Wood @Elegoo Giga.json index 2d3118d9f9..511b3a538a 100644 --- a/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Wood @Elegoo Giga.json +++ b/resources/profiles/Elegoo/filament/EOSGIGA/Elegoo PLA Wood @Elegoo Giga.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Wood @Elegoo Giga", + "renamed_from": "Elegoo PLA Wood @EOS Giga", "inherits": "Elegoo PLA Wood @base", "from": "system", "setting_id": "BI2euv7xwM9F2hKC", @@ -31,6 +32,5 @@ "Elegoo OrangeStorm Giga 0.6 nozzle", "Elegoo OrangeStorm Giga 0.8 nozzle", "Elegoo OrangeStorm Giga 1.0 nozzle" - ], - "renamed_from": "Elegoo PLA Wood @EOS Giga" + ] } diff --git a/resources/profiles/Elegoo/filament/Generic/Generic ABS @Elegoo.json b/resources/profiles/Elegoo/filament/Generic/Generic ABS @Elegoo.json index ff56f113f1..bf95116cca 100644 --- a/resources/profiles/Elegoo/filament/Generic/Generic ABS @Elegoo.json +++ b/resources/profiles/Elegoo/filament/Generic/Generic ABS @Elegoo.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "RWcQPhlCtjoh9xec", "name": "Generic ABS @Elegoo", - "from": "system", - "instantiation": "true", "inherits": "Generic ABS @base", + "from": "system", + "setting_id": "RWcQPhlCtjoh9xec", + "instantiation": "true", "cool_plate_temp": [ "100" ], diff --git a/resources/profiles/Elegoo/filament/Generic/Generic ASA @Elegoo.json b/resources/profiles/Elegoo/filament/Generic/Generic ASA @Elegoo.json index eed4e746d9..ff7a1c9d00 100644 --- a/resources/profiles/Elegoo/filament/Generic/Generic ASA @Elegoo.json +++ b/resources/profiles/Elegoo/filament/Generic/Generic ASA @Elegoo.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "U5sKORLsVPcldRY9", "name": "Generic ASA @Elegoo", - "from": "system", - "instantiation": "true", "inherits": "Generic ASA @base", + "from": "system", + "setting_id": "U5sKORLsVPcldRY9", + "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Elegoo/filament/Generic/Generic PETG @Elegoo.json b/resources/profiles/Elegoo/filament/Generic/Generic PETG @Elegoo.json index 005d5b305c..d8e67cda60 100644 --- a/resources/profiles/Elegoo/filament/Generic/Generic PETG @Elegoo.json +++ b/resources/profiles/Elegoo/filament/Generic/Generic PETG @Elegoo.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "MJMg6nee4l28n2mK", "name": "Generic PETG @Elegoo", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG @base", + "from": "system", + "setting_id": "MJMg6nee4l28n2mK", + "instantiation": "true", "cool_plate_temp": [ "60" ], diff --git a/resources/profiles/Elegoo/filament/Generic/Generic PETG PRO @Elegoo.json b/resources/profiles/Elegoo/filament/Generic/Generic PETG PRO @Elegoo.json index f122066617..6b5a610016 100644 --- a/resources/profiles/Elegoo/filament/Generic/Generic PETG PRO @Elegoo.json +++ b/resources/profiles/Elegoo/filament/Generic/Generic PETG PRO @Elegoo.json @@ -1,12 +1,12 @@ { "type": "filament", - "setting_id": "pKzSR8XeyyUDbrNW", "name": "Generic PETG PRO @Elegoo", "renamed_from": "Elegoo Generic PETG PRO", + "inherits": "Generic PETG @base", "from": "system", + "setting_id": "pKzSR8XeyyUDbrNW", "filament_id": "OFllmFhT", "instantiation": "true", - "inherits": "Generic PETG @base", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Elegoo/filament/Generic/Generic PLA @Elegoo.json b/resources/profiles/Elegoo/filament/Generic/Generic PLA @Elegoo.json index d70a73e10e..263ba5b3e4 100644 --- a/resources/profiles/Elegoo/filament/Generic/Generic PLA @Elegoo.json +++ b/resources/profiles/Elegoo/filament/Generic/Generic PLA @Elegoo.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "PaFKjG9jocZSHl76", "name": "Generic PLA @Elegoo", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA @base", + "from": "system", + "setting_id": "PaFKjG9jocZSHl76", + "instantiation": "true", "cool_plate_temp": [ "60" ], diff --git a/resources/profiles/Elegoo/filament/Generic/Generic PLA Matte @Elegoo.json b/resources/profiles/Elegoo/filament/Generic/Generic PLA Matte @Elegoo.json index 33561c23bc..3519ae8c4d 100644 --- a/resources/profiles/Elegoo/filament/Generic/Generic PLA Matte @Elegoo.json +++ b/resources/profiles/Elegoo/filament/Generic/Generic PLA Matte @Elegoo.json @@ -1,11 +1,11 @@ { "type": "filament", - "setting_id": "dH2Yf92iqsOj5XYo", "name": "Generic PLA Matte @Elegoo", + "inherits": "Generic PLA @base", "from": "system", + "setting_id": "dH2Yf92iqsOj5XYo", "filament_id": "OFmY0l6t", "instantiation": "true", - "inherits": "Generic PLA @base", "cool_plate_temp": [ "60" ], diff --git a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 0.4 nozzle.json index 09536322dd..2733de7433 100644 --- a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "zECkpVCtequEr3jC", "name": "Elegoo Neptune 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Elegoo Neptune 2 0.4 nozzle", + "from": "system", + "setting_id": "zECkpVCtequEr3jC", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune", "default_print_profile": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2 0.4 nozzle.json index 9f2c728356..aca22ef378 100644 --- a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "WButFYamVx0MBjUr", "name": "Elegoo Neptune 2 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_elegoo_common", + "from": "system", + "setting_id": "WButFYamVx0MBjUr", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 2", "default_print_profile": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2D 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2D 0.4 nozzle.json index ae78964a9a..8776a9d224 100644 --- a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2D 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2D 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "9KnJva7m7E5M1quB", "name": "Elegoo Neptune 2D 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Elegoo Neptune 2 0.4 nozzle", + "from": "system", + "setting_id": "9KnJva7m7E5M1quB", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 2D", "default_print_profile": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", @@ -29,58 +29,86 @@ "printable_height": "250", "auxiliary_fan": "0", "machine_max_acceleration_extruding": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_retracting": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_travel": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "70", + "70", "70", "70" ], "machine_max_speed_x": [ + "300", + "300", "300", "300" ], "machine_max_speed_y": [ + "300", + "300", "300", "300" ], "machine_max_speed_z": [ + "20", + "20", "20", "20" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "8", + "8", "8", "8" ], "machine_max_jerk_y": [ + "8", + "8", "8", "8" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2S 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2S 0.4 nozzle.json index e6ee656aad..b8e276a9dd 100644 --- a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2S 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 2S 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "a8iTteroepkgXrLV", "name": "Elegoo Neptune 2S 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_elegoo_common", + "from": "system", + "setting_id": "a8iTteroepkgXrLV", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 2S", "default_print_profile": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 3 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 3 0.4 nozzle.json index 8766784dc6..af79ce92db 100644 --- a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 3 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune 3 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "rdKmVhTTrup3yqgA", "name": "Elegoo Neptune 3 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Elegoo Neptune 2 0.4 nozzle", + "from": "system", + "setting_id": "rdKmVhTTrup3yqgA", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 3", "default_print_profile": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune X 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune X 0.4 nozzle.json index 6596abf85a..19eaa4a699 100644 --- a/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune X 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN2SERIES/Elegoo Neptune X 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "krz8Xh3MatGnm8pm", "name": "Elegoo Neptune X 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_elegoo_common", + "from": "system", + "setting_id": "krz8Xh3MatGnm8pm", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune X", "default_print_profile": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Max 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Max 0.4 nozzle.json index 9aebe16dd2..5e4dc6fe1d 100644 --- a/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "8CM5vaCDh096ZzUs", "name": "Elegoo Neptune 3 Max 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Elegoo Neptune 3 Pro 0.4 nozzle", + "from": "system", + "setting_id": "8CM5vaCDh096ZzUs", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 3 Max", "default_print_profile": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Plus 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Plus 0.4 nozzle.json index c53f7a7d7a..51ad7c820b 100644 --- a/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "FylvH6NMzPbR9Bz6", "name": "Elegoo Neptune 3 Plus 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Elegoo Neptune 3 Pro 0.4 nozzle", + "from": "system", + "setting_id": "FylvH6NMzPbR9Bz6", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 3 Plus", "default_print_profile": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Pro 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Pro 0.4 nozzle.json index 82798b0285..b246cacab0 100644 --- a/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN3SERIES/Elegoo Neptune 3 Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "9vUFjjVwWAggcbwk", "name": "Elegoo Neptune 3 Pro 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_elegoo_common", + "from": "system", + "setting_id": "9vUFjjVwWAggcbwk", + "instantiation": "true", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 3 Pro", "default_print_profile": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.2 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.2 nozzle.json index 32ec717163..2c01584e91 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.2 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 0.2 nozzle", + "renamed_from": "Elegoo Neptune 4 (0.2 nozzle)", "inherits": "Elegoo Neptune 4 0.4 nozzle", "from": "system", "setting_id": "YGH30n1CBw3of81j", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.06" - ], - "renamed_from": "Elegoo Neptune 4 (0.2 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.4 nozzle.json index fb3ca2d389..407344c774 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.4 nozzle.json @@ -1,10 +1,11 @@ { "type": "machine", "name": "Elegoo Neptune 4 0.4 nozzle", + "renamed_from": "Elegoo Neptune 4 (0.4 nozzle)", + "inherits": "fdm_elegoo_3dp_001_common", "from": "system", "setting_id": "69QdWuRQwAZk9rFu", "instantiation": "true", - "inherits": "fdm_elegoo_3dp_001_common", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 4", "default_print_profile": "0.20mm Standard @Elegoo N4 0.4 nozzle", @@ -114,6 +115,5 @@ "160x160/COLPIC/#30394F", "160x160/PNG" ], - "thumbnails_format": "COLPIC", - "renamed_from": "Elegoo Neptune 4 (0.4 nozzle)" + "thumbnails_format": "COLPIC" } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.6 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.6 nozzle.json index 6195ecf232..68763e7e16 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.6 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 0.6 nozzle", + "renamed_from": "Elegoo Neptune 4 (0.6 nozzle)", "inherits": "Elegoo Neptune 4 0.4 nozzle", "from": "system", "setting_id": "hAlEcYQJUiRdXvP3", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.12" - ], - "renamed_from": "Elegoo Neptune 4 (0.6 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.8 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.8 nozzle.json index 52483240b3..f3a97531dc 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.8 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 0.8 nozzle", + "renamed_from": "Elegoo Neptune 4 (0.8 nozzle)", "inherits": "Elegoo Neptune 4 0.4 nozzle", "from": "system", "setting_id": "2lAqJ4y4QPkkG3Eq", @@ -31,6 +32,5 @@ ], "retract_length_toolchange": [ "3" - ], - "renamed_from": "Elegoo Neptune 4 (0.8 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.2 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.2 nozzle.json index 5b863d5773..f3fbfacfda 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.2 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Max 0.2 nozzle", + "renamed_from": "Elegoo Neptune 4 Max (0.2 nozzle)", "inherits": "Elegoo Neptune 4 Max 0.4 nozzle", "from": "system", "setting_id": "cnSthrwdZaeijtbD", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.06" - ], - "renamed_from": "Elegoo Neptune 4 Max (0.2 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.4 nozzle.json index 08c9690cda..3779e74c0d 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.4 nozzle.json @@ -1,10 +1,11 @@ { "type": "machine", "name": "Elegoo Neptune 4 Max 0.4 nozzle", + "renamed_from": "Elegoo Neptune 4 Max (0.4 nozzle)", + "inherits": "Elegoo Neptune 4 0.4 nozzle", "from": "system", "setting_id": "Ie1QF4p1mjA7QqZf", "instantiation": "true", - "inherits": "Elegoo Neptune 4 0.4 nozzle", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 4 Max", "default_print_profile": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", @@ -80,6 +81,5 @@ "nozzle_volume": "110", "default_filament_profile": [ "Elegoo PLA @EN4 Series" - ], - "renamed_from": "Elegoo Neptune 4 Max (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.6 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.6 nozzle.json index 0b117150b1..04562e965a 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Max 0.6 nozzle", + "renamed_from": "Elegoo Neptune 4 Max (0.6 nozzle)", "inherits": "Elegoo Neptune 4 Max 0.4 nozzle", "from": "system", "setting_id": "DXxpsdZ4r73cfNT7", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.12" - ], - "renamed_from": "Elegoo Neptune 4 Max (0.6 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.8 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.8 nozzle.json index ca4c4dc092..9f9aea1263 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Max 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Max 0.8 nozzle", + "renamed_from": "Elegoo Neptune 4 Max (0.8 nozzle)", "inherits": "Elegoo Neptune 4 Max 0.4 nozzle", "from": "system", "setting_id": "licXMWyXGDavpuvu", @@ -31,6 +32,5 @@ ], "retract_length_toolchange": [ "3" - ], - "renamed_from": "Elegoo Neptune 4 Max (0.8 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.2 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.2 nozzle.json index e0c66e5166..1040c95656 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.2 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Plus 0.2 nozzle", + "renamed_from": "Elegoo Neptune 4 Plus (0.2 nozzle)", "inherits": "Elegoo Neptune 4 Plus 0.4 nozzle", "from": "system", "setting_id": "i5vcoYRF6cqkYBg9", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.06" - ], - "renamed_from": "Elegoo Neptune 4 Plus (0.2 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.4 nozzle.json index d6686b8bba..84f8568da2 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.4 nozzle.json @@ -1,10 +1,11 @@ { "type": "machine", "name": "Elegoo Neptune 4 Plus 0.4 nozzle", + "renamed_from": "Elegoo Neptune 4 Plus (0.4 nozzle)", + "inherits": "Elegoo Neptune 4 0.4 nozzle", "from": "system", "setting_id": "Rc54LjtIhvBWRS2Y", "instantiation": "true", - "inherits": "Elegoo Neptune 4 0.4 nozzle", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 4 Plus", "default_print_profile": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", @@ -80,6 +81,5 @@ "nozzle_volume": "110", "default_filament_profile": [ "Elegoo PLA @EN4 Series" - ], - "renamed_from": "Elegoo Neptune 4 Plus (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.6 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.6 nozzle.json index d038519e2e..1a1c90eaea 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Plus 0.6 nozzle", + "renamed_from": "Elegoo Neptune 4 Plus (0.6 nozzle)", "inherits": "Elegoo Neptune 4 Plus 0.4 nozzle", "from": "system", "setting_id": "nCRrAqumiiZpu5Re", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.12" - ], - "renamed_from": "Elegoo Neptune 4 Plus (0.6 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.8 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.8 nozzle.json index e4cbdaf790..21bceaceec 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Plus 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Plus 0.8 nozzle", + "renamed_from": "Elegoo Neptune 4 Plus (0.8 nozzle)", "inherits": "Elegoo Neptune 4 Plus 0.4 nozzle", "from": "system", "setting_id": "CM0ZVy6UJRObNbMV", @@ -31,6 +32,5 @@ ], "retract_length_toolchange": [ "3" - ], - "renamed_from": "Elegoo Neptune 4 Plus (0.8 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.2 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.2 nozzle.json index ff7bd8fdf9..bc9b797d10 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.2 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Pro 0.2 nozzle", + "renamed_from": "Elegoo Neptune 4 Pro (0.2 nozzle)", "inherits": "Elegoo Neptune 4 Pro 0.4 nozzle", "from": "system", "setting_id": "tjxZec78rbpYkEM2", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.06" - ], - "renamed_from": "Elegoo Neptune 4 Pro (0.2 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.4 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.4 nozzle.json index 97b3ad8fea..37b92b682e 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.4 nozzle.json @@ -1,10 +1,11 @@ { "type": "machine", "name": "Elegoo Neptune 4 Pro 0.4 nozzle", + "renamed_from": "Elegoo Neptune 4 Pro (0.4 nozzle)", + "inherits": "Elegoo Neptune 4 0.4 nozzle", "from": "system", "setting_id": "H1wMUu4EMaiQzxeD", "instantiation": "true", - "inherits": "Elegoo Neptune 4 0.4 nozzle", "host_type": "elegoolink", "printer_model": "Elegoo Neptune 4 Pro", "default_print_profile": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", @@ -35,6 +36,5 @@ "before_layer_change_gcode": ";[layer_z]\nG92 E0\n{if (first_layer_print_min[0]) > 57.5 && (first_layer_print_min[1]) > 57.5 &&(first_layer_print_max[0]) < 177.5 && (first_layer_print_max[1]) < 177.5 && layer_num < 4 && bed_temperature_initial_layer_single < 71}\nM141 S0\n{endif}", "default_filament_profile": [ "Elegoo PLA @EN4 Series" - ], - "renamed_from": "Elegoo Neptune 4 Pro (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.6 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.6 nozzle.json index 940da1c6a3..1572bcc985 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Pro 0.6 nozzle", + "renamed_from": "Elegoo Neptune 4 Pro (0.6 nozzle)", "inherits": "Elegoo Neptune 4 Pro 0.4 nozzle", "from": "system", "setting_id": "f9xvw4oHKtdZq7oq", @@ -28,6 +29,5 @@ ], "min_layer_height": [ "0.12" - ], - "renamed_from": "Elegoo Neptune 4 Pro (0.6 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.8 nozzle.json b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.8 nozzle.json index cdeebf75c3..ea04471ccc 100644 --- a/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/machine/EN4SERIES/Elegoo Neptune 4 Pro 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "machine", "name": "Elegoo Neptune 4 Pro 0.8 nozzle", + "renamed_from": "Elegoo Neptune 4 Pro (0.8 nozzle)", "inherits": "Elegoo Neptune 4 Pro 0.4 nozzle", "from": "system", "setting_id": "nd5TLZa3xnDu1s4W", @@ -31,6 +32,5 @@ ], "retract_length_toolchange": [ "3" - ], - "renamed_from": "Elegoo Neptune 4 Pro (0.8 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/process/EC/0.08mm Optimal @Elegoo C 0.2 nozzle.json b/resources/profiles/Elegoo/process/EC/0.08mm Optimal @Elegoo C 0.2 nozzle.json index 2312d6f0e6..4deed44f41 100644 --- a/resources/profiles/Elegoo/process/EC/0.08mm Optimal @Elegoo C 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.08mm Optimal @Elegoo C 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "elefant_foot_compensation": "0.05", - "inherits": "0.10mm Standard @Elegoo C 0.2 nozzle", - "layer_height": "0.08", "name": "0.08mm Optimal @Elegoo C 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo C 0.2 nozzle", "from": "system", "setting_id": "YPAU0R4VfHdwXGMK", - "instantiation": "true" + "instantiation": "true", + "elefant_foot_compensation": "0.05", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EC/0.12mm Draft @Elegoo C 0.2 nozzle.json b/resources/profiles/Elegoo/process/EC/0.12mm Draft @Elegoo C 0.2 nozzle.json index 8a775fd9d6..2c04217e64 100644 --- a/resources/profiles/Elegoo/process/EC/0.12mm Draft @Elegoo C 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.12mm Draft @Elegoo C 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.10mm Standard @Elegoo C 0.2 nozzle", - "layer_height": "0.12", "name": "0.12mm Draft @Elegoo C 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo C 0.2 nozzle", "from": "system", "setting_id": "2syIUL3VOd1cnbjD", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EC/0.12mm Fine @Elegoo C 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC/0.12mm Fine @Elegoo C 0.4 nozzle.json index a94c0e7b2e..f922a8890d 100644 --- a/resources/profiles/Elegoo/process/EC/0.12mm Fine @Elegoo C 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.12mm Fine @Elegoo C 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", - "layer_height": "0.12", "name": "0.12mm Fine @Elegoo C 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", "from": "system", - "wall_loops": "3", "setting_id": "0S47zshoJbgOUinj", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12", + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EC/0.14mm Extra Draft @Elegoo C 0.2 nozzle.json b/resources/profiles/Elegoo/process/EC/0.14mm Extra Draft @Elegoo C 0.2 nozzle.json index d676fb31b1..5eb42ca072 100644 --- a/resources/profiles/Elegoo/process/EC/0.14mm Extra Draft @Elegoo C 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.14mm Extra Draft @Elegoo C 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.10mm Standard @Elegoo C 0.2 nozzle", - "layer_height": "0.14", "name": "0.14mm Extra Draft @Elegoo C 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo C 0.2 nozzle", "from": "system", "setting_id": "6ibckorXgT6NdqHu", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.14" } diff --git a/resources/profiles/Elegoo/process/EC/0.16mm Extra Fine @Elegoo C 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC/0.16mm Extra Fine @Elegoo C 0.8 nozzle.json index 4cc9f531bb..aedfb88750 100644 --- a/resources/profiles/Elegoo/process/EC/0.16mm Extra Fine @Elegoo C 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.16mm Extra Fine @Elegoo C 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.16", "name": "0.16mm Extra Fine @Elegoo C 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", "from": "system", "setting_id": "93O7HpujQ35rwBWc", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EC/0.16mm Optimal @Elegoo C 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC/0.16mm Optimal @Elegoo C 0.4 nozzle.json index 4bce55dde7..cf7751dfb9 100644 --- a/resources/profiles/Elegoo/process/EC/0.16mm Optimal @Elegoo C 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.16mm Optimal @Elegoo C 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", - "layer_height": "0.16", "name": "0.16mm Optimal @Elegoo C 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", "from": "system", "setting_id": "KW2VknXy8J5A7ot5", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EC/0.18mm Fine @Elegoo C 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC/0.18mm Fine @Elegoo C 0.6 nozzle.json index 212ac989de..5d8f5a90b9 100644 --- a/resources/profiles/Elegoo/process/EC/0.18mm Fine @Elegoo C 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.18mm Fine @Elegoo C 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", - "layer_height": "0.18", "name": "0.18mm Fine @Elegoo C 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", "from": "system", "setting_id": "Z2Qn4avdLVCcBmcZ", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.18" } diff --git a/resources/profiles/Elegoo/process/EC/0.20mm Strength @Elegoo C 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC/0.20mm Strength @Elegoo C 0.4 nozzle.json index 33702fa81d..81cf56d8c0 100644 --- a/resources/profiles/Elegoo/process/EC/0.20mm Strength @Elegoo C 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.20mm Strength @Elegoo C 0.4 nozzle.json @@ -1,8 +1,10 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", "name": "0.20mm Strength @Elegoo C 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", "from": "system", + "setting_id": "ICxi69TCESAQTBVb", + "instantiation": "true", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "bottom_shell_layers": "5", @@ -10,7 +12,5 @@ "print_flow_ratio": "0.95", "sparse_infill_density": "20%", "top_shell_layers": "6", - "wall_loops": "6", - "setting_id": "ICxi69TCESAQTBVb", - "instantiation": "true" + "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EC/0.24mm Draft @Elegoo C 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC/0.24mm Draft @Elegoo C 0.4 nozzle.json index fa0edcba37..395d036d1e 100644 --- a/resources/profiles/Elegoo/process/EC/0.24mm Draft @Elegoo C 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.24mm Draft @Elegoo C 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", - "layer_height": "0.24", "name": "0.24mm Draft @Elegoo C 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", "from": "system", "setting_id": "eoyZK9tkjdL1ATi9", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EC/0.24mm Fine @Elegoo C 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC/0.24mm Fine @Elegoo C 0.8 nozzle.json index 16dde5137e..f5b96e47ca 100644 --- a/resources/profiles/Elegoo/process/EC/0.24mm Fine @Elegoo C 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.24mm Fine @Elegoo C 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.24", "name": "0.24mm Fine @Elegoo C 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", "from": "system", "setting_id": "HyulASCV51SI9Dgo", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EC/0.24mm Optimal @Elegoo C 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC/0.24mm Optimal @Elegoo C 0.6 nozzle.json index 3e12c4cc8f..11af13cf25 100644 --- a/resources/profiles/Elegoo/process/EC/0.24mm Optimal @Elegoo C 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.24mm Optimal @Elegoo C 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", - "layer_height": "0.24", "name": "0.24mm Optimal @Elegoo C 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", "from": "system", "setting_id": "2H4qamD9XBTs46M7", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EC/0.28mm Extra Draft @Elegoo C 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC/0.28mm Extra Draft @Elegoo C 0.4 nozzle.json index a996b51d67..a9b43740a2 100644 --- a/resources/profiles/Elegoo/process/EC/0.28mm Extra Draft @Elegoo C 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.28mm Extra Draft @Elegoo C 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", - "layer_height": "0.28", "name": "0.28mm Extra Draft @Elegoo C 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C 0.4 nozzle", "from": "system", "setting_id": "R2evn20zXKqcB4Ro", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EC/0.30mm Strength @Elegoo C 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC/0.30mm Strength @Elegoo C 0.6 nozzle.json index d0d20b4fc7..8b082b398a 100644 --- a/resources/profiles/Elegoo/process/EC/0.30mm Strength @Elegoo C 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.30mm Strength @Elegoo C 0.6 nozzle.json @@ -1,15 +1,15 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", - "inner_wall_speed": "120", "name": "0.30mm Strength @Elegoo C 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", "from": "system", + "setting_id": "GtT1qn9vSWDdqBmm", + "instantiation": "true", + "inner_wall_speed": "120", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "outer_wall_speed": "80", "sparse_infill_density": "15%", "top_surface_speed": "120", - "wall_loops": "4", - "setting_id": "GtT1qn9vSWDdqBmm", - "instantiation": "true" + "wall_loops": "4" } diff --git a/resources/profiles/Elegoo/process/EC/0.32mm Optimal @Elegoo C 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC/0.32mm Optimal @Elegoo C 0.8 nozzle.json index c98b6810e2..7c7badf6de 100644 --- a/resources/profiles/Elegoo/process/EC/0.32mm Optimal @Elegoo C 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.32mm Optimal @Elegoo C 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", - "layer_height": "0.32", "name": "0.32mm Optimal @Elegoo C 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", "from": "system", "setting_id": "HDjwnNiVaWHvhyTX", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EC/0.36mm Draft @Elegoo C 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC/0.36mm Draft @Elegoo C 0.6 nozzle.json index 255e8ee255..24a73ec080 100644 --- a/resources/profiles/Elegoo/process/EC/0.36mm Draft @Elegoo C 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.36mm Draft @Elegoo C 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", - "layer_height": "0.36", "name": "0.36mm Draft @Elegoo C 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", "from": "system", "setting_id": "AviieBSwRir1KzZr", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EC/0.42mm Extra Draft @Elegoo C 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC/0.42mm Extra Draft @Elegoo C 0.6 nozzle.json index c146f09d58..24e74d5c84 100644 --- a/resources/profiles/Elegoo/process/EC/0.42mm Extra Draft @Elegoo C 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.42mm Extra Draft @Elegoo C 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", - "layer_height": "0.42", "name": "0.42mm Extra Draft @Elegoo C 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C 0.6 nozzle", "from": "system", "setting_id": "ex5zv2heDmy6ZcbP", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EC/0.48mm Draft @Elegoo C 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC/0.48mm Draft @Elegoo C 0.8 nozzle.json index 8aea27b6dd..ba4e097193 100644 --- a/resources/profiles/Elegoo/process/EC/0.48mm Draft @Elegoo C 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC/0.48mm Draft @Elegoo C 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", - "layer_height": "0.48", "name": "0.48mm Draft @Elegoo C 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C 0.8 nozzle", "from": "system", "setting_id": "ZFRRBIC9Z4OzSW7b", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EC2/0.08mm Optimal @Elegoo C2 0.2 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.08mm Optimal @Elegoo C2 0.2 nozzle.json index fb31e5b085..2695aa82b0 100644 --- a/resources/profiles/Elegoo/process/EC2/0.08mm Optimal @Elegoo C2 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.08mm Optimal @Elegoo C2 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "elefant_foot_compensation": "0.05", - "inherits": "0.10mm Standard @Elegoo C2 0.2 nozzle", - "layer_height": "0.08", "name": "0.08mm Optimal @Elegoo C2 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo C2 0.2 nozzle", + "from": "system", "setting_id": "w51mhOmSGgIFKlYV", - "instantiation": "true" + "instantiation": "true", + "elefant_foot_compensation": "0.05", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EC2/0.12mm Draft @Elegoo C2 0.2 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.12mm Draft @Elegoo C2 0.2 nozzle.json index 2591f133fa..433b665c69 100644 --- a/resources/profiles/Elegoo/process/EC2/0.12mm Draft @Elegoo C2 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.12mm Draft @Elegoo C2 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.10mm Standard @Elegoo C2 0.2 nozzle", - "layer_height": "0.12", "name": "0.12mm Draft @Elegoo C2 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo C2 0.2 nozzle", + "from": "system", "setting_id": "MwbMs6dE4PKJjWEv", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EC2/0.12mm Fine @Elegoo C2 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.12mm Fine @Elegoo C2 0.4 nozzle.json index 1e38bdedef..03e6cda866 100644 --- a/resources/profiles/Elegoo/process/EC2/0.12mm Fine @Elegoo C2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.12mm Fine @Elegoo C2 0.4 nozzle.json @@ -1,13 +1,13 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", - "layer_height": "0.12", "name": "0.12mm Fine @Elegoo C2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", + "from": "system", + "setting_id": "NbPHZPuFyAdAwYxw", + "instantiation": "true", + "layer_height": "0.12", "wall_loops": "3", "support_bottom_z_distance": "0.2", "support_top_z_distance": "0.2", - "top_solid_infill_flow_ratio": "1.09", - "setting_id": "NbPHZPuFyAdAwYxw", - "instantiation": "true" + "top_solid_infill_flow_ratio": "1.09" } diff --git a/resources/profiles/Elegoo/process/EC2/0.14mm Extra Draft @Elegoo C2 0.2 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.14mm Extra Draft @Elegoo C2 0.2 nozzle.json index 578cc189a1..41468b71bb 100644 --- a/resources/profiles/Elegoo/process/EC2/0.14mm Extra Draft @Elegoo C2 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.14mm Extra Draft @Elegoo C2 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.10mm Standard @Elegoo C2 0.2 nozzle", - "layer_height": "0.14", "name": "0.14mm Extra Draft @Elegoo C2 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo C2 0.2 nozzle", + "from": "system", "setting_id": "WZYQH8ejJLFr3JKT", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.14" } diff --git a/resources/profiles/Elegoo/process/EC2/0.16mm Extra Fine @Elegoo C2 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.16mm Extra Fine @Elegoo C2 0.8 nozzle.json index ee21a677ad..aaeae89b95 100644 --- a/resources/profiles/Elegoo/process/EC2/0.16mm Extra Fine @Elegoo C2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.16mm Extra Fine @Elegoo C2 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.16", "name": "0.16mm Extra Fine @Elegoo C2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", + "from": "system", "setting_id": "8PjDabUQtqZkOYxb", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EC2/0.16mm Optimal @Elegoo C2 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.16mm Optimal @Elegoo C2 0.4 nozzle.json index cbf804ad9c..568d7ed0c2 100644 --- a/resources/profiles/Elegoo/process/EC2/0.16mm Optimal @Elegoo C2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.16mm Optimal @Elegoo C2 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", - "layer_height": "0.16", "name": "0.16mm Optimal @Elegoo C2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", + "from": "system", "setting_id": "cyxRTNBvYul3eWPq", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EC2/0.18mm Fine @Elegoo C2 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.18mm Fine @Elegoo C2 0.6 nozzle.json index 607c77fc1a..f27edc3b97 100644 --- a/resources/profiles/Elegoo/process/EC2/0.18mm Fine @Elegoo C2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.18mm Fine @Elegoo C2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", - "layer_height": "0.18", "name": "0.18mm Fine @Elegoo C2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", + "from": "system", "setting_id": "CpTAuCMAczdOUFQv", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.18" } diff --git a/resources/profiles/Elegoo/process/EC2/0.20mm Strength @Elegoo C2 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.20mm Strength @Elegoo C2 0.4 nozzle.json index 8a87b379c7..3f5375d255 100644 --- a/resources/profiles/Elegoo/process/EC2/0.20mm Strength @Elegoo C2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.20mm Strength @Elegoo C2 0.4 nozzle.json @@ -1,8 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", "name": "0.20mm Strength @Elegoo C2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", + "from": "system", + "setting_id": "qE1gwHDiHsBUar05", + "instantiation": "true", "wall_sequence": "inner wall/outer wall", "reduce_crossing_wall": "0", "bottom_shell_layers": "5", @@ -11,7 +13,5 @@ "sparse_infill_density": "20%", "top_shell_layers": "6", "wall_loops": "5", - "top_solid_infill_flow_ratio": "1.09", - "setting_id": "qE1gwHDiHsBUar05", - "instantiation": "true" + "top_solid_infill_flow_ratio": "1.09" } diff --git a/resources/profiles/Elegoo/process/EC2/0.24mm Draft @Elegoo C2 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.24mm Draft @Elegoo C2 0.4 nozzle.json index 3477713edc..046e6bf7b4 100644 --- a/resources/profiles/Elegoo/process/EC2/0.24mm Draft @Elegoo C2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.24mm Draft @Elegoo C2 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", - "layer_height": "0.24", "name": "0.24mm Draft @Elegoo C2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", + "from": "system", "setting_id": "m8IwC70UUDsvEgDx", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EC2/0.24mm Fine @Elegoo C2 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.24mm Fine @Elegoo C2 0.8 nozzle.json index 8a3d3f1baa..af303b49d3 100644 --- a/resources/profiles/Elegoo/process/EC2/0.24mm Fine @Elegoo C2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.24mm Fine @Elegoo C2 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.24", "name": "0.24mm Fine @Elegoo C2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", + "from": "system", "setting_id": "aGRzp98JewtyCnJ5", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EC2/0.24mm Optimal @Elegoo C2 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.24mm Optimal @Elegoo C2 0.6 nozzle.json index f8a86f303d..844f875909 100644 --- a/resources/profiles/Elegoo/process/EC2/0.24mm Optimal @Elegoo C2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.24mm Optimal @Elegoo C2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", - "layer_height": "0.24", "name": "0.24mm Optimal @Elegoo C2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", + "from": "system", "setting_id": "mg6YKeDhdAmVUnCp", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EC2/0.28mm Extra Draft @Elegoo C2 0.4 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.28mm Extra Draft @Elegoo C2 0.4 nozzle.json index d763b38514..325b617538 100644 --- a/resources/profiles/Elegoo/process/EC2/0.28mm Extra Draft @Elegoo C2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.28mm Extra Draft @Elegoo C2 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", - "layer_height": "0.28", "name": "0.28mm Extra Draft @Elegoo C2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo C2 0.4 nozzle", + "from": "system", "setting_id": "zLhSKg0WGU0C5hfV", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EC2/0.30mm Strength @Elegoo C2 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.30mm Strength @Elegoo C2 0.6 nozzle.json index 52ff71723c..d62a28c431 100644 --- a/resources/profiles/Elegoo/process/EC2/0.30mm Strength @Elegoo C2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.30mm Strength @Elegoo C2 0.6 nozzle.json @@ -1,15 +1,15 @@ { "type": "process", - "from": "system", - "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", - "inner_wall_speed": "120", "name": "0.30mm Strength @Elegoo C2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", + "from": "system", + "setting_id": "6Pdk7vUo7sxZ1H3r", + "instantiation": "true", + "inner_wall_speed": "120", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "outer_wall_speed": "80", "sparse_infill_density": "15%", "top_surface_speed": "120", - "wall_loops": "4", - "setting_id": "6Pdk7vUo7sxZ1H3r", - "instantiation": "true" + "wall_loops": "4" } diff --git a/resources/profiles/Elegoo/process/EC2/0.32mm Optimal @Elegoo C2 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.32mm Optimal @Elegoo C2 0.8 nozzle.json index 46caf9ca4c..f4f0a3152c 100644 --- a/resources/profiles/Elegoo/process/EC2/0.32mm Optimal @Elegoo C2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.32mm Optimal @Elegoo C2 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", - "layer_height": "0.32", "name": "0.32mm Optimal @Elegoo C2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", + "from": "system", "setting_id": "CctfduTuGLmoXTaG", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EC2/0.36mm Draft @Elegoo C2 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.36mm Draft @Elegoo C2 0.6 nozzle.json index a484461350..e5889acabd 100644 --- a/resources/profiles/Elegoo/process/EC2/0.36mm Draft @Elegoo C2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.36mm Draft @Elegoo C2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", - "layer_height": "0.36", "name": "0.36mm Draft @Elegoo C2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", + "from": "system", "setting_id": "MEasFZeORQm7BzsT", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EC2/0.42mm Extra Draft @Elegoo C2 0.6 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.42mm Extra Draft @Elegoo C2 0.6 nozzle.json index 7ab59fecd2..4499644811 100644 --- a/resources/profiles/Elegoo/process/EC2/0.42mm Extra Draft @Elegoo C2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.42mm Extra Draft @Elegoo C2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", - "layer_height": "0.42", "name": "0.42mm Extra Draft @Elegoo C2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo C2 0.6 nozzle", + "from": "system", "setting_id": "TbMqvWBwE7Hf6VdK", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EC2/0.48mm Draft @Elegoo C2 0.8 nozzle.json b/resources/profiles/Elegoo/process/EC2/0.48mm Draft @Elegoo C2 0.8 nozzle.json index 17e2904446..08a962901f 100644 --- a/resources/profiles/Elegoo/process/EC2/0.48mm Draft @Elegoo C2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EC2/0.48mm Draft @Elegoo C2 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", - "layer_height": "0.48", "name": "0.48mm Draft @Elegoo C2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo C2 0.8 nozzle", + "from": "system", "setting_id": "8BBCLnwOPdqLlIIo", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/ECC/0.08mm Optimal @Elegoo CC 0.2 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.08mm Optimal @Elegoo CC 0.2 nozzle.json index 5673d99376..ee5b5e815f 100644 --- a/resources/profiles/Elegoo/process/ECC/0.08mm Optimal @Elegoo CC 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.08mm Optimal @Elegoo CC 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "elefant_foot_compensation": "0.05", - "inherits": "0.10mm Standard @Elegoo CC 0.2 nozzle", - "layer_height": "0.08", "name": "0.08mm Optimal @Elegoo CC 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo CC 0.2 nozzle", "from": "system", "setting_id": "99XQJJWd9FHtXPEa", - "instantiation": "true" + "instantiation": "true", + "elefant_foot_compensation": "0.05", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/ECC/0.12mm Draft @Elegoo CC 0.2 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.12mm Draft @Elegoo CC 0.2 nozzle.json index 4a21f48f65..7de0bb2c42 100644 --- a/resources/profiles/Elegoo/process/ECC/0.12mm Draft @Elegoo CC 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.12mm Draft @Elegoo CC 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.10mm Standard @Elegoo CC 0.2 nozzle", - "layer_height": "0.12", "name": "0.12mm Draft @Elegoo CC 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo CC 0.2 nozzle", "from": "system", "setting_id": "LwyvYtJYTwvDlW5Z", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/ECC/0.12mm Fine @Elegoo CC 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.12mm Fine @Elegoo CC 0.4 nozzle.json index 66ca86dafa..037787bfc2 100644 --- a/resources/profiles/Elegoo/process/ECC/0.12mm Fine @Elegoo CC 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.12mm Fine @Elegoo CC 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", - "layer_height": "0.12", "name": "0.12mm Fine @Elegoo CC 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", "from": "system", - "wall_loops": "3", "setting_id": "340MqJEmv7j7xiOz", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12", + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/ECC/0.14mm Extra Draft @Elegoo CC 0.2 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.14mm Extra Draft @Elegoo CC 0.2 nozzle.json index f30ff023ab..05680ce052 100644 --- a/resources/profiles/Elegoo/process/ECC/0.14mm Extra Draft @Elegoo CC 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.14mm Extra Draft @Elegoo CC 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.10mm Standard @Elegoo CC 0.2 nozzle", - "layer_height": "0.14", "name": "0.14mm Extra Draft @Elegoo CC 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo CC 0.2 nozzle", "from": "system", "setting_id": "Z5WZBJIWjzOpucn2", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.14" } diff --git a/resources/profiles/Elegoo/process/ECC/0.16mm Extra Fine @Elegoo CC 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.16mm Extra Fine @Elegoo CC 0.8 nozzle.json index 6ea50dcd4d..f879a64262 100644 --- a/resources/profiles/Elegoo/process/ECC/0.16mm Extra Fine @Elegoo CC 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.16mm Extra Fine @Elegoo CC 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.16", "name": "0.16mm Extra Fine @Elegoo CC 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", "from": "system", "setting_id": "1pAr6ZTtBBXzHoUw", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/ECC/0.16mm Optimal @Elegoo CC 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.16mm Optimal @Elegoo CC 0.4 nozzle.json index 20391d67eb..cc24a259f6 100644 --- a/resources/profiles/Elegoo/process/ECC/0.16mm Optimal @Elegoo CC 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.16mm Optimal @Elegoo CC 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", - "layer_height": "0.16", "name": "0.16mm Optimal @Elegoo CC 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", "from": "system", "setting_id": "drsSvJoMY02R1hyF", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/ECC/0.18mm Fine @Elegoo CC 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.18mm Fine @Elegoo CC 0.6 nozzle.json index 547b84689f..bb34313938 100644 --- a/resources/profiles/Elegoo/process/ECC/0.18mm Fine @Elegoo CC 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.18mm Fine @Elegoo CC 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", - "layer_height": "0.18", "name": "0.18mm Fine @Elegoo CC 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", "from": "system", "setting_id": "bmv0UtvbzVHeOF4Q", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.18" } diff --git a/resources/profiles/Elegoo/process/ECC/0.20mm Strength @Elegoo CC 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.20mm Strength @Elegoo CC 0.4 nozzle.json index c91e5af39d..d34f85b66f 100644 --- a/resources/profiles/Elegoo/process/ECC/0.20mm Strength @Elegoo CC 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.20mm Strength @Elegoo CC 0.4 nozzle.json @@ -1,8 +1,10 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", "name": "0.20mm Strength @Elegoo CC 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", "from": "system", + "setting_id": "1OQrGLkl8fwRTEDT", + "instantiation": "true", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "bottom_shell_layers": "5", @@ -10,7 +12,5 @@ "print_flow_ratio": "0.95", "sparse_infill_density": "20%", "top_shell_layers": "6", - "wall_loops": "6", - "setting_id": "1OQrGLkl8fwRTEDT", - "instantiation": "true" + "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/ECC/0.24mm Draft @Elegoo CC 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.24mm Draft @Elegoo CC 0.4 nozzle.json index e59c6de6b4..da3b132b6a 100644 --- a/resources/profiles/Elegoo/process/ECC/0.24mm Draft @Elegoo CC 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.24mm Draft @Elegoo CC 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", - "layer_height": "0.24", "name": "0.24mm Draft @Elegoo CC 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", "from": "system", "setting_id": "PMeZoCKetIP9VQZM", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/ECC/0.24mm Fine @Elegoo CC 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.24mm Fine @Elegoo CC 0.8 nozzle.json index bacdbd0ca9..82dd9cbca4 100644 --- a/resources/profiles/Elegoo/process/ECC/0.24mm Fine @Elegoo CC 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.24mm Fine @Elegoo CC 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.24", "name": "0.24mm Fine @Elegoo CC 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", "from": "system", "setting_id": "6sqS6WmJX9aYJymC", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/ECC/0.24mm Optimal @Elegoo CC 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.24mm Optimal @Elegoo CC 0.6 nozzle.json index 7e25c9177f..a92338f4de 100644 --- a/resources/profiles/Elegoo/process/ECC/0.24mm Optimal @Elegoo CC 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.24mm Optimal @Elegoo CC 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", - "layer_height": "0.24", "name": "0.24mm Optimal @Elegoo CC 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", "from": "system", "setting_id": "hIJP5FSSmLy6bMcK", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/ECC/0.28mm Extra Draft @Elegoo CC 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.28mm Extra Draft @Elegoo CC 0.4 nozzle.json index 1b03db5ce9..80f65df58d 100644 --- a/resources/profiles/Elegoo/process/ECC/0.28mm Extra Draft @Elegoo CC 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.28mm Extra Draft @Elegoo CC 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", - "layer_height": "0.28", "name": "0.28mm Extra Draft @Elegoo CC 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC 0.4 nozzle", "from": "system", "setting_id": "6A6cE25ThuCqP7wi", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/ECC/0.30mm Strength @Elegoo CC 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.30mm Strength @Elegoo CC 0.6 nozzle.json index 33d040c984..f14883ffe6 100644 --- a/resources/profiles/Elegoo/process/ECC/0.30mm Strength @Elegoo CC 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.30mm Strength @Elegoo CC 0.6 nozzle.json @@ -1,15 +1,15 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", - "inner_wall_speed": "120", "name": "0.30mm Strength @Elegoo CC 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", "from": "system", + "setting_id": "b3rbevf3CUh8I05M", + "instantiation": "true", + "inner_wall_speed": "120", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "outer_wall_speed": "80", "sparse_infill_density": "15%", "top_surface_speed": "120", - "wall_loops": "4", - "setting_id": "b3rbevf3CUh8I05M", - "instantiation": "true" + "wall_loops": "4" } diff --git a/resources/profiles/Elegoo/process/ECC/0.32mm Optimal @Elegoo CC 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.32mm Optimal @Elegoo CC 0.8 nozzle.json index 654a49c1c5..8725296220 100644 --- a/resources/profiles/Elegoo/process/ECC/0.32mm Optimal @Elegoo CC 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.32mm Optimal @Elegoo CC 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", - "layer_height": "0.32", "name": "0.32mm Optimal @Elegoo CC 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", "from": "system", "setting_id": "Kez7FhiJRPdChlgg", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/ECC/0.36mm Draft @Elegoo CC 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.36mm Draft @Elegoo CC 0.6 nozzle.json index eaed462a3e..197ebfc0a3 100644 --- a/resources/profiles/Elegoo/process/ECC/0.36mm Draft @Elegoo CC 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.36mm Draft @Elegoo CC 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", - "layer_height": "0.36", "name": "0.36mm Draft @Elegoo CC 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", "from": "system", "setting_id": "pigdfIs4DLj6QswL", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/ECC/0.42mm Extra Draft @Elegoo CC 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.42mm Extra Draft @Elegoo CC 0.6 nozzle.json index c1fd90decf..1f6bb2fbb7 100644 --- a/resources/profiles/Elegoo/process/ECC/0.42mm Extra Draft @Elegoo CC 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.42mm Extra Draft @Elegoo CC 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", - "layer_height": "0.42", "name": "0.42mm Extra Draft @Elegoo CC 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC 0.6 nozzle", "from": "system", "setting_id": "griDT2q7IdUWT7hr", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/ECC/0.48mm Draft @Elegoo CC 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC/0.48mm Draft @Elegoo CC 0.8 nozzle.json index 775f515837..3b571e8079 100644 --- a/resources/profiles/Elegoo/process/ECC/0.48mm Draft @Elegoo CC 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC/0.48mm Draft @Elegoo CC 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", - "layer_height": "0.48", "name": "0.48mm Draft @Elegoo CC 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC 0.8 nozzle", "from": "system", "setting_id": "tpCT2ow532mcwKcd", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.08mm Optimal @Elegoo CC2 0.2 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.08mm Optimal @Elegoo CC2 0.2 nozzle.json index 82dc23f427..8b4947373f 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.08mm Optimal @Elegoo CC2 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.08mm Optimal @Elegoo CC2 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "elefant_foot_compensation": "0.05", - "inherits": "0.10mm Standard @Elegoo CC2 0.2 nozzle", - "layer_height": "0.08", "name": "0.08mm Optimal @Elegoo CC2 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo CC2 0.2 nozzle", "from": "system", "setting_id": "uD5gceL1thOzkzGo", - "instantiation": "true" + "instantiation": "true", + "elefant_foot_compensation": "0.05", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.12mm Draft @Elegoo CC2 0.2 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.12mm Draft @Elegoo CC2 0.2 nozzle.json index e570db58fc..19784aedec 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.12mm Draft @Elegoo CC2 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.12mm Draft @Elegoo CC2 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.10mm Standard @Elegoo CC2 0.2 nozzle", - "layer_height": "0.12", "name": "0.12mm Draft @Elegoo CC2 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo CC2 0.2 nozzle", "from": "system", "setting_id": "cGFwf6ddNwMmqs9h", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.12mm Fine @Elegoo CC2 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.12mm Fine @Elegoo CC2 0.4 nozzle.json index 85705f0aa9..e5a793903d 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.12mm Fine @Elegoo CC2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.12mm Fine @Elegoo CC2 0.4 nozzle.json @@ -1,13 +1,13 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", - "layer_height": "0.12", "name": "0.12mm Fine @Elegoo CC2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", "from": "system", + "setting_id": "lRhdk46FwTwzcCYh", + "instantiation": "true", + "layer_height": "0.12", "wall_loops": "3", "support_bottom_z_distance": "0.2", "support_top_z_distance": "0.2", - "top_solid_infill_flow_ratio": "1.09", - "setting_id": "lRhdk46FwTwzcCYh", - "instantiation": "true" + "top_solid_infill_flow_ratio": "1.09" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.14mm Extra Draft @Elegoo CC2 0.2 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.14mm Extra Draft @Elegoo CC2 0.2 nozzle.json index 69934b5680..1ec3f6f14d 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.14mm Extra Draft @Elegoo CC2 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.14mm Extra Draft @Elegoo CC2 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.10mm Standard @Elegoo CC2 0.2 nozzle", - "layer_height": "0.14", "name": "0.14mm Extra Draft @Elegoo CC2 0.2 nozzle", + "inherits": "0.10mm Standard @Elegoo CC2 0.2 nozzle", "from": "system", "setting_id": "falXCyvjKInAQBuU", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.14" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.16mm Extra Fine @Elegoo CC2 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.16mm Extra Fine @Elegoo CC2 0.8 nozzle.json index e5de49c2fc..65bf021f37 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.16mm Extra Fine @Elegoo CC2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.16mm Extra Fine @Elegoo CC2 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.16", "name": "0.16mm Extra Fine @Elegoo CC2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", "from": "system", "setting_id": "fkdUtfBU1HkWIIvT", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.16mm Optimal @Elegoo CC2 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.16mm Optimal @Elegoo CC2 0.4 nozzle.json index 82cebc5760..9fb8d633c4 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.16mm Optimal @Elegoo CC2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.16mm Optimal @Elegoo CC2 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", - "layer_height": "0.16", "name": "0.16mm Optimal @Elegoo CC2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", "from": "system", "setting_id": "et3r9GAefxCq9TSq", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.18mm Fine @Elegoo CC2 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.18mm Fine @Elegoo CC2 0.6 nozzle.json index a8c83adc07..739c4695b1 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.18mm Fine @Elegoo CC2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.18mm Fine @Elegoo CC2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", - "layer_height": "0.18", "name": "0.18mm Fine @Elegoo CC2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", "from": "system", "setting_id": "zpijb8su3jIgrND9", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.18" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.20mm Strength @Elegoo CC2 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.20mm Strength @Elegoo CC2 0.4 nozzle.json index d3374f99e0..92db8b43a7 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.20mm Strength @Elegoo CC2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.20mm Strength @Elegoo CC2 0.4 nozzle.json @@ -1,8 +1,10 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", "name": "0.20mm Strength @Elegoo CC2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", "from": "system", + "setting_id": "jTiebnbHJERoOZ2Y", + "instantiation": "true", "wall_sequence": "inner wall/outer wall", "reduce_crossing_wall": "0", "bottom_shell_layers": "5", @@ -11,7 +13,5 @@ "sparse_infill_density": "20%", "top_shell_layers": "6", "wall_loops": "5", - "top_solid_infill_flow_ratio": "1.09", - "setting_id": "jTiebnbHJERoOZ2Y", - "instantiation": "true" + "top_solid_infill_flow_ratio": "1.09" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.24mm Draft @Elegoo CC2 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.24mm Draft @Elegoo CC2 0.4 nozzle.json index cb28d46e8d..fd84b8c167 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.24mm Draft @Elegoo CC2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.24mm Draft @Elegoo CC2 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", - "layer_height": "0.24", "name": "0.24mm Draft @Elegoo CC2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", "from": "system", "setting_id": "dw8ZgRee5mUlNdon", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.24mm Fine @Elegoo CC2 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.24mm Fine @Elegoo CC2 0.8 nozzle.json index 1df6cf54a0..111f740966 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.24mm Fine @Elegoo CC2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.24mm Fine @Elegoo CC2 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", - "initial_layer_print_height": "0.3", - "layer_height": "0.24", "name": "0.24mm Fine @Elegoo CC2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", "from": "system", "setting_id": "TrKMkazV6my94O8Q", - "instantiation": "true" + "instantiation": "true", + "initial_layer_print_height": "0.3", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.24mm Optimal @Elegoo CC2 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.24mm Optimal @Elegoo CC2 0.6 nozzle.json index e559bf36ca..b9d53c20bc 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.24mm Optimal @Elegoo CC2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.24mm Optimal @Elegoo CC2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", - "layer_height": "0.24", "name": "0.24mm Optimal @Elegoo CC2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", "from": "system", "setting_id": "VfcmVzpWGuafr5C8", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.28mm Extra Draft @Elegoo CC2 0.4 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.28mm Extra Draft @Elegoo CC2 0.4 nozzle.json index f7259db276..335d024ec0 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.28mm Extra Draft @Elegoo CC2 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.28mm Extra Draft @Elegoo CC2 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", - "layer_height": "0.28", "name": "0.28mm Extra Draft @Elegoo CC2 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo CC2 0.4 nozzle", "from": "system", "setting_id": "iOd2EdXRnWMT6VZM", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.30mm Strength @Elegoo CC2 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.30mm Strength @Elegoo CC2 0.6 nozzle.json index 7b67d63e18..798c769cd2 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.30mm Strength @Elegoo CC2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.30mm Strength @Elegoo CC2 0.6 nozzle.json @@ -1,15 +1,15 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", - "inner_wall_speed": "120", "name": "0.30mm Strength @Elegoo CC2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", "from": "system", + "setting_id": "qvgkuo9AInajHCez", + "instantiation": "true", + "inner_wall_speed": "120", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "outer_wall_speed": "80", "sparse_infill_density": "15%", "top_surface_speed": "120", - "wall_loops": "4", - "setting_id": "qvgkuo9AInajHCez", - "instantiation": "true" + "wall_loops": "4" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.32mm Optimal @Elegoo CC2 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.32mm Optimal @Elegoo CC2 0.8 nozzle.json index e84edc7edf..1caa6083a2 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.32mm Optimal @Elegoo CC2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.32mm Optimal @Elegoo CC2 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", - "layer_height": "0.32", "name": "0.32mm Optimal @Elegoo CC2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", "from": "system", "setting_id": "3l5lU1sBxbMAzV6x", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.36mm Draft @Elegoo CC2 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.36mm Draft @Elegoo CC2 0.6 nozzle.json index 41479b76b1..e892c976fd 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.36mm Draft @Elegoo CC2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.36mm Draft @Elegoo CC2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", - "layer_height": "0.36", "name": "0.36mm Draft @Elegoo CC2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", "from": "system", "setting_id": "S1MtBrEo884gfhm3", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.42mm Extra Draft @Elegoo CC2 0.6 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.42mm Extra Draft @Elegoo CC2 0.6 nozzle.json index debbe6ef13..10f98d7d2e 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.42mm Extra Draft @Elegoo CC2 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.42mm Extra Draft @Elegoo CC2 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", - "layer_height": "0.42", "name": "0.42mm Extra Draft @Elegoo CC2 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo CC2 0.6 nozzle", "from": "system", "setting_id": "Du73E9Zw3cOyKZYb", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/ECC2/0.48mm Draft @Elegoo CC2 0.8 nozzle.json b/resources/profiles/Elegoo/process/ECC2/0.48mm Draft @Elegoo CC2 0.8 nozzle.json index 08006c453f..b7786ea559 100644 --- a/resources/profiles/Elegoo/process/ECC2/0.48mm Draft @Elegoo CC2 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/ECC2/0.48mm Draft @Elegoo CC2 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", - "layer_height": "0.48", "name": "0.48mm Draft @Elegoo CC2 0.8 nozzle", + "inherits": "0.40mm Standard @Elegoo CC2 0.8 nozzle", "from": "system", "setting_id": "K7hJQ2Kzyu7kgmCx", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.12mm Fine @Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.12mm Fine @Elegoo Neptune 0.4 nozzle.json index cd7a6f60ae..b7a1867e5a 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.12mm Fine @Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.12mm Fine @Elegoo Neptune 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "setting_id": "x7ZbjKUNtGbCsJWr", - "from": "system", - "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", "name": "0.12mm Fine @Elegoo Neptune 0.4 nozzle", - "layer_height": "0.12", - "wall_loops": "3", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune;0.08mm Extra Fine @Elegoo Neptune2;0.08mm Extra Fine @Elegoo Neptune2D;0.08mm Extra Fine @Elegoo Neptune2S;0.08mm Extra Fine @Elegoo NeptuneX;0.12mm Fine @Elegoo Neptune;0.12mm Fine @Elegoo Neptune2;0.12mm Fine @Elegoo Neptune2D;0.12mm Fine @Elegoo Neptune2S;0.12mm Fine @Elegoo NeptuneX", + "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", + "from": "system", + "setting_id": "x7ZbjKUNtGbCsJWr", "instantiation": "true", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune;0.08mm Extra Fine @Elegoo Neptune2;0.08mm Extra Fine @Elegoo Neptune2D;0.08mm Extra Fine @Elegoo Neptune2S;0.08mm Extra Fine @Elegoo NeptuneX;0.12mm Fine @Elegoo Neptune;0.12mm Fine @Elegoo Neptune2;0.12mm Fine @Elegoo Neptune2D;0.12mm Fine @Elegoo Neptune2S;0.12mm Fine @Elegoo NeptuneX" + "layer_height": "0.12", + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.16mm Optimal @Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.16mm Optimal @Elegoo Neptune 0.4 nozzle.json index c616506306..79e11c97f4 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.16mm Optimal @Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.16mm Optimal @Elegoo Neptune 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "dmdjW1ZxuWAXgArQ", - "from": "system", - "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", "name": "0.16mm Optimal @Elegoo Neptune 0.4 nozzle", - "layer_height": "0.16", + "renamed_from": "0.16mm Optimal @Elegoo Neptune;0.16mm Optimal @Elegoo Neptune2;0.16mm Optimal @Elegoo Neptune2D;0.16mm Optimal @Elegoo Neptune2S;0.16mm Optimal @Elegoo NeptuneX", + "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", + "from": "system", + "setting_id": "dmdjW1ZxuWAXgArQ", "instantiation": "true", - "renamed_from": "0.16mm Optimal @Elegoo Neptune;0.16mm Optimal @Elegoo Neptune2;0.16mm Optimal @Elegoo Neptune2D;0.16mm Optimal @Elegoo Neptune2S;0.16mm Optimal @Elegoo NeptuneX" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Standard @Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Standard @Elegoo Neptune 0.4 nozzle.json index fce4e6ea2a..b1d56aef44 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Standard @Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Standard @Elegoo Neptune 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "ivuelLxit3DxpCQf", "name": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune;0.20mm Standard @Elegoo Neptune2;0.20mm Standard @Elegoo Neptune2D;0.20mm Standard @Elegoo Neptune2S;0.20mm Standard @Elegoo NeptuneX", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "ivuelLxit3DxpCQf", "instantiation": "true", "filename_format": "{nozzle_diameter[0]}{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "1000", @@ -34,6 +35,5 @@ "Elegoo Neptune 2S 0.4 nozzle", "Elegoo Neptune 2D 0.4 nozzle", "Elegoo Neptune 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune;0.20mm Standard @Elegoo Neptune2;0.20mm Standard @Elegoo Neptune2D;0.20mm Standard @Elegoo Neptune2S;0.20mm Standard @Elegoo NeptuneX" + ] } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Strength @Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Strength @Elegoo Neptune 0.4 nozzle.json index e7c2cc6460..56ea858aa7 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Strength @Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.20mm Strength @Elegoo Neptune 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "setting_id": "7o8beRTTV9kahf6c", - "from": "system", - "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", "name": "0.20mm Strength @Elegoo Neptune 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", + "from": "system", + "setting_id": "7o8beRTTV9kahf6c", + "instantiation": "true", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", - "wall_loops": "6", - "instantiation": "true" + "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Draft @Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Draft @Elegoo Neptune 0.4 nozzle.json index 939d9d3e0d..4d5178d0ff 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Draft @Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Draft @Elegoo Neptune 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "AQnZ1c7zUfkqHzUV", - "from": "system", - "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", "name": "0.24mm Draft @Elegoo Neptune 0.4 nozzle", - "layer_height": "0.24", + "renamed_from": "0.24mm Draft @Elegoo Neptune;0.24mm Draft @Elegoo Neptune2;0.24mm Draft @Elegoo Neptune2D;0.24mm Draft @Elegoo Neptune2S;0.24mm Draft @Elegoo NeptuneX", + "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", + "from": "system", + "setting_id": "AQnZ1c7zUfkqHzUV", "instantiation": "true", - "renamed_from": "0.24mm Draft @Elegoo Neptune;0.24mm Draft @Elegoo Neptune2;0.24mm Draft @Elegoo Neptune2D;0.24mm Draft @Elegoo Neptune2S;0.24mm Draft @Elegoo NeptuneX" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Fine @Elegoo Neptune 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Fine @Elegoo Neptune 0.8 nozzle.json index 5ecf1d6597..1195505088 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Fine @Elegoo Neptune 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Fine @Elegoo Neptune 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "58PjDN7iOw2uuKCa", - "from": "system", "name": "0.24mm Fine @Elegoo Neptune 0.8 nozzle", "inherits": "0.40mm Standard @Elegoo Neptune 0.8 nozzle", - "layer_height": "0.24", - "instantiation": "true" + "from": "system", + "setting_id": "58PjDN7iOw2uuKCa", + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Optimal @Elegoo Neptune 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Optimal @Elegoo Neptune 0.6 nozzle.json index 4564e2836a..c0e47c5aa5 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Optimal @Elegoo Neptune 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.24mm Optimal @Elegoo Neptune 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "9TcC7ocHTTV5fO6u", - "from": "system", "name": "0.24mm Optimal @Elegoo Neptune 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Neptune 0.6 nozzle", - "layer_height": "0.24", - "instantiation": "true" + "from": "system", + "setting_id": "9TcC7ocHTTV5fO6u", + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.28mm Extra Draft @Elegoo Neptune 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.28mm Extra Draft @Elegoo Neptune 0.4 nozzle.json index dc1f40365c..8751d16bec 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.28mm Extra Draft @Elegoo Neptune 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.28mm Extra Draft @Elegoo Neptune 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "gZWSfkY2eEsk2BOj", - "from": "system", - "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo Neptune 0.4 nozzle", - "layer_height": "0.28", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune;0.28mm Extra Draft @Elegoo Neptune2;0.28mm Extra Draft @Elegoo Neptune2D;0.28mm Extra Draft @Elegoo Neptune2S;0.28mm Extra Draft @Elegoo NeptuneX", + "inherits": "0.20mm Standard @Elegoo Neptune 0.4 nozzle", + "from": "system", + "setting_id": "gZWSfkY2eEsk2BOj", "instantiation": "true", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune;0.28mm Extra Draft @Elegoo Neptune2;0.28mm Extra Draft @Elegoo Neptune2D;0.28mm Extra Draft @Elegoo Neptune2S;0.28mm Extra Draft @Elegoo NeptuneX" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.32mm Optimal @Elegoo Neptune 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.32mm Optimal @Elegoo Neptune 0.8 nozzle.json index 21508d6fcb..30262f4649 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.32mm Optimal @Elegoo Neptune 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.32mm Optimal @Elegoo Neptune 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "pubCZO4TSk26n9tN", - "from": "system", "name": "0.32mm Optimal @Elegoo Neptune 0.8 nozzle", "inherits": "0.40mm Standard @Elegoo Neptune 0.8 nozzle", - "layer_height": "0.32", - "instantiation": "true" + "from": "system", + "setting_id": "pubCZO4TSk26n9tN", + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.36mm Draft @Elegoo Neptune 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.36mm Draft @Elegoo Neptune 0.6 nozzle.json index 2c70c48f96..3fa40e6835 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.36mm Draft @Elegoo Neptune 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.36mm Draft @Elegoo Neptune 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "3uIERa8zvsPoVkk8", - "from": "system", "name": "0.36mm Draft @Elegoo Neptune 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Neptune 0.6 nozzle", - "layer_height": "0.36", - "instantiation": "true" + "from": "system", + "setting_id": "3uIERa8zvsPoVkk8", + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN2SERIES/0.42mm Extra Draft @Elegoo Neptune 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN2SERIES/0.42mm Extra Draft @Elegoo Neptune 0.6 nozzle.json index d0deeae0cd..e99545bc37 100644 --- a/resources/profiles/Elegoo/process/EN2SERIES/0.42mm Extra Draft @Elegoo Neptune 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN2SERIES/0.42mm Extra Draft @Elegoo Neptune 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "xvfDVb6XEH8USrny", - "from": "system", "name": "0.42mm Extra Draft @Elegoo Neptune 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Neptune 0.6 nozzle", - "layer_height": "0.42", - "instantiation": "true" + "from": "system", + "setting_id": "xvfDVb6XEH8USrny", + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Max 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Max 0.2 nozzle.json index c7551fea08..34ff7bf326 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Max 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Max 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N3Max 0.2 nozzle", - "from": "system", "inherits": "0.10mm Standard @Elegoo N3Max 0.2 nozzle", - "layer_height": "0.08", + "from": "system", "setting_id": "XEXWDtkuVN27Z0Ae", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Plus 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Plus 0.2 nozzle.json index 751845d1a7..4e47fdf3b2 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Plus 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Plus 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N3Plus 0.2 nozzle", - "from": "system", "inherits": "0.10mm Standard @Elegoo N3Plus 0.2 nozzle", - "layer_height": "0.08", + "from": "system", "setting_id": "oRNlKaMaOZS6N4pT", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Pro 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Pro 0.2 nozzle.json index 98dc95f83c..91f6449c43 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Pro 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.08mm Optimal @Elegoo N3Pro 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N3Pro 0.2 nozzle", - "from": "system", "inherits": "0.10mm Standard @Elegoo N3Pro 0.2 nozzle", - "layer_height": "0.08", + "from": "system", "setting_id": "4d4rm5pkuVEpvKUA", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Max 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Max 0.2 nozzle.json index 593b54ea29..eb407e5674 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Max 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Max 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N3Max 0.2 nozzle", - "from": "system", "inherits": "0.10mm Standard @Elegoo N3Max 0.2 nozzle", + "from": "system", "setting_id": "0tL8rTEK1rEksfWu", "instantiation": "true", "layer_height": "0.12" diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Plus 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Plus 0.2 nozzle.json index ac73a53ff0..001848ec26 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Plus 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Plus 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N3Plus 0.2 nozzle", - "from": "system", "inherits": "0.10mm Standard @Elegoo N3Plus 0.2 nozzle", - "layer_height": "0.12", + "from": "system", "setting_id": "4H7asjR6qAfYD1zA", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Pro 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Pro 0.2 nozzle.json index 93e0053162..52b0b59650 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Pro 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Draft @Elegoo N3Pro 0.2 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N3Pro 0.2 nozzle", - "from": "system", "inherits": "0.10mm Standard @Elegoo N3Pro 0.2 nozzle", - "layer_height": "0.12", + "from": "system", "setting_id": "B5TzYBAO9JaSXfj8", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Max 0.4 nozzle.json index df15921fc8..310f13fc98 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Max 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", "name": "0.12mm Fine @Elegoo N3Max 0.4 nozzle", - "layer_height": "0.12", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune3Max;0.12mm Fine @Elegoo Neptune3Max", + "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", + "from": "system", "setting_id": "EvN6TYCeyMKxI6Re", "instantiation": "true", - "wall_loops": "3", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune3Max;0.12mm Fine @Elegoo Neptune3Max" + "layer_height": "0.12", + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Plus 0.4 nozzle.json index 3ea7659416..41f6f6683b 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Plus 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", "name": "0.12mm Fine @Elegoo N3Plus 0.4 nozzle", - "layer_height": "0.12", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune3Plus;0.12mm Fine @Elegoo Neptune3Plus", + "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", + "from": "system", "setting_id": "7BlZuuOXdqTj6cV6", "instantiation": "true", - "wall_loops": "3", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune3Plus;0.12mm Fine @Elegoo Neptune3Plus" + "layer_height": "0.12", + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Pro 0.4 nozzle.json index e4e8b01040..6050a1a9cd 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.12mm Fine @Elegoo N3Pro 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", "name": "0.12mm Fine @Elegoo N3Pro 0.4 nozzle", - "layer_height": "0.12", - "wall_loops": "3", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune3;0.08mm Extra Fine @Elegoo Neptune3Pro;0.12mm Fine @Elegoo Neptune3;0.12mm Fine @Elegoo Neptune3Pro", + "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", + "from": "system", "setting_id": "sxbVyUoQQwvDwEgm", "instantiation": "true", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune3;0.08mm Extra Fine @Elegoo Neptune3Pro;0.12mm Fine @Elegoo Neptune3;0.12mm Fine @Elegoo Neptune3Pro" + "layer_height": "0.12", + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Max 0.4 nozzle.json index e6f3e04bc7..2fe8babd91 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", "name": "0.16mm Optimal @Elegoo N3Max 0.4 nozzle", - "layer_height": "0.16", + "renamed_from": "0.16mm Optimal @Elegoo Neptune3Max", + "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", + "from": "system", "setting_id": "TCM0SNa96VA5Dx2H", "instantiation": "true", - "renamed_from": "0.16mm Optimal @Elegoo Neptune3Max" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Plus 0.4 nozzle.json index bdcacf92c7..0d0c52e654 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", "name": "0.16mm Optimal @Elegoo N3Plus 0.4 nozzle", - "layer_height": "0.16", + "renamed_from": "0.16mm Optimal @Elegoo Neptune3Plus", + "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", + "from": "system", "setting_id": "WZhze0PkeqiyOdrj", "instantiation": "true", - "renamed_from": "0.16mm Optimal @Elegoo Neptune3Plus" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Pro 0.4 nozzle.json index 823a13b1be..bc0864f976 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.16mm Optimal @Elegoo N3Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", "name": "0.16mm Optimal @Elegoo N3Pro 0.4 nozzle", - "layer_height": "0.16", + "renamed_from": "0.16mm Optimal @Elegoo Neptune3;0.16mm Optimal @Elegoo Neptune3Pro", + "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", + "from": "system", "setting_id": "xSjvTTFHSiKGi5vc", "instantiation": "true", - "renamed_from": "0.16mm Optimal @Elegoo Neptune3;0.16mm Optimal @Elegoo Neptune3Pro" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Max 0.4 nozzle.json index badc9335be..0cd5f99157 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Max 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "YVbjgCkFSIfI9zDy", "name": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune3Max", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "YVbjgCkFSIfI9zDy", "instantiation": "true", "filename_format": "EN3Max_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "gap_infill_speed": "30", @@ -26,6 +27,5 @@ "travel_speed": "150", "compatible_printers": [ "Elegoo Neptune 3 Max 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune3Max" + ] } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Plus 0.4 nozzle.json index beb35d4ae7..00b47f0dbc 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Plus 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "t2QdKzmUAoGrZTl2", "name": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune3Plus", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "t2QdKzmUAoGrZTl2", "instantiation": "true", "filename_format": "EN3Plus_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "1000", @@ -26,6 +27,5 @@ "travel_speed": "200", "compatible_printers": [ "Elegoo Neptune 3 Plus 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune3Plus" + ] } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Pro 0.4 nozzle.json index 68635c0424..eabbef58d0 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Standard @Elegoo N3Pro 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "Z6E0SkSXvbyrgCwI", "name": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune3;0.20mm Standard @Elegoo Neptune3Pro", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "Z6E0SkSXvbyrgCwI", "instantiation": "true", "filename_format": "EN3Pro_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "1000", @@ -26,6 +27,5 @@ "travel_speed": "200", "compatible_printers": [ "Elegoo Neptune 3 Pro 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune3;0.20mm Standard @Elegoo Neptune3Pro" + ] } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Max 0.4 nozzle.json index 5e666a782f..cb5d6ce635 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Max 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", "name": "0.20mm Strength @Elegoo N3Max 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", + "from": "system", + "setting_id": "F9cFxKIj5tmaKw0q", + "instantiation": "true", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", - "wall_loops": "6", - "setting_id": "F9cFxKIj5tmaKw0q", - "instantiation": "true" + "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Plus 0.4 nozzle.json index b5b6ce375a..1d98f8670c 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Plus 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", "name": "0.20mm Strength @Elegoo N3Plus 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", + "from": "system", + "setting_id": "dUTKuxKR2EutaNmT", + "instantiation": "true", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", - "wall_loops": "6", - "setting_id": "dUTKuxKR2EutaNmT", - "instantiation": "true" + "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Pro 0.4 nozzle.json index a369fa15e4..e2739cccf6 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.20mm Strength @Elegoo N3Pro 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", "name": "0.20mm Strength @Elegoo N3Pro 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", + "from": "system", + "setting_id": "8A1LaTaH5mFRXIRT", + "instantiation": "true", "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", - "wall_loops": "6", - "setting_id": "8A1LaTaH5mFRXIRT", - "instantiation": "true" + "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Max 0.4 nozzle.json index 81bbeed822..8ea3de4a8a 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", "name": "0.24mm Draft @Elegoo N3Max 0.4 nozzle", - "layer_height": "0.24", + "renamed_from": "0.24mm Draft @Elegoo Neptune3Max", + "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", + "from": "system", "setting_id": "4cjFrdHJQUTXPlhY", "instantiation": "true", - "renamed_from": "0.24mm Draft @Elegoo Neptune3Max" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Plus 0.4 nozzle.json index 647186a296..583b2b0aa9 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", "name": "0.24mm Draft @Elegoo N3Plus 0.4 nozzle", - "layer_height": "0.24", + "renamed_from": "0.24mm Draft @Elegoo Neptune3Plus", + "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", + "from": "system", "setting_id": "YVe8MEaJXZUeE3h4", "instantiation": "true", - "renamed_from": "0.24mm Draft @Elegoo Neptune3Plus" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Pro 0.4 nozzle.json index 84bfc06411..3c4c32a08e 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Draft @Elegoo N3Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", "name": "0.24mm Draft @Elegoo N3Pro 0.4 nozzle", - "layer_height": "0.24", + "renamed_from": "0.24mm Draft @Elegoo Neptune3;0.24mm Draft @Elegoo Neptune3Pro", + "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", + "from": "system", "setting_id": "D8EjvZ18sgk2kVfO", "instantiation": "true", - "renamed_from": "0.24mm Draft @Elegoo Neptune3;0.24mm Draft @Elegoo Neptune3Pro" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Max 0.8 nozzle.json index 9f1fb265ca..01f46c671b 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Max 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N3Max 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Max 0.8 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "AIFj2Nkig3Xe3f80", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Plus 0.8 nozzle.json index 05753f9621..7c37971f9d 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Plus 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N3Plus 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Plus 0.8 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "Fo9SwcT3g26U1cJO", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Pro 0.8 nozzle.json index 2c43b42df2..900bd39899 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Fine @Elegoo N3Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N3Pro 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Pro 0.8 nozzle", + "from": "system", "setting_id": "QEh6pEz7MS4x51QA", "instantiation": "true", "layer_height": "0.24" diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Max 0.6 nozzle.json index 9284fa65e4..ff37a1d0f2 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Max 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N3Max 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Max 0.6 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "sRz0TXDOEWnLxXh5", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Plus 0.6 nozzle.json index dbf6f01505..c71c7c422d 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Plus 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N3Plus 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Plus 0.6 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "T7cpTs4IIK8zix8P", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Pro 0.6 nozzle.json index a0fbc1a58b..52ea4e8c08 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.24mm Optimal @Elegoo N3Pro 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N3Pro 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Pro 0.6 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "T2QWt3peRdwFJFXE", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Max 0.4 nozzle.json index 5feef5dfe9..168d00b90f 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N3Max 0.4 nozzle", - "layer_height": "0.28", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune3Max", + "inherits": "0.20mm Standard @Elegoo N3Max 0.4 nozzle", + "from": "system", "setting_id": "nJX8mCa1nrWxYsEd", "instantiation": "true", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune3Max" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Plus 0.4 nozzle.json index 45b060a748..ae7381a4a4 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N3Plus 0.4 nozzle", - "layer_height": "0.28", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune3Plus", + "inherits": "0.20mm Standard @Elegoo N3Plus 0.4 nozzle", + "from": "system", "setting_id": "7ZbuPzdEsBEeZlOC", "instantiation": "true", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune3Plus" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Pro 0.4 nozzle.json index fbfcb2f8c4..d6d3d8eb3d 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.28mm Extra Draft @Elegoo N3Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N3Pro 0.4 nozzle", - "layer_height": "0.28", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune3;0.28mm Extra Draft @Elegoo Neptune3Pro", + "inherits": "0.20mm Standard @Elegoo N3Pro 0.4 nozzle", + "from": "system", "setting_id": "pcBUWmShCb8ii1Ro", "instantiation": "true", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune3;0.28mm Extra Draft @Elegoo Neptune3Pro" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Max 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Max 1.0 nozzle.json index 524e501772..413db6d902 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Max 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Max 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N3Max 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Max 1.0 nozzle", - "layer_height": "0.3", + "from": "system", "setting_id": "HMDmYxoPgPEF3o2k", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.3" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Plus 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Plus 1.0 nozzle.json index 88ad4e385a..121f851b6c 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Plus 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Plus 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N3Plus 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Plus 1.0 nozzle", - "layer_height": "0.3", + "from": "system", "setting_id": "nnGIKTAThcIjqiNY", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.3" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Pro 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Pro 1.0 nozzle.json index d33a7620be..f22d330a05 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Pro 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.30mm Fine @Elegoo N3Pro 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N3Pro 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Pro 1.0 nozzle", - "layer_height": "0.3", + "from": "system", "setting_id": "PGLk0C6CFjdJgUD2", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.3" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Max 0.8 nozzle.json index 540bafd120..a46bb223e2 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Max 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N3Max 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Max 0.8 nozzle", - "layer_height": "0.32", + "from": "system", "setting_id": "EuI4NCtPdnDgCwod", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Plus 0.8 nozzle.json index de45890943..e3e6ad27cc 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Plus 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N3Plus 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Plus 0.8 nozzle", - "layer_height": "0.32", + "from": "system", "setting_id": "cWbafri96E6xdetF", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Pro 0.8 nozzle.json index 2b0823c3fb..24a6026cc0 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.32mm Optimal @Elegoo N3Pro 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N3Pro 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Pro 0.8 nozzle", - "layer_height": "0.32", + "from": "system", "setting_id": "JyNhgxXpE3QGd22F", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Max 0.6 nozzle.json index 3a5b561cb7..7936351746 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Max 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N3Max 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Max 0.6 nozzle", - "layer_height": "0.36", + "from": "system", "setting_id": "lyUQ9qqdlT3xOjLa", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Plus 0.6 nozzle.json index ab050a47a5..c0aa4c85a1 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Plus 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N3Plus 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Plus 0.6 nozzle", - "layer_height": "0.36", + "from": "system", "setting_id": "9fgmDydMRIQt1EMc", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Pro 0.6 nozzle.json index 4d306b8c9c..477693abdb 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.36mm Draft @Elegoo N3Pro 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N3Pro 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Pro 0.6 nozzle", - "layer_height": "0.36", + "from": "system", "setting_id": "y577AyAVfQm2t7MC", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Max 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Max 1.0 nozzle.json index b385b6032b..087e4e4187 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Max 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Max 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N3Max 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Max 1.0 nozzle", - "layer_height": "0.4", + "from": "system", "setting_id": "SVth0sMD2ndZBpxW", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.4" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Plus 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Plus 1.0 nozzle.json index 8671652915..0103f473fc 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Plus 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Plus 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N3Plus 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Plus 1.0 nozzle", - "layer_height": "0.4", + "from": "system", "setting_id": "Bg9wsz7gRUfhdsxO", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.4" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Pro 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Pro 1.0 nozzle.json index 24b31b6c1a..f129f697b1 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Pro 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.40mm Optimal @Elegoo N3Pro 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N3Pro 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Pro 1.0 nozzle", - "layer_height": "0.4", + "from": "system", "setting_id": "TTj088WcmPAL0J2v", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.4" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Max 0.6 nozzle.json index 64e16d4207..d7408a5423 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Max 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N3Max 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Max 0.6 nozzle", - "layer_height": "0.42", + "from": "system", "setting_id": "q8wRFEbNbhFiR68s", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Plus 0.6 nozzle.json index 001039fd99..9baa0bd846 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Plus 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N3Plus 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Plus 0.6 nozzle", - "layer_height": "0.42", + "from": "system", "setting_id": "S3XpelIawW7YF0tp", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Pro 0.6 nozzle.json index 72aa6be907..f34162a375 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.42mm Extra Draft @Elegoo N3Pro 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N3Pro 0.6 nozzle", - "from": "system", "inherits": "0.30mm Standard @Elegoo N3Pro 0.6 nozzle", - "layer_height": "0.42", + "from": "system", "setting_id": "fZmtvPZ1k15dep6l", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Max 0.8 nozzle.json index fc26633f8a..9cebf8ef94 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Max 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N3Max 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Max 0.8 nozzle", - "layer_height": "0.48", + "from": "system", "setting_id": "xpdQ4VMjMsYWaLNA", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Plus 0.8 nozzle.json index f7286e3bb5..c24c66df3c 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Plus 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N3Plus 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Plus 0.8 nozzle", - "layer_height": "0.48", + "from": "system", "setting_id": "5H03Otf81sLLUkRT", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Pro 0.8 nozzle.json index cb5da8f8da..ea5736e51a 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.48mm Draft @Elegoo N3Pro 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N3Pro 0.8 nozzle", - "from": "system", "inherits": "0.40mm Standard @Elegoo N3Pro 0.8 nozzle", - "layer_height": "0.48", + "from": "system", "setting_id": "kC1SOTD5KAkOvmkd", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Max 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Max 1.0 nozzle.json index 4334cd2fb8..a924ba7465 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Max 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Max 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N3Max 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Max 1.0 nozzle", - "layer_height": "0.6", + "from": "system", "setting_id": "VDAPQAbVmGJlCEUB", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.6" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Plus 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Plus 1.0 nozzle.json index 54172dcdbe..81b9e2705e 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Plus 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Plus 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N3Plus 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Plus 1.0 nozzle", - "layer_height": "0.6", + "from": "system", "setting_id": "M67oOpMsXtZzCcLQ", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.6" } diff --git a/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Pro 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Pro 1.0 nozzle.json index 26d78b0da3..3038e060d6 100644 --- a/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Pro 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN3SERIES/0.60mm Draft @Elegoo N3Pro 1.0 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N3Pro 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N3Pro 1.0 nozzle", - "layer_height": "0.6", + "from": "system", "setting_id": "FTb0W3wG9mNPkONL", - "instantiation": "true" + "instantiation": "true", + "layer_height": "0.6" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4 0.2 nozzle.json index bb30a9622a..a0902f4a38 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N4 0.2 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4 (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4 0.2 nozzle", + "from": "system", "setting_id": "mPn1wANI8OeyLWGt", "instantiation": "true", - "layer_height": "0.08", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4 (0.2 nozzle)" + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Max 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Max 0.2 nozzle.json index 93bcefb615..a35cfc7024 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Max 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Max 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N4Max 0.2 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4Max (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4Max 0.2 nozzle", + "from": "system", "setting_id": "n72kCNTZ1ILUzaiJ", "instantiation": "true", - "layer_height": "0.08", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4Max (0.2 nozzle)" + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Plus 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Plus 0.2 nozzle.json index 5f663fb35c..a9db44da77 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Plus 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Plus 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N4Plus 0.2 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4 Plus (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4Plus 0.2 nozzle", + "from": "system", "setting_id": "apACoiYg6U3Z0xwK", "instantiation": "true", - "layer_height": "0.08", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4 Plus (0.2 nozzle)" + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Pro 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Pro 0.2 nozzle.json index ae08228f0f..3435578e98 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Pro 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.08mm Optimal @Elegoo N4Pro 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.08mm Optimal @Elegoo N4Pro 0.2 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4Pro (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4Pro 0.2 nozzle", + "from": "system", "setting_id": "tY0jBQmvK2chT34r", "instantiation": "true", - "layer_height": "0.08", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.2 nozzle);0.16mm Optimal @Elegoo Neptune4Pro (0.2 nozzle)" + "layer_height": "0.08" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4 0.2 nozzle.json index fc4663a2fd..d431496ddc 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.10mm Standard @Elegoo N4 0.2 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.2 nozzle)", "inherits": "fdm_process_elegoo_02010", "from": "system", "setting_id": "j8LrMhjmrrWEcnSl", @@ -12,6 +13,5 @@ ], "default_acceleration": "6000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "5000", - "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.2 nozzle)" + "outer_wall_acceleration": "5000" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Max 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Max 0.2 nozzle.json index 793f694514..936cefd906 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Max 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Max 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.10mm Standard @Elegoo N4Max 0.2 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.2 nozzle)", "inherits": "fdm_process_elegoo_02010", "from": "system", "setting_id": "zFHnOUd2WXdPG1d0", @@ -12,6 +13,5 @@ ], "default_acceleration": "3000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "1500", - "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.2 nozzle)" + "outer_wall_acceleration": "1500" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Plus 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Plus 0.2 nozzle.json index 4064775c34..17983a171c 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Plus 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Plus 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.10mm Standard @Elegoo N4Plus 0.2 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.2 nozzle)", "inherits": "fdm_process_elegoo_02010", "from": "system", "setting_id": "RpheR4sGaJlp7yJp", @@ -12,6 +13,5 @@ ], "default_acceleration": "5000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "2500", - "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.2 nozzle)" + "outer_wall_acceleration": "2500" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Pro 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Pro 0.2 nozzle.json index 6f611b6f10..856403c945 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Pro 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.10mm Standard @Elegoo N4Pro 0.2 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.10mm Standard @Elegoo N4Pro 0.2 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.2 nozzle)", "inherits": "fdm_process_elegoo_02010", "from": "system", "setting_id": "EH1TvdVsdTCuvv2c", @@ -12,6 +13,5 @@ ], "default_acceleration": "6000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "5000", - "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.2 nozzle)" + "outer_wall_acceleration": "5000" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4 0.2 nozzle.json index fea092f942..903f60ea17 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N4 0.2 nozzle", - "from": "system", + "renamed_from": "0.12mm Fine @Elegoo Neptune4 (0.2 nozzle);0.24mm Draft @Elegoo Neptune4 (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4 (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4 0.2 nozzle", + "from": "system", "setting_id": "Vis3rzOs4NILDE6C", "instantiation": "true", - "layer_height": "0.12", - "renamed_from": "0.12mm Fine @Elegoo Neptune4 (0.2 nozzle);0.24mm Draft @Elegoo Neptune4 (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4 (0.2 nozzle)" + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Max 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Max 0.2 nozzle.json index 318662d214..eac769ef26 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Max 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Max 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N4Max 0.2 nozzle", - "from": "system", + "renamed_from": "0.12mm Fine @Elegoo Neptune4Max (0.2 nozzle);0.24mm Draft @Elegoo Neptune4Max (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4Max (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4Max 0.2 nozzle", + "from": "system", "setting_id": "BdbN0fjzy0GtRZty", "instantiation": "true", - "layer_height": "0.12", - "renamed_from": "0.12mm Fine @Elegoo Neptune4Max (0.2 nozzle);0.24mm Draft @Elegoo Neptune4Max (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4Max (0.2 nozzle)" + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Plus 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Plus 0.2 nozzle.json index 5e6c3b13b0..1a26f69852 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Plus 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Plus 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N4Plus 0.2 nozzle", - "from": "system", + "renamed_from": "0.12mm Fine @Elegoo Neptune4 Plus (0.2 nozzle);0.24mm Draft @Elegoo Neptune4 Plus (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4 Plus (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4Plus 0.2 nozzle", + "from": "system", "setting_id": "zPlAvLncVwzD1wCI", "instantiation": "true", - "layer_height": "0.12", - "renamed_from": "0.12mm Fine @Elegoo Neptune4 Plus (0.2 nozzle);0.24mm Draft @Elegoo Neptune4 Plus (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4 Plus (0.2 nozzle)" + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Pro 0.2 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Pro 0.2 nozzle.json index 62ceae2703..04fbd5753f 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Pro 0.2 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Draft @Elegoo N4Pro 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.12mm Draft @Elegoo N4Pro 0.2 nozzle", - "from": "system", + "renamed_from": "0.12mm Fine @Elegoo Neptune4Pro (0.2 nozzle);0.24mm Draft @Elegoo Neptune4Pro (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4Pro (0.2 nozzle)", "inherits": "0.10mm Standard @Elegoo N4Pro 0.2 nozzle", + "from": "system", "setting_id": "UpIR8nVGr9eXImwd", "instantiation": "true", - "layer_height": "0.12", - "renamed_from": "0.12mm Fine @Elegoo Neptune4Pro (0.2 nozzle);0.24mm Draft @Elegoo Neptune4Pro (0.2 nozzle);0.28mm Extra Draft @Elegoo Neptune4Pro (0.2 nozzle)" + "layer_height": "0.12" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4 0.4 nozzle.json index 4c4e045ce5..659e6ea759 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", + "name": "0.12mm Fine @Elegoo N4 0.4 nozzle", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.4 nozzle);0.12mm Fine @Elegoo Neptune4 (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", + "from": "system", "setting_id": "RQ9dC2A0MkeEXleJ", "instantiation": "true", - "name": "0.12mm Fine @Elegoo N4 0.4 nozzle", "layer_height": "0.12", - "wall_loops": "3", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.4 nozzle);0.12mm Fine @Elegoo Neptune4 (0.4 nozzle)" + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Max 0.4 nozzle.json index afd2451e06..2eadf5cd0c 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Max 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", + "name": "0.12mm Fine @Elegoo N4Max 0.4 nozzle", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.4 nozzle);0.12mm Fine @Elegoo Neptune4Max (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", + "from": "system", "setting_id": "YJTSqtPEGZDih9XE", "instantiation": "true", - "name": "0.12mm Fine @Elegoo N4Max 0.4 nozzle", "layer_height": "0.12", - "wall_loops": "3", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.4 nozzle);0.12mm Fine @Elegoo Neptune4Max (0.4 nozzle)" + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Plus 0.4 nozzle.json index f69751563e..d2294ac9a0 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Plus 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", + "name": "0.12mm Fine @Elegoo N4Plus 0.4 nozzle", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.4 nozzle);0.12mm Fine @Elegoo Neptune4 Plus (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", + "from": "system", "setting_id": "9BipQyur4imL8jml", "instantiation": "true", - "name": "0.12mm Fine @Elegoo N4Plus 0.4 nozzle", "layer_height": "0.12", - "wall_loops": "3", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.4 nozzle);0.12mm Fine @Elegoo Neptune4 Plus (0.4 nozzle)" + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Pro 0.4 nozzle.json index 500ba47b84..c73263f6ff 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.12mm Fine @Elegoo N4Pro 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", + "name": "0.12mm Fine @Elegoo N4Pro 0.4 nozzle", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.4 nozzle);0.12mm Fine @Elegoo Neptune4Pro (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", + "from": "system", "setting_id": "iN9aVhyxLhUdhDdG", "instantiation": "true", - "name": "0.12mm Fine @Elegoo N4Pro 0.4 nozzle", "layer_height": "0.12", - "wall_loops": "3", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.4 nozzle);0.12mm Fine @Elegoo Neptune4Pro (0.4 nozzle)" + "wall_loops": "3" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4 0.4 nozzle.json index 819552c612..5c44b2ae5a 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.16mm Optimal @Elegoo N4 0.4 nozzle", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4 (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", + "from": "system", "setting_id": "Cbq6b2Enl5dz7R61", "instantiation": "true", - "name": "0.16mm Optimal @Elegoo N4 0.4 nozzle", - "layer_height": "0.16", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4 (0.4 nozzle)" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Max 0.4 nozzle.json index 05ad8379a9..e7283fb678 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.16mm Optimal @Elegoo N4Max 0.4 nozzle", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4Max (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", + "from": "system", "setting_id": "StpHJelrwAxTFcwx", "instantiation": "true", - "name": "0.16mm Optimal @Elegoo N4Max 0.4 nozzle", - "layer_height": "0.16", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4Max (0.4 nozzle)" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Plus 0.4 nozzle.json index b7e0e6bcb0..f1821e5c43 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.16mm Optimal @Elegoo N4Plus 0.4 nozzle", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4 Plus (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", + "from": "system", "setting_id": "rldSbNbKZcfEVZqR", "instantiation": "true", - "name": "0.16mm Optimal @Elegoo N4Plus 0.4 nozzle", - "layer_height": "0.16", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4 Plus (0.4 nozzle)" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Pro 0.4 nozzle.json index fe95ed6e04..a710a00b74 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.16mm Optimal @Elegoo N4Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.16mm Optimal @Elegoo N4Pro 0.4 nozzle", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4Pro (0.4 nozzle)", "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", + "from": "system", "setting_id": "SNO9sWlpg5QylF2U", "instantiation": "true", - "name": "0.16mm Optimal @Elegoo N4Pro 0.4 nozzle", - "layer_height": "0.16", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4Pro (0.4 nozzle)" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4 0.4 nozzle.json index 8904a2de16..e1386c5e48 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "KX7Cn4tNCSa1BMpF", "name": "0.20mm Standard @Elegoo N4 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.4 nozzle)", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "KX7Cn4tNCSa1BMpF", "instantiation": "true", "filename_format": "EN4_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "6000", @@ -12,6 +13,5 @@ "min_width_top_surface": "50%", "compatible_printers": [ "Elegoo Neptune 4 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Max 0.4 nozzle.json index 418d9824c0..349f1dab0c 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Max 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "6llMZka0sgQ4w50C", "name": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.4 nozzle)", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "6llMZka0sgQ4w50C", "instantiation": "true", "filename_format": "EN4Max_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "3000", @@ -12,6 +13,5 @@ "min_width_top_surface": "50%", "compatible_printers": [ "Elegoo Neptune 4 Max 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Plus 0.4 nozzle.json index 316a5d8dec..d31b34e6ce 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Plus 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "EWip2jSpsehCzgdG", "name": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.4 nozzle)", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "EWip2jSpsehCzgdG", "instantiation": "true", "filename_format": "EN4Plus_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "5000", @@ -12,6 +13,5 @@ "min_width_top_surface": "50%", "compatible_printers": [ "Elegoo Neptune 4 Plus 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Pro 0.4 nozzle.json index d9d74a5fb0..145afaa989 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Standard @Elegoo N4Pro 0.4 nozzle.json @@ -1,9 +1,10 @@ { "type": "process", - "setting_id": "ev7Dl6VzLoldRKK3", "name": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", - "from": "system", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.4 nozzle)", "inherits": "fdm_process_elegoo_04020", + "from": "system", + "setting_id": "ev7Dl6VzLoldRKK3", "instantiation": "true", "filename_format": "EN4Pro_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "default_acceleration": "6000", @@ -12,6 +13,5 @@ "min_width_top_surface": "50%", "compatible_printers": [ "Elegoo Neptune 4 Pro 0.4 nozzle" - ], - "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.4 nozzle)" + ] } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4 0.4 nozzle.json index 7b3f4c2e64..98cb1470f1 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", "name": "0.20mm Strength @Elegoo N4 0.4 nozzle", - "wall_sequence": "inner-outer-inner wall", + "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", + "from": "system", "setting_id": "WBaSzHgrqKENej4G", "instantiation": "true", + "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Max 0.4 nozzle.json index 54ad422763..f701643d83 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Max 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", "name": "0.20mm Strength @Elegoo N4Max 0.4 nozzle", - "wall_sequence": "inner-outer-inner wall", + "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", + "from": "system", "setting_id": "HaK3rpieMESKs6PY", "instantiation": "true", + "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Plus 0.4 nozzle.json index 831205c4d7..a61ed21ae8 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Plus 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", "name": "0.20mm Strength @Elegoo N4Plus 0.4 nozzle", - "wall_sequence": "inner-outer-inner wall", + "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", + "from": "system", "setting_id": "ad0UueKfT6sGUn0I", "instantiation": "true", + "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Pro 0.4 nozzle.json index 0d475532a4..71cd7c1b92 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.20mm Strength @Elegoo N4Pro 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", "name": "0.20mm Strength @Elegoo N4Pro 0.4 nozzle", - "wall_sequence": "inner-outer-inner wall", + "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", + "from": "system", "setting_id": "LrBDOuD4h741FItb", "instantiation": "true", + "wall_sequence": "inner-outer-inner wall", "reduce_crossing_wall": "1", "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4 0.4 nozzle.json index e0a2eaabd9..120ee7171f 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", "name": "0.24mm Draft @Elegoo N4 0.4 nozzle", + "renamed_from": "0.24mm Draft @Elegoo Neptune4 (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", + "from": "system", "setting_id": "3bX9fmM7GOKwsWLc", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.24mm Draft @Elegoo Neptune4 (0.4 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Max 0.4 nozzle.json index 7035c986c8..cdc064da5a 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", "name": "0.24mm Draft @Elegoo N4Max 0.4 nozzle", + "renamed_from": "0.24mm Draft @Elegoo Neptune4Max (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", + "from": "system", "setting_id": "I5pPHYUqGEV4faQe", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.24mm Draft @Elegoo Neptune4Max (0.4 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Plus 0.4 nozzle.json index aec452e1b0..07dbfe2095 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", "name": "0.24mm Draft @Elegoo N4Plus 0.4 nozzle", + "renamed_from": "0.24mm Draft @Elegoo Neptune4 Plus (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", + "from": "system", "setting_id": "TUwtXktoDMUFiUjH", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.24mm Draft @Elegoo Neptune4 Plus (0.4 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Pro 0.4 nozzle.json index 20acd0a27c..8cd1ca3d67 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Draft @Elegoo N4Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", "name": "0.24mm Draft @Elegoo N4Pro 0.4 nozzle", + "renamed_from": "0.24mm Draft @Elegoo Neptune4Pro (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", + "from": "system", "setting_id": "JSPwiPfUUfrEmRLx", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.24mm Draft @Elegoo Neptune4Pro (0.4 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4 0.8 nozzle.json index d093eeaf65..b073c67b8d 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N4 0.8 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.8 nozzle);0.12mm Fine @Elegoo Neptune4 (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4 0.8 nozzle", + "from": "system", "setting_id": "HUtKrGQKYKgX2DSp", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.8 nozzle);0.12mm Fine @Elegoo Neptune4 (0.8 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Max 0.8 nozzle.json index 493fd9ff9a..6c1b56167e 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Max 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N4Max 0.8 nozzle", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.8 nozzle);0.12mm Fine @Elegoo Neptune4Max (0.8 nozzle)", + "inherits": "0.40mm Standard @Elegoo N4Max 0.8 nozzle", "from": "system", "setting_id": "8eKtU9RlWvWk8MfS", "instantiation": "true", - "inherits": "0.40mm Standard @Elegoo N4Max 0.8 nozzle", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.8 nozzle);0.12mm Fine @Elegoo Neptune4Max (0.8 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Plus 0.8 nozzle.json index 6bdaeb44c2..697eac529b 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Plus 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N4Plus 0.8 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.8 nozzle);0.12mm Fine @Elegoo Neptune4 Plus (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Plus 0.8 nozzle", + "from": "system", "setting_id": "hRKqKq27wVaeLAPG", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.8 nozzle);0.12mm Fine @Elegoo Neptune4 Plus (0.8 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Pro 0.8 nozzle.json index 2449ed7c4b..4431caf445 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Fine @Elegoo N4Pro 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Fine @Elegoo N4Pro 0.8 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.8 nozzle);0.12mm Fine @Elegoo Neptune4Pro (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Pro 0.8 nozzle", + "from": "system", "setting_id": "OcNAeI4a7QtbFJ6W", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.8 nozzle);0.12mm Fine @Elegoo Neptune4Pro (0.8 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4 0.6 nozzle.json index ff72b55af4..be2bedfb89 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N4 0.6 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.6 nozzle);0.12mm Fine @Elegoo Neptune4 (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4 (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4 0.6 nozzle", + "from": "system", "setting_id": "EX3MNVdWZSogtuND", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 (0.6 nozzle);0.12mm Fine @Elegoo Neptune4 (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4 (0.6 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Max 0.6 nozzle.json index e54636a0b6..6b4eae42dc 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Max 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N4Max 0.6 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.6 nozzle);0.12mm Fine @Elegoo Neptune4Max (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4Max (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Max 0.6 nozzle", + "from": "system", "setting_id": "KvtJF6N8LWqwgBJu", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Max (0.6 nozzle);0.12mm Fine @Elegoo Neptune4Max (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4Max (0.6 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Plus 0.6 nozzle.json index fcbc9a9066..47582bb842 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Plus 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N4Plus 0.6 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.6 nozzle);0.12mm Fine @Elegoo Neptune4 Plus (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4 Plus (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Plus 0.6 nozzle", + "from": "system", "setting_id": "vVYW2JeI230MxnFV", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4 Plus (0.6 nozzle);0.12mm Fine @Elegoo Neptune4 Plus (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4 Plus (0.6 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Pro 0.6 nozzle.json index 9f225d96f5..da502a172d 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.24mm Optimal @Elegoo N4Pro 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.24mm Optimal @Elegoo N4Pro 0.6 nozzle", - "from": "system", + "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.6 nozzle);0.12mm Fine @Elegoo Neptune4Pro (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4Pro (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Pro 0.6 nozzle", + "from": "system", "setting_id": "3mpKq49ZsvU2jr1J", "instantiation": "true", - "layer_height": "0.24", - "renamed_from": "0.08mm Extra Fine @Elegoo Neptune4Pro (0.6 nozzle);0.12mm Fine @Elegoo Neptune4Pro (0.6 nozzle);0.16mm Optimal @Elegoo Neptune4Pro (0.6 nozzle)" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4 0.4 nozzle.json index 3495255fee..00031f343e 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N4 0.4 nozzle", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4 0.4 nozzle", + "from": "system", "setting_id": "d1EZu3O7DCEtvUo9", "instantiation": "true", - "layer_height": "0.28", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 (0.4 nozzle)" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Max 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Max 0.4 nozzle.json index 316c9f9376..8af768caee 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Max 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Max 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N4Max 0.4 nozzle", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Max (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4Max 0.4 nozzle", + "from": "system", "setting_id": "uBXPR8bbDu4tnfZ7", "instantiation": "true", - "layer_height": "0.28", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Max (0.4 nozzle)" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Plus 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Plus 0.4 nozzle.json index 195d30d125..4475997940 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Plus 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Plus 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N4Plus 0.4 nozzle", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 Plus (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4Plus 0.4 nozzle", + "from": "system", "setting_id": "McXTTMnfUYmOZHcI", "instantiation": "true", - "layer_height": "0.28", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 Plus (0.4 nozzle)" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Pro 0.4 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Pro 0.4 nozzle.json index 98e5594b4c..be50ba0bb3 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Pro 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.28mm Extra Draft @Elegoo N4Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", "name": "0.28mm Extra Draft @Elegoo N4Pro 0.4 nozzle", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Pro (0.4 nozzle)", + "inherits": "0.20mm Standard @Elegoo N4Pro 0.4 nozzle", + "from": "system", "setting_id": "qIl89vLzpnjOmZMG", "instantiation": "true", - "layer_height": "0.28", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Pro (0.4 nozzle)" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4 1.0 nozzle.json index f159ca8b8e..5f287a1ed6 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N4 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4 1.0 nozzle", + "from": "system", "setting_id": "LSxHoq8lDbiY0WwD", "instantiation": "true", "layer_height": "0.3" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Max 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Max 1.0 nozzle.json index 4dda55dcb9..c28369ad54 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Max 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Max 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N4Max 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Max 1.0 nozzle", + "from": "system", "setting_id": "Usm5LQIdEG5qte0Z", "instantiation": "true", "layer_height": "0.3" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Plus 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Plus 1.0 nozzle.json index 57db88d6c0..f14bbdd458 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Plus 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Plus 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N4Plus 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Plus 1.0 nozzle", + "from": "system", "setting_id": "sSKLKqIlQsgkvBoj", "instantiation": "true", "layer_height": "0.3" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Pro 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Pro 1.0 nozzle.json index 3b9ca2ba34..57661ac6a8 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Pro 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Fine @Elegoo N4Pro 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.30mm Fine @Elegoo N4Pro 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Pro 1.0 nozzle", + "from": "system", "setting_id": "Fs44Eg0QxZTwNB4i", "instantiation": "true", "layer_height": "0.3" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4 0.6 nozzle.json index 4b0d1d7041..92858aedd6 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Standard @Elegoo N4 0.6 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.6 nozzle)", "inherits": "fdm_process_elegoo_06030", "from": "system", "setting_id": "X0otPkxfrqhtmKyX", @@ -11,6 +12,5 @@ ], "default_acceleration": "6000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "5000", - "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.6 nozzle)" + "outer_wall_acceleration": "5000" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Max 0.6 nozzle.json index 9f10ee23f4..f8efc3ca05 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Max 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Standard @Elegoo N4Max 0.6 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.6 nozzle)", "inherits": "fdm_process_elegoo_06030", "from": "system", "setting_id": "Vy5RnlR6iFs2Uo4Z", @@ -11,6 +12,5 @@ ], "default_acceleration": "3000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "1500", - "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.6 nozzle)" + "outer_wall_acceleration": "1500" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Plus 0.6 nozzle.json index 653de53108..cea5c991e9 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Plus 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Standard @Elegoo N4Plus 0.6 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.6 nozzle)", "inherits": "fdm_process_elegoo_06030", "from": "system", "setting_id": "VtWElYWASazfYCCd", @@ -11,6 +12,5 @@ ], "default_acceleration": "5000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "2500", - "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.6 nozzle)" + "outer_wall_acceleration": "2500" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Pro 0.6 nozzle.json index 603c81acb4..291c14166b 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.30mm Standard @Elegoo N4Pro 0.6 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.30mm Standard @Elegoo N4Pro 0.6 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.6 nozzle)", "inherits": "fdm_process_elegoo_06030", "from": "system", "setting_id": "rNfnCbVknDzyGq7a", @@ -11,6 +12,5 @@ ], "default_acceleration": "6000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "5000", - "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.6 nozzle)" + "outer_wall_acceleration": "5000" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4 0.8 nozzle.json index 444ca610ff..e5049ab07b 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N4 0.8 nozzle", - "from": "system", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4 (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4 (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4 0.8 nozzle", + "from": "system", "setting_id": "qzrXP9bCuf6aoqg6", "instantiation": "true", - "layer_height": "0.32", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4 (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4 (0.8 nozzle)" + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Max 0.8 nozzle.json index b27212d71a..adfe70dbd2 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Max 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N4Max 0.8 nozzle", - "from": "system", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4Max (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4Max (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Max 0.8 nozzle", + "from": "system", "setting_id": "G3FnBHsN3NV7ZfTR", "instantiation": "true", - "layer_height": "0.32", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4Max (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4Max (0.8 nozzle)" + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Plus 0.8 nozzle.json index ab89009c71..9b6a97a83c 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Plus 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N4Plus 0.8 nozzle", - "from": "system", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4 Plus (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4 Plus (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Plus 0.8 nozzle", + "from": "system", "setting_id": "xbAlLK2WW32kCp3z", "instantiation": "true", - "layer_height": "0.32", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4 Plus (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4 Plus (0.8 nozzle)" + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Pro 0.8 nozzle.json index 2dd5be1fbf..09d0f7ee49 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.32mm Optimal @Elegoo N4Pro 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.32mm Optimal @Elegoo N4Pro 0.8 nozzle", - "from": "system", + "renamed_from": "0.16mm Optimal @Elegoo Neptune4Pro (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4Pro (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Pro 0.8 nozzle", + "from": "system", "setting_id": "KOk0kTX3EelPCG3R", "instantiation": "true", - "layer_height": "0.32", - "renamed_from": "0.16mm Optimal @Elegoo Neptune4Pro (0.8 nozzle);0.28mm Extra Draft @Elegoo Neptune4Pro (0.8 nozzle)" + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4 0.6 nozzle.json index 827c319064..b9c0a86537 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N4 0.6 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4 (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4 0.6 nozzle", + "from": "system", "setting_id": "RPUd5w4RMBgxhvgu", "instantiation": "true", - "layer_height": "0.36", - "renamed_from": "0.24mm Draft @Elegoo Neptune4 (0.6 nozzle)" + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Max 0.6 nozzle.json index 1facc52b31..886865680a 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Max 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N4Max 0.6 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4Max (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Max 0.6 nozzle", + "from": "system", "setting_id": "C9QhIRg3uvqiceM9", "instantiation": "true", - "layer_height": "0.36", - "renamed_from": "0.24mm Draft @Elegoo Neptune4Max (0.6 nozzle)" + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Plus 0.6 nozzle.json index 6e05f6655f..f00a560ddd 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Plus 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N4Plus 0.6 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4 Plus (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Plus 0.6 nozzle", + "from": "system", "setting_id": "6LT83N9zzhnyndd1", "instantiation": "true", - "layer_height": "0.36", - "renamed_from": "0.24mm Draft @Elegoo Neptune4 Plus (0.6 nozzle)" + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Pro 0.6 nozzle.json index 7380250779..7d981cc1b5 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.36mm Draft @Elegoo N4Pro 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.36mm Draft @Elegoo N4Pro 0.6 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4Pro (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Pro 0.6 nozzle", + "from": "system", "setting_id": "uV8fOfHicJZXuBrG", "instantiation": "true", - "layer_height": "0.36", - "renamed_from": "0.24mm Draft @Elegoo Neptune4Pro (0.6 nozzle)" + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4 1.0 nozzle.json index e1c9dc2ebf..41062da83d 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N4 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4 1.0 nozzle", + "from": "system", "setting_id": "knCmCemB0pCsXI9H", "instantiation": "true", "layer_height": "0.4" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Max 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Max 1.0 nozzle.json index 2db783f9c1..7184631de3 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Max 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Max 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N4Max 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Max 1.0 nozzle", + "from": "system", "setting_id": "O0MSBh9OeaZDP7ow", "instantiation": "true", "layer_height": "0.4" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Plus 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Plus 1.0 nozzle.json index f5abebabbb..6e57163463 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Plus 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Plus 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N4Plus 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Plus 1.0 nozzle", + "from": "system", "setting_id": "rxq0eIQKDme3F1Es", "instantiation": "true", "layer_height": "0.4" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Pro 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Pro 1.0 nozzle.json index 56bc5cd096..0798fc7630 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Pro 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Optimal @Elegoo N4Pro 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.40mm Optimal @Elegoo N4Pro 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Pro 1.0 nozzle", + "from": "system", "setting_id": "tc7tn1h9Sf3B0D0X", "instantiation": "true", "layer_height": "0.4" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4 0.8 nozzle.json index a07bccbda1..c4440bf396 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.40mm Standard @Elegoo N4 0.8 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.8 nozzle)", "inherits": "fdm_process_elegoo_08040", "from": "system", "setting_id": "VnE7I5kpYjaWE9TQ", @@ -11,6 +12,5 @@ ], "default_acceleration": "6000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "5000", - "renamed_from": "0.20mm Standard @Elegoo Neptune4 (0.8 nozzle)" + "outer_wall_acceleration": "5000" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Max 0.8 nozzle.json index c3fd42ae08..3c398e5473 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Max 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.40mm Standard @Elegoo N4Max 0.8 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.8 nozzle)", "inherits": "fdm_process_elegoo_08040", "from": "system", "setting_id": "tgLcMBDWsMF48oRZ", @@ -11,6 +12,5 @@ ], "default_acceleration": "3000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "1500", - "renamed_from": "0.20mm Standard @Elegoo Neptune4Max (0.8 nozzle)" + "outer_wall_acceleration": "1500" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Plus 0.8 nozzle.json index 768d30d0a1..45b9a3bb84 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Plus 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.40mm Standard @Elegoo N4Plus 0.8 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.8 nozzle)", "inherits": "fdm_process_elegoo_08040", "from": "system", "setting_id": "9o2i5h6e4I7l7QOg", @@ -11,6 +12,5 @@ ], "default_acceleration": "5000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "2500", - "renamed_from": "0.20mm Standard @Elegoo Neptune4 Plus (0.8 nozzle)" + "outer_wall_acceleration": "2500" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Pro 0.8 nozzle.json index 5cd78291fc..c9c2761c65 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.40mm Standard @Elegoo N4Pro 0.8 nozzle.json @@ -1,6 +1,7 @@ { "type": "process", "name": "0.40mm Standard @Elegoo N4Pro 0.8 nozzle", + "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.8 nozzle)", "inherits": "fdm_process_elegoo_08040", "from": "system", "setting_id": "xFnwaHCJymLM4Bgb", @@ -11,6 +12,5 @@ ], "default_acceleration": "6000", "min_width_top_surface": "50%", - "outer_wall_acceleration": "5000", - "renamed_from": "0.20mm Standard @Elegoo Neptune4Pro (0.8 nozzle)" + "outer_wall_acceleration": "5000" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4 0.6 nozzle.json index 1c43c12f8b..2461ad12a5 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N4 0.6 nozzle", - "from": "system", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4 0.6 nozzle", + "from": "system", "setting_id": "XlLhnDcy7S6BcaFE", "instantiation": "true", - "layer_height": "0.42", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 (0.6 nozzle)" + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Max 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Max 0.6 nozzle.json index f6d276ebb6..c5c1cfbbe2 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Max 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Max 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N4Max 0.6 nozzle", - "from": "system", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Max (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Max 0.6 nozzle", + "from": "system", "setting_id": "oPxKL0bgR2gX0Ijh", "instantiation": "true", - "layer_height": "0.42", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Max (0.6 nozzle)" + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Plus 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Plus 0.6 nozzle.json index 7def2341c6..0a90e61896 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Plus 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Plus 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N4Plus 0.6 nozzle", - "from": "system", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 Plus (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Plus 0.6 nozzle", + "from": "system", "setting_id": "qY9HPvv16AZMQj4O", "instantiation": "true", - "layer_height": "0.42", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4 Plus (0.6 nozzle)" + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Pro 0.6 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Pro 0.6 nozzle.json index d060f49384..bff2a4b016 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Pro 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.42mm Extra Draft @Elegoo N4Pro 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.42mm Extra Draft @Elegoo N4Pro 0.6 nozzle", - "from": "system", + "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Pro (0.6 nozzle)", "inherits": "0.30mm Standard @Elegoo N4Pro 0.6 nozzle", + "from": "system", "setting_id": "o1GuCAN5AF2cjFRZ", "instantiation": "true", - "layer_height": "0.42", - "renamed_from": "0.28mm Extra Draft @Elegoo Neptune4Pro (0.6 nozzle)" + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4 0.8 nozzle.json index 41feffa308..8e9e970cb2 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N4 0.8 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4 (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4 0.8 nozzle", + "from": "system", "setting_id": "SBUBC3tTWEsoUDwB", "instantiation": "true", - "layer_height": "0.48", - "renamed_from": "0.24mm Draft @Elegoo Neptune4 (0.8 nozzle)" + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Max 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Max 0.8 nozzle.json index e0a4de6b6a..05c2713f77 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Max 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Max 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N4Max 0.8 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4Max (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Max 0.8 nozzle", + "from": "system", "setting_id": "O8HQgyqJNT6oHFL1", "instantiation": "true", - "layer_height": "0.48", - "renamed_from": "0.24mm Draft @Elegoo Neptune4Max (0.8 nozzle)" + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Plus 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Plus 0.8 nozzle.json index f6f5655f0d..dcd7156e56 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Plus 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Plus 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N4Plus 0.8 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4 Plus (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Plus 0.8 nozzle", + "from": "system", "setting_id": "DSXwIJeZIaTQNJdD", "instantiation": "true", - "layer_height": "0.48", - "renamed_from": "0.24mm Draft @Elegoo Neptune4 Plus (0.8 nozzle)" + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Pro 0.8 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Pro 0.8 nozzle.json index 796fc78212..fcc66b3900 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Pro 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.48mm Draft @Elegoo N4Pro 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", "name": "0.48mm Draft @Elegoo N4Pro 0.8 nozzle", - "from": "system", + "renamed_from": "0.24mm Draft @Elegoo Neptune4Pro (0.8 nozzle)", "inherits": "0.40mm Standard @Elegoo N4Pro 0.8 nozzle", + "from": "system", "setting_id": "GYMUhWOFDMRwYdxY", "instantiation": "true", - "layer_height": "0.48", - "renamed_from": "0.24mm Draft @Elegoo Neptune4Pro (0.8 nozzle)" + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4 1.0 nozzle.json index 6da75b45b4..83291412e3 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N4 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4 1.0 nozzle", + "from": "system", "setting_id": "Y8DwHQxs3j9DEU2v", "instantiation": "true", "layer_height": "0.6" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Max 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Max 1.0 nozzle.json index c713999503..cbf3c2e5c3 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Max 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Max 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N4Max 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Max 1.0 nozzle", + "from": "system", "setting_id": "QoV7xebXnXFxPc1G", "instantiation": "true", "layer_height": "0.6" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Plus 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Plus 1.0 nozzle.json index 78e01e0765..e296202055 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Plus 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Plus 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N4Plus 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Plus 1.0 nozzle", + "from": "system", "setting_id": "f5rYjm5HnjXGeRv9", "instantiation": "true", "layer_height": "0.6" diff --git a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Pro 1.0 nozzle.json b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Pro 1.0 nozzle.json index e935f52c72..2de38474da 100644 --- a/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Pro 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EN4SERIES/0.60mm Draft @Elegoo N4Pro 1.0 nozzle.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.60mm Draft @Elegoo N4Pro 1.0 nozzle", - "from": "system", "inherits": "0.50mm Standard @Elegoo N4Pro 1.0 nozzle", + "from": "system", "setting_id": "pjsuqOu6iU4ZDjfL", "instantiation": "true", "layer_height": "0.6" diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.16mm Optimal @Elegoo Giga 0.4 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.16mm Optimal @Elegoo Giga 0.4 nozzle.json index 965365edd6..b4adafc224 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.16mm Optimal @Elegoo Giga 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.16mm Optimal @Elegoo Giga 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.16mm Optimal @Elegoo Giga 0.4 nozzle", + "renamed_from": "0.16mm Optimal @EOS Giga 0.4 nozzle", "inherits": "0.20mm Standard @Elegoo Giga 0.4 nozzle", - "layer_height": "0.16", + "from": "system", "setting_id": "XLb4AmNTfuDRMWQl", "instantiation": "true", - "renamed_from": "0.16mm Optimal @EOS Giga 0.4 nozzle", - "name": "0.16mm Optimal @Elegoo Giga 0.4 nozzle" + "layer_height": "0.16" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.18mm Fine @Elegoo Giga 0.6 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.18mm Fine @Elegoo Giga 0.6 nozzle.json index f82182d302..76e69eb5a9 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.18mm Fine @Elegoo Giga 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.18mm Fine @Elegoo Giga 0.6 nozzle.json @@ -1,12 +1,12 @@ { "type": "process", - "from": "system", + "name": "0.18mm Fine @Elegoo Giga 0.6 nozzle", + "renamed_from": "0.18mm Fine @EOS Giga 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Giga 0.6 nozzle", - "layer_height": "0.18", + "from": "system", "setting_id": "xxVHp48sijSkmOCr", "instantiation": "true", - "renamed_from": "0.18mm Fine @EOS Giga 0.6 nozzle", - "name": "0.18mm Fine @Elegoo Giga 0.6 nozzle", + "layer_height": "0.18", "compatible_printers": [ "Elegoo OrangeStorm Giga 0.6 nozzle" ] diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Standard @Elegoo Giga 0.4 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Standard @Elegoo Giga 0.4 nozzle.json index 1dc016e684..bca4437c89 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Standard @Elegoo Giga 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Standard @Elegoo Giga 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", "name": "0.20mm Standard @Elegoo Giga 0.4 nozzle", + "renamed_from": "0.20mm Standard @EOS Giga 0.4 nozzle", "inherits": "fdm_process_elegoo_04020", "from": "system", "setting_id": "GIglVjgVd5bAy2nW", "instantiation": "true", - "renamed_from": "0.20mm Standard @EOS Giga 0.4 nozzle", "default_acceleration": "3000", "filename_format": "EOGiga1_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Strength @Elegoo Giga 0.4 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Strength @Elegoo Giga 0.4 nozzle.json index 432e7b60d2..dc25639b17 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Strength @Elegoo Giga 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.20mm Strength @Elegoo Giga 0.4 nozzle.json @@ -1,12 +1,12 @@ { "type": "process", - "from": "system", - "inherits": "0.20mm Standard @Elegoo Giga 0.4 nozzle", "name": "0.20mm Strength @Elegoo Giga 0.4 nozzle", - "wall_sequence": "inner-outer-inner wall", - "reduce_crossing_wall": "1", + "renamed_from": "0.20mm Strength @EOS Giga 0.4 nozzle", + "inherits": "0.20mm Standard @Elegoo Giga 0.4 nozzle", + "from": "system", "setting_id": "JsDp89yLYQpZ8a9z", "instantiation": "true", - "renamed_from": "0.20mm Strength @EOS Giga 0.4 nozzle", + "wall_sequence": "inner-outer-inner wall", + "reduce_crossing_wall": "1", "wall_loops": "6" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Draft @Elegoo Giga 0.4 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Draft @Elegoo Giga 0.4 nozzle.json index c7df41ccde..5b76b8e465 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Draft @Elegoo Giga 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Draft @Elegoo Giga 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.24mm Draft @Elegoo Giga 0.4 nozzle", + "renamed_from": "0.24mm Draft @EOS Giga 0.4 nozzle", "inherits": "0.20mm Standard @Elegoo Giga 0.4 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "V1FtH3wGlPhP8SlR", "instantiation": "true", - "renamed_from": "0.24mm Draft @EOS Giga 0.4 nozzle", - "name": "0.24mm Draft @Elegoo Giga 0.4 nozzle" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Fine @Elegoo Giga 0.8 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Fine @Elegoo Giga 0.8 nozzle.json index 3c61774ab9..e1f16f497c 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Fine @Elegoo Giga 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Fine @Elegoo Giga 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.24mm Fine @Elegoo Giga 0.8 nozzle", + "renamed_from": "0.24mm Fine @EOS Giga 0.8 nozzle", "inherits": "0.40mm Standard @Elegoo Giga 0.8 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "v4n8azbYxr3XfTC1", "instantiation": "true", - "renamed_from": "0.24mm Fine @EOS Giga 0.8 nozzle", - "name": "0.24mm Fine @Elegoo Giga 0.8 nozzle" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Optimal @Elegoo Giga 0.6 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Optimal @Elegoo Giga 0.6 nozzle.json index 5c9783aca0..72b80ea0ab 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Optimal @Elegoo Giga 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.24mm Optimal @Elegoo Giga 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.24mm Optimal @Elegoo Giga 0.6 nozzle", + "renamed_from": "0.24mm Optimal @EOS Giga 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Giga 0.6 nozzle", - "layer_height": "0.24", + "from": "system", "setting_id": "ZvTBY1VByXi0woy8", "instantiation": "true", - "renamed_from": "0.24mm Optimal @EOS Giga 0.6 nozzle", - "name": "0.24mm Optimal @Elegoo Giga 0.6 nozzle" + "layer_height": "0.24" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.28mm Extra Draft @Elegoo Giga 0.4 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.28mm Extra Draft @Elegoo Giga 0.4 nozzle.json index cfb1f6173b..afecee96d4 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.28mm Extra Draft @Elegoo Giga 0.4 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.28mm Extra Draft @Elegoo Giga 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.28mm Extra Draft @Elegoo Giga 0.4 nozzle", + "renamed_from": "0.28mm Extra Draft @EOS Giga 0.4 nozzle", "inherits": "0.20mm Standard @Elegoo Giga 0.4 nozzle", - "layer_height": "0.28", + "from": "system", "setting_id": "fJFavkWAsAtwN4W2", "instantiation": "true", - "renamed_from": "0.28mm Extra Draft @EOS Giga 0.4 nozzle", - "name": "0.28mm Extra Draft @Elegoo Giga 0.4 nozzle" + "layer_height": "0.28" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Fine @Elegoo Giga 1.0 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Fine @Elegoo Giga 1.0 nozzle.json index 0d57c5f756..cf0bb205e7 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Fine @Elegoo Giga 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Fine @Elegoo Giga 1.0 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.30mm Fine @Elegoo Giga 1.0 nozzle", + "renamed_from": "0.30mm Fine @EOS Giga 1.0 nozzle", "inherits": "0.50mm Standard @Elegoo Giga 1.0 nozzle", - "layer_height": "0.3", + "from": "system", "setting_id": "fmE4BaIielLYEpAm", "instantiation": "true", - "renamed_from": "0.30mm Fine @EOS Giga 1.0 nozzle", - "name": "0.30mm Fine @Elegoo Giga 1.0 nozzle" + "layer_height": "0.3" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Strength @Elegoo Giga 0.6 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Strength @Elegoo Giga 0.6 nozzle.json index ce791916ca..46edb7aefa 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Strength @Elegoo Giga 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.30mm Strength @Elegoo Giga 0.6 nozzle.json @@ -1,12 +1,12 @@ { "type": "process", - "from": "system", - "inherits": "0.30mm Standard @Elegoo Giga 0.6 nozzle", "name": "0.30mm Strength @Elegoo Giga 0.6 nozzle", - "wall_sequence": "inner-outer-inner wall", - "reduce_crossing_wall": "1", + "renamed_from": "0.30mm Strength @EOS Giga 0.6 nozzle", + "inherits": "0.30mm Standard @Elegoo Giga 0.6 nozzle", + "from": "system", "setting_id": "Vwty88kyYO8bPt9l", "instantiation": "true", - "renamed_from": "0.30mm Strength @EOS Giga 0.6 nozzle", + "wall_sequence": "inner-outer-inner wall", + "reduce_crossing_wall": "1", "wall_loops": "5" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.32mm Optimal @Elegoo Giga 0.8 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.32mm Optimal @Elegoo Giga 0.8 nozzle.json index c859de87a7..be8908ca94 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.32mm Optimal @Elegoo Giga 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.32mm Optimal @Elegoo Giga 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.32mm Optimal @Elegoo Giga 0.8 nozzle", + "renamed_from": "0.32mm Optimal @EOS Giga 0.8 nozzle", "inherits": "0.40mm Standard @Elegoo Giga 0.8 nozzle", - "layer_height": "0.32", + "from": "system", "setting_id": "U6XpRv8LUHeLMpO6", "instantiation": "true", - "renamed_from": "0.32mm Optimal @EOS Giga 0.8 nozzle", - "name": "0.32mm Optimal @Elegoo Giga 0.8 nozzle" + "layer_height": "0.32" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.36mm Draft @Elegoo Giga 0.6 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.36mm Draft @Elegoo Giga 0.6 nozzle.json index fa032fc410..f8f348841e 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.36mm Draft @Elegoo Giga 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.36mm Draft @Elegoo Giga 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.36mm Draft @Elegoo Giga 0.6 nozzle", + "renamed_from": "0.36mm Draft @EOS Giga 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Giga 0.6 nozzle", - "layer_height": "0.36", + "from": "system", "setting_id": "aFZ4bLGGhFIcwoH5", "instantiation": "true", - "renamed_from": "0.36mm Draft @EOS Giga 0.6 nozzle", - "name": "0.36mm Draft @Elegoo Giga 0.6 nozzle" + "layer_height": "0.36" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Optimal @Elegoo Giga 1.0 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Optimal @Elegoo Giga 1.0 nozzle.json index aa8af94e85..48ffeb9d06 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Optimal @Elegoo Giga 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Optimal @Elegoo Giga 1.0 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.40mm Optimal @Elegoo Giga 1.0 nozzle", + "renamed_from": "0.40mm Optimal @EOS Giga 1.0 nozzle", "inherits": "0.50mm Standard @Elegoo Giga 1.0 nozzle", - "layer_height": "0.4", + "from": "system", "setting_id": "fGSfqfyNqMhuqZ8X", "instantiation": "true", - "renamed_from": "0.40mm Optimal @EOS Giga 1.0 nozzle", - "name": "0.40mm Optimal @Elegoo Giga 1.0 nozzle" + "layer_height": "0.4" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Standard @Elegoo Giga 0.8 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Standard @Elegoo Giga 0.8 nozzle.json index 8b73f6b7d1..10e4611bc4 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Standard @Elegoo Giga 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.40mm Standard @Elegoo Giga 0.8 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", "name": "0.40mm Standard @Elegoo Giga 0.8 nozzle", + "renamed_from": "0.40mm Standard @EOS Giga 0.8 nozzle", "inherits": "fdm_process_elegoo_08040", "from": "system", "setting_id": "oiMWJMGC2aW2v4wg", "instantiation": "true", - "renamed_from": "0.40mm Standard @EOS Giga 0.8 nozzle", "default_acceleration": "3000", "filename_format": "EOGiga1_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "initial_layer_acceleration": "1000", diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.42mm Extra Draft @Elegoo Giga 0.6 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.42mm Extra Draft @Elegoo Giga 0.6 nozzle.json index 803606068b..11004b57f4 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.42mm Extra Draft @Elegoo Giga 0.6 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.42mm Extra Draft @Elegoo Giga 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.42mm Extra Draft @Elegoo Giga 0.6 nozzle", + "renamed_from": "0.42mm Extra Draft @EOS Giga 0.6 nozzle", "inherits": "0.30mm Standard @Elegoo Giga 0.6 nozzle", - "layer_height": "0.42", + "from": "system", "setting_id": "dlzWR8ZIwaJ1tYId", "instantiation": "true", - "renamed_from": "0.42mm Extra Draft @EOS Giga 0.6 nozzle", - "name": "0.42mm Extra Draft @Elegoo Giga 0.6 nozzle" + "layer_height": "0.42" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.48mm Draft @Elegoo Giga 0.8 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.48mm Draft @Elegoo Giga 0.8 nozzle.json index 3c660f5b8e..33163a00f1 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.48mm Draft @Elegoo Giga 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.48mm Draft @Elegoo Giga 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.48mm Draft @Elegoo Giga 0.8 nozzle", + "renamed_from": "0.48mm Draft @EOS Giga 0.8 nozzle", "inherits": "0.40mm Standard @Elegoo Giga 0.8 nozzle", - "layer_height": "0.48", + "from": "system", "setting_id": "lqJRn5QLgMp5i2dr", "instantiation": "true", - "renamed_from": "0.48mm Draft @EOS Giga 0.8 nozzle", - "name": "0.48mm Draft @Elegoo Giga 0.8 nozzle" + "layer_height": "0.48" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.50mm Standard @Elegoo Giga 1.0 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.50mm Standard @Elegoo Giga 1.0 nozzle.json index f2ad7bb95a..0252414921 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.50mm Standard @Elegoo Giga 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.50mm Standard @Elegoo Giga 1.0 nozzle.json @@ -1,11 +1,11 @@ { "type": "process", - "inherits": "fdm_process_elegoo_10050", "name": "0.50mm Standard @Elegoo Giga 1.0 nozzle", + "renamed_from": "0.50mm Standard @EOS Giga 1.0 nozzle", + "inherits": "fdm_process_elegoo_10050", "from": "system", "setting_id": "hLPWpsFCvKgbrebl", "instantiation": "true", - "renamed_from": "0.50mm Standard @EOS Giga 1.0 nozzle", "default_acceleration": "3000", "filename_format": "EOGiga1_{nozzle_diameter[0]}_{input_filename_base}_{filament_name}_{layer_height}_{print_time}.gcode", "initial_layer_acceleration": "1000", diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.56mm Extra Draft @Elegoo Giga 0.8 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.56mm Extra Draft @Elegoo Giga 0.8 nozzle.json index 8104d7423a..9a1b450a86 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.56mm Extra Draft @Elegoo Giga 0.8 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.56mm Extra Draft @Elegoo Giga 0.8 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "from": "system", - "inherits": "0.40mm Standard @Elegoo Giga 0.8 nozzle", - "setting_id": "EC6Dqk8dUIai51E5", - "instantiation": "true", + "name": "0.56mm Extra Draft @Elegoo Giga 0.8 nozzle", "renamed_from": "0.56mm Extra Draft @EOS Giga 0.8 nozzle", - "name": "0.56mm Extra Draft @Elegoo Giga 0.8 nozzle" + "inherits": "0.40mm Standard @Elegoo Giga 0.8 nozzle", + "from": "system", + "setting_id": "EC6Dqk8dUIai51E5", + "instantiation": "true" } diff --git a/resources/profiles/Elegoo/process/EOSGIGA/0.60mm Draft @Elegoo Giga 1.0 nozzle.json b/resources/profiles/Elegoo/process/EOSGIGA/0.60mm Draft @Elegoo Giga 1.0 nozzle.json index d53af64b0e..664dbdddea 100644 --- a/resources/profiles/Elegoo/process/EOSGIGA/0.60mm Draft @Elegoo Giga 1.0 nozzle.json +++ b/resources/profiles/Elegoo/process/EOSGIGA/0.60mm Draft @Elegoo Giga 1.0 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "from": "system", + "name": "0.60mm Draft @Elegoo Giga 1.0 nozzle", + "renamed_from": "0.60mm Draft @EOS Giga 1.0 nozzle", "inherits": "0.50mm Standard @Elegoo Giga 1.0 nozzle", - "layer_height": "0.6", + "from": "system", "setting_id": "VsOntugsCeEPNBvC", "instantiation": "true", - "renamed_from": "0.60mm Draft @EOS Giga 1.0 nozzle", - "name": "0.60mm Draft @Elegoo Giga 1.0 nozzle" + "layer_height": "0.6" } diff --git a/resources/profiles/Eryone.json b/resources/profiles/Eryone.json index ea9ce20a44..3a222c5404 100644 --- a/resources/profiles/Eryone.json +++ b/resources/profiles/Eryone.json @@ -1,6 +1,6 @@ { "name": "Eryone", - "version": "02.04.00.06", + "version": "02.04.00.07", "force_update": "0", "description": "Eryone configurations", "machine_model_list": [ diff --git a/resources/profiles/Eryone/filament/Eryone ABS @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone ABS @0.2 nozzle.json index 11bd3c3c67..c178314b73 100644 --- a/resources/profiles/Eryone/filament/Eryone ABS @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone ABS @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone ABS @0.2 nozzle", + "inherits": "Eryone ABS", "from": "system", "setting_id": "sNet9szMIhVY4WoS", "instantiation": "true", - "inherits": "Eryone ABS", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone ABS-CF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone ABS-CF @0.2 nozzle.json index 0d862c72f6..c64db14844 100644 --- a/resources/profiles/Eryone/filament/Eryone ABS-CF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone ABS-CF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone ABS-CF @0.2 nozzle", + "inherits": "Eryone ABS-CF", "from": "system", "setting_id": "a7qk6VtkbJziQHZo", "instantiation": "true", - "inherits": "Eryone ABS-CF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone ASA @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone ASA @0.2 nozzle.json index fd8a747c60..090804de80 100644 --- a/resources/profiles/Eryone/filament/Eryone ASA @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone ASA @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone ASA @0.2 nozzle", + "inherits": "Eryone ASA", "from": "system", "setting_id": "SopkMvsT3DXzJ9Ky", "instantiation": "true", - "inherits": "Eryone ASA", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone ASA-CF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone ASA-CF @0.2 nozzle.json index 3e38a60b4f..a89631b5e0 100644 --- a/resources/profiles/Eryone/filament/Eryone ASA-CF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone ASA-CF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone ASA-CF @0.2 nozzle", + "inherits": "Eryone ASA-CF", "from": "system", "setting_id": "yBYSvDH0djt4S123", "instantiation": "true", - "inherits": "Eryone ASA-CF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PA @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PA @0.2 nozzle.json index f8ee131756..36af337c35 100644 --- a/resources/profiles/Eryone/filament/Eryone PA @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PA @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PA @0.2 nozzle", + "inherits": "Eryone PA", "from": "system", "setting_id": "zavqdFwS2fsajkps", "instantiation": "true", - "inherits": "Eryone PA", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PA-CF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PA-CF @0.2 nozzle.json index bb0b1ecba2..006ac2d6d7 100644 --- a/resources/profiles/Eryone/filament/Eryone PA-CF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PA-CF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PA-CF @0.2 nozzle", + "inherits": "Eryone PA-CF", "from": "system", "setting_id": "wbnmjqeccJS209GO", "instantiation": "true", - "inherits": "Eryone PA-CF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PA-GF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PA-GF @0.2 nozzle.json index 14c8620f6a..d161e2ca89 100644 --- a/resources/profiles/Eryone/filament/Eryone PA-GF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PA-GF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PA-GF @0.2 nozzle", + "inherits": "Eryone PA-GF", "from": "system", "setting_id": "J7Oy1mm1szLspwBb", "instantiation": "true", - "inherits": "Eryone PA-GF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PETG @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PETG @0.2 nozzle.json index e8ddc59440..d3e8c6b1e2 100644 --- a/resources/profiles/Eryone/filament/Eryone PETG @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PETG @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PETG @0.2 nozzle", + "inherits": "Eryone PETG", "from": "system", "setting_id": "cATziDM4CjP6MiC4", "instantiation": "true", - "inherits": "Eryone PETG", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PETG-CF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PETG-CF @0.2 nozzle.json index 3bb3f6f1df..84f3ac67a1 100644 --- a/resources/profiles/Eryone/filament/Eryone PETG-CF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PETG-CF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PETG-CF @0.2 nozzle", + "inherits": "Eryone PETG-CF", "from": "system", "setting_id": "wsR57UlUrO2aW2Lc", "instantiation": "true", - "inherits": "Eryone PETG-CF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PLA @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PLA @0.2 nozzle.json index 204bb5e32e..d28cd2146c 100644 --- a/resources/profiles/Eryone/filament/Eryone PLA @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PLA @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PLA @0.2 nozzle", + "inherits": "Eryone PLA", "from": "system", "setting_id": "kJhDYIHtXhAd4M6v", "instantiation": "true", - "inherits": "Eryone PLA", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PLA-CF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PLA-CF @0.2 nozzle.json index 9d43ea33e3..953392e263 100644 --- a/resources/profiles/Eryone/filament/Eryone PLA-CF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PLA-CF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PLA-CF @0.2 nozzle", + "inherits": "Eryone PLA-CF", "from": "system", "setting_id": "ghNuMkVp1164Fw1Z", "instantiation": "true", - "inherits": "Eryone PLA-CF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PP @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PP @0.2 nozzle.json index 47d0b9ec14..f6df74cfe5 100644 --- a/resources/profiles/Eryone/filament/Eryone PP @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PP @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PP @0.2 nozzle", + "inherits": "Eryone PP", "from": "system", "setting_id": "ePXvfc5tmC3GnZPe", "instantiation": "true", - "inherits": "Eryone PP", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone PP-CF @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone PP-CF @0.2 nozzle.json index 986696084e..2b8dab8617 100644 --- a/resources/profiles/Eryone/filament/Eryone PP-CF @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone PP-CF @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone PP-CF @0.2 nozzle", + "inherits": "Eryone PP-CF", "from": "system", "setting_id": "os5ZrNT1utAczy2F", "instantiation": "true", - "inherits": "Eryone PP-CF", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone Silk PLA @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone Silk PLA @0.2 nozzle.json index 1a617e7f14..bfa247ca71 100644 --- a/resources/profiles/Eryone/filament/Eryone Silk PLA @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone Silk PLA @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone Silk PLA @0.2 nozzle", + "inherits": "Eryone Silk PLA", "from": "system", "setting_id": "RS6yfcZ6PbJzGrUc", "instantiation": "true", - "inherits": "Eryone Silk PLA", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/filament/Eryone TPU @0.2 nozzle.json b/resources/profiles/Eryone/filament/Eryone TPU @0.2 nozzle.json index 8596a81fb9..2116afac4b 100644 --- a/resources/profiles/Eryone/filament/Eryone TPU @0.2 nozzle.json +++ b/resources/profiles/Eryone/filament/Eryone TPU @0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "Eryone TPU @0.2 nozzle", + "inherits": "Eryone TPU", "from": "system", "setting_id": "6Le5wRz6cFfKcPaz", "instantiation": "true", - "inherits": "Eryone TPU", "compatible_printers": [ "Thinker X400 0.2 nozzle" ], diff --git a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.2 nozzle.json b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.2 nozzle.json index 452efb7dba..133e2bd1e1 100644 --- a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.2 nozzle.json +++ b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.2 nozzle.json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.10mm Standard @Eryone ER20 0.2 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 0.2 nozzle", "inherits": "fdm_machine_eryone_ER20_common", + "from": "system", "setting_id": "mN66BkXzUCaGGkZ5", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.10mm Standard @Eryone ER20 0.2 nozzle", "max_layer_height": [ "0.14" ], "min_layer_height": [ "0.04" ], - "name": "Eryone ER20 0.2 nozzle", "nozzle_diameter": [ "0.2" ], "printer_model": "Eryone ER20", - "printer_variant": "0.2", - "type": "machine" + "printer_variant": "0.2" } diff --git a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.4 nozzle.json b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.4 nozzle.json index c9dd07d94e..b77a7fa400 100644 --- a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.4 nozzle.json +++ b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.4 nozzle.json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.20mm Standard @Eryone ER20", - "from": "system", + "type": "machine", + "name": "Eryone ER20 0.4 nozzle", "inherits": "fdm_machine_eryone_ER20_common", + "from": "system", "setting_id": "7Hs87Tz3oMj8YGLU", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.20mm Standard @Eryone ER20", "max_layer_height": [ "0.32" ], "min_layer_height": [ "0.08" ], - "name": "Eryone ER20 0.4 nozzle", "nozzle_diameter": [ "0.4" ], "printer_model": "Eryone ER20", - "printer_variant": "0.4", - "type": "machine" + "printer_variant": "0.4" } diff --git a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.5 nozzle.json b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.5 nozzle.json index 6565c58aa8..5ee3558c4d 100644 --- a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.5 nozzle.json +++ b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.5 nozzle.json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.25mm Standard @Eryone ER20 0.5 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 0.5 nozzle", "inherits": "fdm_machine_eryone_ER20_common", + "from": "system", "setting_id": "8AfjLDQQXEAnxuQ7", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.25mm Standard @Eryone ER20 0.5 nozzle", "max_layer_height": [ "0.38" ], "min_layer_height": [ "0.10" ], - "name": "Eryone ER20 0.5 nozzle", "nozzle_diameter": [ "0.5" ], "printer_model": "Eryone ER20", - "printer_variant": "0.5", - "type": "machine" + "printer_variant": "0.5" } diff --git a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.6 nozzle.json index f090d44b6b..7940d962ea 100644 --- a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.6 nozzle.json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.30mm Standard @Eryone ER20 0.6 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 0.6 nozzle", "inherits": "fdm_machine_eryone_ER20_common", + "from": "system", "setting_id": "8USSZMCTCDoHK55n", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.30mm Standard @Eryone ER20 0.6 nozzle", "max_layer_height": [ "0.42" ], "min_layer_height": [ "0.12" ], - "name": "Eryone ER20 0.6 nozzle", "nozzle_diameter": [ "0.6" ], "printer_model": "Eryone ER20", - "printer_variant": "0.6", - "type": "machine" + "printer_variant": "0.6" } diff --git a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.8 nozzle.json b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.8 nozzle.json index d64321fabf..1e2ef0d4e4 100644 --- a/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.8 nozzle.json +++ b/resources/profiles/Eryone/machine/ER20/Eryone ER20 0.8 nozzle.json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.40mm Standard @Eryone ER20 0.8 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 0.8 nozzle", "inherits": "fdm_machine_eryone_ER20_common", + "from": "system", "setting_id": "JWFQL6GvDRJk46i7", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.40mm Standard @Eryone ER20 0.8 nozzle", "max_layer_height": [ "0.56" ], "min_layer_height": [ "0.16" ], - "name": "Eryone ER20 0.8 nozzle", "nozzle_diameter": [ "0.8" ], "printer_model": "Eryone ER20", - "printer_variant": "0.8", - "type": "machine" + "printer_variant": "0.8" } diff --git a/resources/profiles/Eryone/machine/ER20/Eryone ER20.json b/resources/profiles/Eryone/machine/ER20/Eryone ER20.json index c555d904dc..f6c3f95c7e 100644 --- a/resources/profiles/Eryone/machine/ER20/Eryone ER20.json +++ b/resources/profiles/Eryone/machine/ER20/Eryone ER20.json @@ -1,4 +1,6 @@ { + "type": "machine_model", + "name": "Eryone ER20", "bed_model": "eryone_er20_buildplate_model.stl", "bed_texture": "Eryone ER20_texture.svg", "family": "Eryone", @@ -6,7 +8,5 @@ "machine_tech": "FFF", "model_id": "Eryone ER20", "default_materials": "Generic PLA @System", - "name": "Eryone ER20", - "nozzle_diameter": "0.4;0.2;0.5;0.6;0.8", - "type": "machine_model" + "nozzle_diameter": "0.4;0.2;0.5;0.6;0.8" } diff --git a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.2 nozzle .json b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.2 nozzle .json index fe19a23635..901e256a50 100644 --- a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.2 nozzle .json +++ b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.2 nozzle .json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.10mm Standard @Eryone ER20 Klipper 0.2 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 Klipper 0.2 nozzle", "inherits": "fdm_machine_eryone_ER20_Klipper_common", + "from": "system", "setting_id": "dUHn8STOXHOXD63f", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.10mm Standard @Eryone ER20 Klipper 0.2 nozzle", "max_layer_height": [ "0.14" ], "min_layer_height": [ "0.04" ], - "name": "Eryone ER20 Klipper 0.2 nozzle", "nozzle_diameter": [ "0.2" ], "printer_model": "Eryone ER20 Klipper", - "printer_variant": "0.2", - "type": "machine" + "printer_variant": "0.2" } diff --git a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.4 nozzle .json b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.4 nozzle .json index 5a95f35977..d206af00a6 100644 --- a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.4 nozzle .json +++ b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.4 nozzle .json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.20mm Standard @Eryone ER20 Klipper", - "from": "system", + "type": "machine", + "name": "Eryone ER20 Klipper 0.4 nozzle", "inherits": "fdm_machine_eryone_ER20_Klipper_common", + "from": "system", "setting_id": "xp3wEd41u0J6bR65", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.20mm Standard @Eryone ER20 Klipper", "max_layer_height": [ "0.32" ], "min_layer_height": [ "0.08" ], - "name": "Eryone ER20 Klipper 0.4 nozzle", "nozzle_diameter": [ "0.4" ], "printer_model": "Eryone ER20 Klipper", - "printer_variant": "0.4", - "type": "machine" + "printer_variant": "0.4" } diff --git a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.5 nozzle .json b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.5 nozzle .json index 1f97d64742..24b4bdcbbb 100644 --- a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.5 nozzle .json +++ b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.5 nozzle .json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 Klipper 0.5 nozzle", "inherits": "fdm_machine_eryone_ER20_Klipper_common", + "from": "system", "setting_id": "5zuzTKyILhVSA5J5", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle", "max_layer_height": [ "0.38" ], "min_layer_height": [ "0.10" ], - "name": "Eryone ER20 Klipper 0.5 nozzle", "nozzle_diameter": [ "0.5" ], "printer_model": "Eryone ER20 Klipper", - "printer_variant": "0.5", - "type": "machine" + "printer_variant": "0.5" } diff --git a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.6 nozzle .json b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.6 nozzle .json index b9f675ea43..09abdb4adf 100644 --- a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.6 nozzle .json +++ b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.6 nozzle .json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 Klipper 0.6 nozzle", "inherits": "fdm_machine_eryone_ER20_Klipper_common", + "from": "system", "setting_id": "LCVtRqmtH6YySurQ", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle", "max_layer_height": [ "0.42" ], "min_layer_height": [ "0.12" ], - "name": "Eryone ER20 Klipper 0.6 nozzle", "nozzle_diameter": [ "0.6" ], "printer_model": "Eryone ER20 Klipper", - "printer_variant": "0.6", - "type": "machine" + "printer_variant": "0.6" } diff --git a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.8 nozzle .json b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.8 nozzle .json index 558a442e30..3f09c89052 100644 --- a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.8 nozzle .json +++ b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper 0.8 nozzle .json @@ -1,21 +1,21 @@ { - "default_filament_profile": [], - "default_print_profile": "0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle", - "from": "system", + "type": "machine", + "name": "Eryone ER20 Klipper 0.8 nozzle", "inherits": "fdm_machine_eryone_ER20_Klipper_common", + "from": "system", "setting_id": "eMvz9rZXfWxXvuva", "instantiation": "true", + "default_filament_profile": [], + "default_print_profile": "0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle", "max_layer_height": [ "0.56" ], "min_layer_height": [ "0.16" ], - "name": "Eryone ER20 Klipper 0.8 nozzle", "nozzle_diameter": [ "0.8" ], "printer_model": "Eryone ER20 Klipper", - "printer_variant": "0.8", - "type": "machine" + "printer_variant": "0.8" } diff --git a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper.json b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper.json index 11d48a7859..edf488dfc9 100644 --- a/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper.json +++ b/resources/profiles/Eryone/machine/ER20_Klipper/Eryone ER20 Klipper.json @@ -1,4 +1,6 @@ { + "type": "machine_model", + "name": "Eryone ER20 Klipper", "bed_model": "eryone_er20_buildplate_model.stl", "bed_texture": "Eryone ER20_texture.svg", "default_bed_type": "Textured PEI Plate", @@ -7,8 +9,6 @@ "machine_tech": "FFF", "model_id": "Eryone ER20 Klipper", "default_materials": "Generic PLA @System", - "name": "Eryone ER20 Klipper", "nozzle_diameter": "0.4;0.2;0.5;0.6;0.8", - "type": "machine_model", "desciption": "optimized Eryone ER20 Klipper configuration with E3D Hotend, BMG directdrive, printable height limited to 200 because of the directdrive and Z-Sync mod" } diff --git a/resources/profiles/Eryone/machine/Thinker X400 0.2 nozzle.json b/resources/profiles/Eryone/machine/Thinker X400 0.2 nozzle.json index da3983130a..da328b97ec 100644 --- a/resources/profiles/Eryone/machine/Thinker X400 0.2 nozzle.json +++ b/resources/profiles/Eryone/machine/Thinker X400 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "machine", - "from": "system", "name": "Thinker X400 0.2 nozzle", "inherits": "Thinker X400 0.4 nozzle", + "from": "system", "setting_id": "hMvy9QaXQyM7tGke", "instantiation": "true", "printer_model": "Thinker X400", diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.12mm Draft @Eryone ER20 0.2 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.12mm Draft @Eryone ER20 0.2 nozzle.json index f17dc797a8..d811c3cd92 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.12mm Draft @Eryone ER20 0.2 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.12mm Draft @Eryone ER20 0.2 nozzle.json @@ -1,13 +1,13 @@ { + "type": "process", + "name": "0.12mm Draft @Eryone ER20 0.2 nozzle", + "inherits": "fdm_process_ER20_0.12_nozzle_0.2", + "from": "system", + "setting_id": "X5RY5e2qDLLXRw73", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.2 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.12_nozzle_0.2", - "setting_id": "X5RY5e2qDLLXRw73", - "instantiation": "true", - "name": "0.12mm Draft @Eryone ER20 0.2 nozzle", - "sparse_infill_pattern": "gyroid", - "type": "process" + "sparse_infill_pattern": "gyroid" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.14mm Extra Draft @Eryone ER20 0.2 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.14mm Extra Draft @Eryone ER20 0.2 nozzle.json index 7cc56e1902..dda0835710 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.14mm Extra Draft @Eryone ER20 0.2 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.14mm Extra Draft @Eryone ER20 0.2 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.14mm Extra Draft @Eryone ER20 0.2 nozzle", + "inherits": "fdm_process_ER20_0.14_nozzle_0.2", + "from": "system", + "setting_id": "USrHobTi6gZB0qfs", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.2 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.14_nozzle_0.2", - "setting_id": "USrHobTi6gZB0qfs", - "instantiation": "true", - "name": "0.14mm Extra Draft @Eryone ER20 0.2 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.15mm Optimal @Eryone ER20 0.5 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.15mm Optimal @Eryone ER20 0.5 nozzle.json index c552b7ec31..b294de444d 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.15mm Optimal @Eryone ER20 0.5 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.15mm Optimal @Eryone ER20 0.5 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.15mm Optimal @Eryone ER20 0.5 nozzle", + "inherits": "fdm_process_ER20_0.15_nozzle_0.5", + "from": "system", + "setting_id": "oapNf4dk0MGlHc1t", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.5 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.15_nozzle_0.5", - "setting_id": "oapNf4dk0MGlHc1t", - "instantiation": "true", - "name": "0.15mm Optimal @Eryone ER20 0.5 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.18mm Fine @Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.18mm Fine @Eryone ER20 0.6 nozzle.json index c7078cfba4..919f30c69d 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.18mm Fine @Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.18mm Fine @Eryone ER20 0.6 nozzle.json @@ -1,11 +1,11 @@ { - "compatible_printers": [ - "Eryone ER20 0.6 nozzle" - ], - "from": "system", + "type": "process", + "name": "0.18mm Fine @Eryone ER20 0.6 nozzle", "inherits": "fdm_process_ER20_0.18_nozzle_0.6", + "from": "system", "setting_id": "XnzfgUygXaUCzqsa", "instantiation": "true", - "name": "0.18mm Fine @Eryone ER20 0.6 nozzle", - "type": "process" + "compatible_printers": [ + "Eryone ER20 0.6 nozzle" + ] } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.20mm Standard @Eryone ER20.json b/resources/profiles/Eryone/process/eryone_ER20/0.20mm Standard @Eryone ER20.json index 2e223dab0c..bd50b52efa 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.20mm Standard @Eryone ER20.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.20mm Standard @Eryone ER20.json @@ -1,13 +1,13 @@ { + "type": "process", + "name": "0.20mm Standard @Eryone ER20", + "inherits": "fdm_process_ER20_0.20", + "from": "system", + "setting_id": "TMsKM3bODapym77c", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.4 nozzle" ], - "from": "system", - "inherits": "fdm_process_ER20_0.20", - "setting_id": "TMsKM3bODapym77c", - "instantiation": "true", "layer_height": "0.20", - "name": "0.20mm Standard @Eryone ER20", - "notes": "", - "type": "process" + "notes": "" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.20mm Strength @Eryone ER20.json b/resources/profiles/Eryone/process/eryone_ER20/0.20mm Strength @Eryone ER20.json index 0ce68ee027..ff47769d19 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.20mm Strength @Eryone ER20.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.20mm Strength @Eryone ER20.json @@ -1,14 +1,14 @@ { + "type": "process", + "name": "0.20mm Strength @Eryone ER20", + "inherits": "fdm_process_ER20_0.20", + "from": "system", + "setting_id": "GFfpctaMRI4Nuqk9", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.4 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.20", - "setting_id": "GFfpctaMRI4Nuqk9", - "instantiation": "true", - "name": "0.20mm Strength @Eryone ER20", "sparse_infill_density": "25%", - "type": "process", "wall_loops": "6" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.24mm Draft @Eryone ER20.json b/resources/profiles/Eryone/process/eryone_ER20/0.24mm Draft @Eryone ER20.json index 339736d0b1..bb25e98ead 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.24mm Draft @Eryone ER20.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.24mm Draft @Eryone ER20.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.24mm Draft @Eryone ER20", + "inherits": "fdm_process_ER20_0.24", + "from": "system", + "setting_id": "8rfQRPMh82vmdDeb", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.4 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.24", - "setting_id": "8rfQRPMh82vmdDeb", - "instantiation": "true", - "name": "0.24mm Draft @Eryone ER20", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.24mm Fine @Eryone ER20 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.24mm Fine @Eryone ER20 0.8 nozzle.json index 44d7d8e926..e82e27216d 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.24mm Fine @Eryone ER20 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.24mm Fine @Eryone ER20 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.24mm Fine @Eryone ER20 0.8 nozzle", + "inherits": "fdm_process_ER20_0.24_nozzle_0.8", + "from": "system", + "setting_id": "0Ham5AnvDEnEzaSY", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.24_nozzle_0.8", - "setting_id": "0Ham5AnvDEnEzaSY", - "instantiation": "true", - "name": "0.24mm Fine @Eryone ER20 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.24mm Optimal @Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.24mm Optimal @Eryone ER20 0.6 nozzle.json index 7fea46be58..fcf464d07a 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.24mm Optimal @Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.24mm Optimal @Eryone ER20 0.6 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.24mm Optimal @Eryone ER20 0.6 nozzle", + "inherits": "fdm_process_ER20_0.24_nozzle_0.6", + "from": "system", + "setting_id": "0CRLvmSKxkmglWRi", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.6 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.24_nozzle_0.6", - "setting_id": "0CRLvmSKxkmglWRi", - "instantiation": "true", - "name": "0.24mm Optimal @Eryone ER20 0.6 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.25mm Standard @Eryone ER20 0.5 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.25mm Standard @Eryone ER20 0.5 nozzle.json index e1a26f1715..8dbe018f32 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.25mm Standard @Eryone ER20 0.5 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.25mm Standard @Eryone ER20 0.5 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.25mm Standard @Eryone ER20 0.5 nozzle", + "inherits": "fdm_process_ER20_0.25_nozzle_0.5", + "from": "system", + "setting_id": "oEjMrkTjRF6zL46C", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.5 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.25_nozzle_0.5", - "setting_id": "oEjMrkTjRF6zL46C", - "instantiation": "true", - "name": "0.25mm Standard @Eryone ER20 0.5 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.28mm Extra Draft @Eryone ER20.json b/resources/profiles/Eryone/process/eryone_ER20/0.28mm Extra Draft @Eryone ER20.json index 8a63db28a4..0afdb08dbb 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.28mm Extra Draft @Eryone ER20.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.28mm Extra Draft @Eryone ER20.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.28mm Extra Draft @Eryone ER20", + "inherits": "fdm_process_ER20_0.28", + "from": "system", + "setting_id": "oyoecLMFQzjbIfcd", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.4 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.28", - "setting_id": "oyoecLMFQzjbIfcd", - "instantiation": "true", - "name": "0.28mm Extra Draft @Eryone ER20", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.30mm Standard @Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.30mm Standard @Eryone ER20 0.6 nozzle.json index f928604605..67288717e1 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.30mm Standard @Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.30mm Standard @Eryone ER20 0.6 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.30mm Standard @Eryone ER20 0.6 nozzle", + "inherits": "fdm_process_ER20_0.30_nozzle_0.6", + "from": "system", + "setting_id": "jw5QUhazCifzzM6Q", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.6 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.30_nozzle_0.6", - "setting_id": "jw5QUhazCifzzM6Q", - "instantiation": "true", - "name": "0.30mm Standard @Eryone ER20 0.6 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.30mm Strength @Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.30mm Strength @Eryone ER20 0.6 nozzle.json index 42a56dafef..0467be8ba4 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.30mm Strength @Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.30mm Strength @Eryone ER20 0.6 nozzle.json @@ -1,14 +1,14 @@ { + "type": "process", + "name": "0.30mm Strength @Eryone ER20 0.6 nozzle", + "inherits": "fdm_process_ER20_0.30_nozzle_0.6", + "from": "system", + "setting_id": "LqOFomJiS10Vbrdp", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.6 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.30_nozzle_0.6", - "setting_id": "LqOFomJiS10Vbrdp", - "instantiation": "true", - "name": "0.30mm Strength @Eryone ER20 0.6 nozzle", "sparse_infill_density": "25%", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.32mm Optimal @Eryone ER20 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.32mm Optimal @Eryone ER20 0.8 nozzle.json index 8c1ff89a9c..5171631cfa 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.32mm Optimal @Eryone ER20 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.32mm Optimal @Eryone ER20 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.32mm Optimal @Eryone ER20 0.8 nozzle", + "inherits": "fdm_process_ER20_0.32_nozzle_0.8", + "from": "system", + "setting_id": "5lYVYrlEfVVl2n0F", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.32_nozzle_0.8", - "setting_id": "5lYVYrlEfVVl2n0F", - "instantiation": "true", - "name": "0.32mm Optimal @Eryone ER20 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.36mm Draft @Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.36mm Draft @Eryone ER20 0.6 nozzle.json index e673f0b293..da668817ab 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.36mm Draft @Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.36mm Draft @Eryone ER20 0.6 nozzle.json @@ -1,13 +1,13 @@ { + "type": "process", + "name": "0.36mm Draft @Eryone ER20 0.6 nozzle", + "inherits": "fdm_process_ER20_0.36_nozzle_0.6", + "from": "system", + "setting_id": "vavNueSF5zRpUlTZ", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.6 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.36_nozzle_0.6", - "setting_id": "vavNueSF5zRpUlTZ", - "instantiation": "true", - "name": "0.36mm Draft @Eryone ER20 0.6 nozzle", - "travel_speed": "250", - "type": "process" + "travel_speed": "250" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.40mm Standard @Eryone ER20 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.40mm Standard @Eryone ER20 0.8 nozzle.json index 053d009d36..6ee5f62a08 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.40mm Standard @Eryone ER20 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.40mm Standard @Eryone ER20 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.40mm Standard @Eryone ER20 0.8 nozzle", + "inherits": "fdm_process_ER20_0.40_nozzle_0.8", + "from": "system", + "setting_id": "TlCbtZYdCRCkpIf6", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.40_nozzle_0.8", - "setting_id": "TlCbtZYdCRCkpIf6", - "instantiation": "true", - "name": "0.40mm Standard @Eryone ER20 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.42mm Extra Draft @Eryone ER20 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.42mm Extra Draft @Eryone ER20 0.6 nozzle.json index b6c8cd4dbb..13bdd2a5fb 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.42mm Extra Draft @Eryone ER20 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.42mm Extra Draft @Eryone ER20 0.6 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.42mm Extra Draft @Eryone ER20 0.6 nozzle", + "inherits": "fdm_process_ER20_0.42_nozzle_0.6", + "from": "system", + "setting_id": "q6PozBOTtWU7CMb0", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.6 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.42_nozzle_0.6", - "setting_id": "q6PozBOTtWU7CMb0", - "instantiation": "true", - "name": "0.42mm Extra Draft @Eryone ER20 0.6 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.48mm Draft @Eryone ER20 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.48mm Draft @Eryone ER20 0.8 nozzle.json index b4b2bed4e5..a45b4c05b2 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.48mm Draft @Eryone ER20 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.48mm Draft @Eryone ER20 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.48mm Draft @Eryone ER20 0.8 nozzle", + "inherits": "fdm_process_ER20_0.48_nozzle_0.8", + "from": "system", + "setting_id": "O3BhYAmUROrYm64x", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.48_nozzle_0.8", - "setting_id": "O3BhYAmUROrYm64x", - "instantiation": "true", - "name": "0.48mm Draft @Eryone ER20 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/0.56mm Extra Draft @Eryone ER20 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20/0.56mm Extra Draft @Eryone ER20 0.8 nozzle.json index df15e8722f..c500f00896 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/0.56mm Extra Draft @Eryone ER20 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20/0.56mm Extra Draft @Eryone ER20 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.56mm Extra Draft @Eryone ER20 0.8 nozzle", + "inherits": "fdm_process_ER20_0.56_nozzle_0.8", + "from": "system", + "setting_id": "RCycTBzuArwmwrj1", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_0.56_nozzle_0.8", - "setting_id": "RCycTBzuArwmwrj1", - "instantiation": "true", - "name": "0.56mm Extra Draft @Eryone ER20 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.06_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.06_nozzle_0.2.json index aeb0a8babe..25626784f6 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.06_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.06_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_0.06_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.06", "line_width": "0.22", - "name": "fdm_process_ER20_0.06_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.06", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.06", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.08_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.08_nozzle_0.2.json index 298bae6b03..cba1685f01 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.08_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.08_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_0.08_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.08", "line_width": "0.22", - "name": "fdm_process_ER20_0.08_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.08", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.08", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.10_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.10_nozzle_0.2.json index e25994edf5..fc5d14a763 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.10_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.10_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_0.10_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.1", "line_width": "0.22", - "name": "fdm_process_ER20_0.10_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.1", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.1", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12.json index 47dab55b11..2fd68b2f50 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12.json @@ -1,12 +1,13 @@ { + "type": "process", + "name": "fdm_process_ER20_0.12", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", - "instantiation": "false", "layer_height": "0.12", - "name": "fdm_process_ER20_0.12", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", "overhang_3_4_speed": "10", @@ -14,6 +15,5 @@ "support_threshold_angle": "25", "support_top_z_distance": "0.16", "top_shell_layers": "5", - "top_shell_thickness": "0.6", - "type": "process" + "top_shell_thickness": "0.6" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12_nozzle_0.2.json index f365127bd8..a850e4d244 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.12_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_0.12_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.12", "line_width": "0.22", - "name": "fdm_process_ER20_0.12_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.12", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.12", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.14_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.14_nozzle_0.2.json index 36bddbb8c1..01d0d03b70 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.14_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.14_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_0.14_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.14", "line_width": "0.22", - "name": "fdm_process_ER20_0.14_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.14", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.14", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.15_nozzle_0.5.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.15_nozzle_0.5.json index c1b87f3c79..1ac3e109d2 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.15_nozzle_0.5.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.15_nozzle_0.5.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_0.15_nozzle_0.5", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", "initial_layer_line_width": "0.52", "inner_wall_line_width": "0.55", - "instantiation": "false", "internal_solid_infill_line_width": "0.55", "ironing_inset": "0.21", "layer_height": "0.15", "line_width": "0.52", - "name": "fdm_process_ER20_0.15_nozzle_0.5", "outer_wall_line_width": "0.52", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", @@ -22,6 +23,5 @@ "support_top_z_distance": "0.15", "top_shell_layers": "6", "top_shell_thickness": "0", - "top_surface_line_width": "0.52", - "type": "process" + "top_surface_line_width": "0.52" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.16.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.16.json index 4ccdbd7f5d..559dd8a177 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.16.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.16.json @@ -1,18 +1,18 @@ { + "type": "process", + "name": "fdm_process_ER20_0.16", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "bottom_shell_layers": "5", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", - "instantiation": "false", "layer_height": "0.16", - "name": "fdm_process_ER20_0.16", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", "overhang_3_4_speed": "10", "support_bottom_z_distance": "0.16", "support_top_z_distance": "0.16", "top_shell_layers": "6", - "top_shell_thickness": "0", - "type": "process" + "top_shell_thickness": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.18_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.18_nozzle_0.6.json index e0898428f9..806ecfd94b 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.18_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.18_nozzle_0.6.json @@ -1,22 +1,22 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.18_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.18", "line_width": "0.62", - "name": "fdm_process_ER20_0.18_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_bottom_z_distance": "0.18", "support_line_width": "0.62", "support_top_z_distance": "0.18", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.20.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.20.json index d19ce1d6b5..db95834983 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.20.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.20.json @@ -1,18 +1,18 @@ { + "type": "process", + "name": "fdm_process_ER20_0.20", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "bottom_shell_layers": "5", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", - "instantiation": "false", "layer_height": "0.20", - "name": "fdm_process_ER20_0.20", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", "overhang_3_4_speed": "10", "support_bottom_z_distance": "0.16", "support_top_z_distance": "0.16", "top_shell_layers": "5", - "top_shell_thickness": "0", - "type": "process" + "top_shell_thickness": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24.json index a7123ed6e4..ea72c8881c 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24.json @@ -1,16 +1,16 @@ { + "type": "process", + "name": "fdm_process_ER20_0.24", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", - "instantiation": "false", "layer_height": "0.24", - "name": "fdm_process_ER20_0.24", "support_bottom_z_distance": "0.16", "support_top_z_distance": "0.16", "support_threshold_angle": "35", "top_shell_layers": "5", "top_shell_thickness": "0", - "top_surface_line_width": "0.45", - "type": "process" + "top_surface_line_width": "0.45" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.6.json index 1532096134..86ba72d2f1 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.24_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.24", "line_width": "0.62", - "name": "fdm_process_ER20_0.24_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.8.json index 2a6ffbb9f5..6d6a928541 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.24_nozzle_0.8.json @@ -1,21 +1,21 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.24_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.24", "line_width": "0.82", - "name": "fdm_process_ER20_0.24_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", - "top_surface_line_width": "0.82", - "type": "process" + "top_surface_line_width": "0.82" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.25_nozzle_0.5.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.25_nozzle_0.5.json index ecffb4877c..38003a9df9 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.25_nozzle_0.5.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.25_nozzle_0.5.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.25_nozzle_0.5", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.55", "initial_layer_print_height": "0.2", "inner_wall_line_width": "0.55", - "instantiation": "false", "internal_solid_infill_line_width": "0.55", "ironing_inset": "0.21", "layer_height": "0.25", "line_width": "0.55", - "name": "fdm_process_ER20_0.25_nozzle_0.5", "outer_wall_line_width": "0.55", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.55", "support_line_width": "0.55", - "top_surface_line_width": "0.55", - "type": "process" + "top_surface_line_width": "0.55" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.28.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.28.json index d75e311f29..ba913a409f 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.28.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.28.json @@ -1,16 +1,16 @@ { + "type": "process", + "name": "fdm_process_ER20_0.28", + "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_common", - "instantiation": "false", "layer_height": "0.28", - "name": "fdm_process_ER20_0.28", "support_bottom_z_distance": "0.16", "support_threshold_angle": "40", "support_top_z_distance": "0.16", "top_shell_layers": "4", "top_shell_thickness": "0", - "top_surface_line_width": "0.45", - "type": "process" + "top_surface_line_width": "0.45" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.30_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.30_nozzle_0.6.json index 906493c26d..91de6302d0 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.30_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.30_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.30_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.3", "line_width": "0.62", - "name": "fdm_process_ER20_0.30_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.32_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.32_nozzle_0.8.json index 3a41303514..70ba0bd138 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.32_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.32_nozzle_0.8.json @@ -1,21 +1,21 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.32_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.32", "line_width": "0.82", - "name": "fdm_process_ER20_0.32_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", - "top_surface_line_width": "0.82", - "type": "process" + "top_surface_line_width": "0.82" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.36_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.36_nozzle_0.6.json index b204326637..b20f77d447 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.36_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.36_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.36_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.36", "line_width": "0.62", - "name": "fdm_process_ER20_0.36_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.40_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.40_nozzle_0.8.json index a12fe0e287..4b96ae9173 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.40_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.40_nozzle_0.8.json @@ -1,21 +1,21 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.40_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.4", "line_width": "0.82", - "name": "fdm_process_ER20_0.40_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", - "top_surface_line_width": "0.82", - "type": "process" + "top_surface_line_width": "0.82" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.42_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.42_nozzle_0.6.json index 5663b993b7..25f8762e55 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.42_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.42_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.42_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.42", "line_width": "0.62", - "name": "fdm_process_ER20_0.42_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.48_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.48_nozzle_0.8.json index c5a3bca18c..603758c587 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.48_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.48_nozzle_0.8.json @@ -1,21 +1,21 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.48_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.48", "line_width": "0.82", - "name": "fdm_process_ER20_0.48_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", - "top_surface_line_width": "0.82", - "type": "process" + "top_surface_line_width": "0.82" } diff --git a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.56_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.56_nozzle_0.8.json index 28c4e47272..eecb35736f 100644 --- a/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.56_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20/fdm_process_ER20_0.56_nozzle_0.8.json @@ -1,22 +1,22 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_0.56_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.56", "line_width": "0.82", - "name": "fdm_process_ER20_0.56_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", "top_surface_line_width": "0.82", - "top_surface_pattern": "monotonic", - "type": "process" + "top_surface_pattern": "monotonic" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.12mm Draft @Eryone ER20 Klipper 0.2 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.12mm Draft @Eryone ER20 Klipper 0.2 nozzle.json index 1ea915ac25..bb24e38c8b 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.12mm Draft @Eryone ER20 Klipper 0.2 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.12mm Draft @Eryone ER20 Klipper 0.2 nozzle.json @@ -1,13 +1,13 @@ { + "type": "process", + "name": "0.12mm Draft @Eryone ER20 Klipper 0.2 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.12_nozzle_0.2", + "from": "system", + "setting_id": "G6ezw9j2ZskBlDcf", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.2 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.12_nozzle_0.2", - "setting_id": "G6ezw9j2ZskBlDcf", - "instantiation": "true", - "name": "0.12mm Draft @Eryone ER20 Klipper 0.2 nozzle", - "sparse_infill_pattern": "gyroid", - "type": "process" + "sparse_infill_pattern": "gyroid" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.14mm Extra Draft @Eryone ER20 Klipper 0.2 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.14mm Extra Draft @Eryone ER20 Klipper 0.2 nozzle.json index 17ddd78449..781bcc50b4 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.14mm Extra Draft @Eryone ER20 Klipper 0.2 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.14mm Extra Draft @Eryone ER20 Klipper 0.2 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.14mm Extra Draft @Eryone ER20 Klipper 0.2 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.14_nozzle_0.2", + "from": "system", + "setting_id": "REb8DrBmb84Jz1RU", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.2 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.14_nozzle_0.2", - "setting_id": "REb8DrBmb84Jz1RU", - "instantiation": "true", - "name": "0.14mm Extra Draft @Eryone ER20 Klipper 0.2 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.15mm Optimal @Eryone ER20 Klipper 0.5 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.15mm Optimal @Eryone ER20 Klipper 0.5 nozzle.json index dae8d693f8..6839e252df 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.15mm Optimal @Eryone ER20 Klipper 0.5 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.15mm Optimal @Eryone ER20 Klipper 0.5 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.15mm Optimal @Eryone ER20 Klipper 0.5 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.15_nozzle_0.5", + "from": "system", + "setting_id": "bwykEBgiXSoyw8zd", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.5 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.15_nozzle_0.5", - "setting_id": "bwykEBgiXSoyw8zd", - "instantiation": "true", - "name": "0.15mm Optimal @Eryone ER20 Klipper 0.5 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.18mm Fine @Eryone ER20 Klipper 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.18mm Fine @Eryone ER20 Klipper 0.6 nozzle.json index abba79b691..55b5c999e6 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.18mm Fine @Eryone ER20 Klipper 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.18mm Fine @Eryone ER20 Klipper 0.6 nozzle.json @@ -1,11 +1,11 @@ { - "compatible_printers": [ - "Eryone ER20 Klipper 0.6 nozzle" - ], - "from": "system", + "type": "process", + "name": "0.18mm Fine @Eryone ER20 Klipper 0.6 nozzle", "inherits": "fdm_process_ER20_Klipper_0.18_nozzle_0.6", + "from": "system", "setting_id": "4Wh9O5o6h68TEy69", "instantiation": "true", - "name": "0.18mm Fine @Eryone ER20 Klipper 0.6 nozzle", - "type": "process" + "compatible_printers": [ + "Eryone ER20 Klipper 0.6 nozzle" + ] } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Standard @Eryone ER20 Klipper.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Standard @Eryone ER20 Klipper.json index 3208090373..bb42e46c99 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Standard @Eryone ER20 Klipper.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Standard @Eryone ER20 Klipper.json @@ -1,13 +1,13 @@ { + "type": "process", + "name": "0.20mm Standard @Eryone ER20 Klipper", + "inherits": "fdm_process_ER20_Klipper_0.20", + "from": "system", + "setting_id": "08wgu9MP0trL3JBg", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.4 nozzle" ], - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.20", - "setting_id": "08wgu9MP0trL3JBg", - "instantiation": "true", "layer_height": "0.20", - "name": "0.20mm Standard @Eryone ER20 Klipper", - "notes": "", - "type": "process" + "notes": "" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Strength @Eryone ER20 Klipper.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Strength @Eryone ER20 Klipper.json index a0679cda21..b39dcd5503 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Strength @Eryone ER20 Klipper.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.20mm Strength @Eryone ER20 Klipper.json @@ -1,14 +1,14 @@ { + "type": "process", + "name": "0.20mm Strength @Eryone ER20 Klipper", + "inherits": "fdm_process_ER20_Klipper_0.20", + "from": "system", + "setting_id": "7pYaosUUA3Kv13pI", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.4 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.20", - "setting_id": "7pYaosUUA3Kv13pI", - "instantiation": "true", - "name": "0.20mm Strength @Eryone ER20 Klipper", "sparse_infill_density": "25%", - "type": "process", "wall_loops": "6" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Draft @Eryone ER20 Klipper.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Draft @Eryone ER20 Klipper.json index 4a9d3d1a7b..0c33decbda 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Draft @Eryone ER20 Klipper.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Draft @Eryone ER20 Klipper.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.24mm Draft @Eryone ER20 Klipper", + "inherits": "fdm_process_ER20_Klipper_0.24", + "from": "system", + "setting_id": "SJzxe1s82yL2Lgrj", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.4 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.24", - "setting_id": "SJzxe1s82yL2Lgrj", - "instantiation": "true", - "name": "0.24mm Draft @Eryone ER20 Klipper", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Fine @Eryone ER20 Klipper 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Fine @Eryone ER20 Klipper 0.8 nozzle.json index 75c49ea75a..b0505f3053 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Fine @Eryone ER20 Klipper 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Fine @Eryone ER20 Klipper 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.24mm Fine @Eryone ER20 Klipper 0.8 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.24_nozzle_0.8", + "from": "system", + "setting_id": "FaQ9qpjWF28hexB2", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.24_nozzle_0.8", - "setting_id": "FaQ9qpjWF28hexB2", - "instantiation": "true", - "name": "0.24mm Fine @Eryone ER20 Klipper 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Optimal @Eryone ER20 Klipper 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Optimal @Eryone ER20 Klipper 0.6 nozzle.json index 67c4801673..c6ec9d4d14 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Optimal @Eryone ER20 Klipper 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.24mm Optimal @Eryone ER20 Klipper 0.6 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.24mm Optimal @Eryone ER20 Klipper 0.6 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.24_nozzle_0.6", + "from": "system", + "setting_id": "BaYIyJyVUiPXPjMr", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.6 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.24_nozzle_0.6", - "setting_id": "BaYIyJyVUiPXPjMr", - "instantiation": "true", - "name": "0.24mm Optimal @Eryone ER20 Klipper 0.6 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle.json index 74b798ed80..8c6142132e 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.25_nozzle_0.5", + "from": "system", + "setting_id": "GFnRlK2ceYBvswLe", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.5 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.25_nozzle_0.5", - "setting_id": "GFnRlK2ceYBvswLe", - "instantiation": "true", - "name": "0.25mm Standard @Eryone ER20 Klipper 0.5 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.28mm Extra Draft @Eryone ER20 Klipper.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.28mm Extra Draft @Eryone ER20 Klipper.json index 182198870c..10a767540c 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.28mm Extra Draft @Eryone ER20 Klipper.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.28mm Extra Draft @Eryone ER20 Klipper.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.28mm Extra Draft @Eryone ER20 Klipper", + "inherits": "fdm_process_ER20_Klipper_0.28", + "from": "system", + "setting_id": "q5VO6Fykaq7MeqA3", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.4 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.28", - "setting_id": "q5VO6Fykaq7MeqA3", - "instantiation": "true", - "name": "0.28mm Extra Draft @Eryone ER20 Klipper", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle.json index e89b4e4328..f1b660b67b 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.30_nozzle_0.6", + "from": "system", + "setting_id": "uteDUtHF4ALpNDE9", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.6 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.30_nozzle_0.6", - "setting_id": "uteDUtHF4ALpNDE9", - "instantiation": "true", - "name": "0.30mm Standard @Eryone ER20 Klipper 0.6 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Strength @Eryone ER20 Klipper 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Strength @Eryone ER20 Klipper 0.6 nozzle.json index 948cffdd9e..4c89f50816 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Strength @Eryone ER20 Klipper 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.30mm Strength @Eryone ER20 Klipper 0.6 nozzle.json @@ -1,14 +1,14 @@ { + "type": "process", + "name": "0.30mm Strength @Eryone ER20 Klipper 0.6 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.30_nozzle_0.6", + "from": "system", + "setting_id": "I69wf0KGngqBKs6d", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.6 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.30_nozzle_0.6", - "setting_id": "I69wf0KGngqBKs6d", - "instantiation": "true", - "name": "0.30mm Strength @Eryone ER20 Klipper 0.6 nozzle", "sparse_infill_density": "25%", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.32mm Optimal @Eryone ER20 Klipper 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.32mm Optimal @Eryone ER20 Klipper 0.8 nozzle.json index a4fab18d22..33b0a77c3b 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.32mm Optimal @Eryone ER20 Klipper 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.32mm Optimal @Eryone ER20 Klipper 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.32mm Optimal @Eryone ER20 Klipper 0.8 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.32_nozzle_0.8", + "from": "system", + "setting_id": "6ULt0zBZlGeQj0zL", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.32_nozzle_0.8", - "setting_id": "6ULt0zBZlGeQj0zL", - "instantiation": "true", - "name": "0.32mm Optimal @Eryone ER20 Klipper 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.36mm Draft @Eryone ER20 Klipper 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.36mm Draft @Eryone ER20 Klipper 0.6 nozzle.json index 32a776a3c3..ba2c8d73c5 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.36mm Draft @Eryone ER20 Klipper 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.36mm Draft @Eryone ER20 Klipper 0.6 nozzle.json @@ -1,13 +1,13 @@ { + "type": "process", + "name": "0.36mm Draft @Eryone ER20 Klipper 0.6 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.36_nozzle_0.6", + "from": "system", + "setting_id": "JLPcqoC2Uib9aRUQ", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.6 nozzle" ], "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.36_nozzle_0.6", - "setting_id": "JLPcqoC2Uib9aRUQ", - "instantiation": "true", - "name": "0.36mm Draft @Eryone ER20 Klipper 0.6 nozzle", - "travel_speed": "250", - "type": "process" + "travel_speed": "250" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle.json index 90db009e2c..8f53d41934 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.40_nozzle_0.8", + "from": "system", + "setting_id": "Rar12YnTox9pGeWw", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.40_nozzle_0.8", - "setting_id": "Rar12YnTox9pGeWw", - "instantiation": "true", - "name": "0.40mm Standard @Eryone ER20 Klipper 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.42mm Extra Draft @Eryone ER20 Klipper 0.6 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.42mm Extra Draft @Eryone ER20 Klipper 0.6 nozzle.json index 2fb538d04a..4eb71e439d 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.42mm Extra Draft @Eryone ER20 Klipper 0.6 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.42mm Extra Draft @Eryone ER20 Klipper 0.6 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.42mm Extra Draft @Eryone ER20 Klipper 0.6 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.42_nozzle_0.6", + "from": "system", + "setting_id": "8XAFm1qhJ5VbrcDt", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.6 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.42_nozzle_0.6", - "setting_id": "8XAFm1qhJ5VbrcDt", - "instantiation": "true", - "name": "0.42mm Extra Draft @Eryone ER20 Klipper 0.6 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.48mm Draft @Eryone ER20 Klipper 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.48mm Draft @Eryone ER20 Klipper 0.8 nozzle.json index 96a1373759..57d3990944 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.48mm Draft @Eryone ER20 Klipper 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.48mm Draft @Eryone ER20 Klipper 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.48mm Draft @Eryone ER20 Klipper 0.8 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.48_nozzle_0.8", + "from": "system", + "setting_id": "PtwzuflLVEwcJU1s", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.48_nozzle_0.8", - "setting_id": "PtwzuflLVEwcJU1s", - "instantiation": "true", - "name": "0.48mm Draft @Eryone ER20 Klipper 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.56mm Extra Draft @Eryone ER20 Klipper 0.8 nozzle.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.56mm Extra Draft @Eryone ER20 Klipper 0.8 nozzle.json index a76d38d67a..f9dcb4b411 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.56mm Extra Draft @Eryone ER20 Klipper 0.8 nozzle.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/0.56mm Extra Draft @Eryone ER20 Klipper 0.8 nozzle.json @@ -1,12 +1,12 @@ { + "type": "process", + "name": "0.56mm Extra Draft @Eryone ER20 Klipper 0.8 nozzle", + "inherits": "fdm_process_ER20_Klipper_0.56_nozzle_0.8", + "from": "system", + "setting_id": "yjLp31EgxsGWg3AY", + "instantiation": "true", "compatible_printers": [ "Eryone ER20 Klipper 0.8 nozzle" ], - "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_ER20_Klipper_0.56_nozzle_0.8", - "setting_id": "yjLp31EgxsGWg3AY", - "instantiation": "true", - "name": "0.56mm Extra Draft @Eryone ER20 Klipper 0.8 nozzle", - "type": "process" + "elefant_foot_compensation": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.06_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.06_nozzle_0.2.json index b7ddf5d471..e10f036503 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.06_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.06_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.06_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.06", "line_width": "0.22", - "name": "fdm_process_ER20_Klipper_0.06_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.06", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.06", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.08_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.08_nozzle_0.2.json index 023831538f..3717b77e01 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.08_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.08_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.08_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.08", "line_width": "0.22", - "name": "fdm_process_ER20_Klipper_0.08_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.08", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.08", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.10_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.10_nozzle_0.2.json index 7595ff7330..d1f2d8a94e 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.10_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.10_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.10_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.1", "line_width": "0.22", - "name": "fdm_process_ER20_Klipper_0.10_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.1", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.1", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12.json index 69ff2af25e..ea4b88c42c 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12.json @@ -1,12 +1,13 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.12", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", - "instantiation": "false", "layer_height": "0.12", - "name": "fdm_process_ER20_Klipper_0.12", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", "overhang_3_4_speed": "10", @@ -14,6 +15,5 @@ "support_threshold_angle": "25", "support_top_z_distance": "0.16", "top_shell_layers": "5", - "top_shell_thickness": "0.6", - "type": "process" + "top_shell_thickness": "0.6" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12_nozzle_0.2.json index b05e4cc430..5193865b34 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.12_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.12_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.12", "line_width": "0.22", - "name": "fdm_process_ER20_Klipper_0.12_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.12", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.12", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.14_nozzle_0.2.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.14_nozzle_0.2.json index 4cb51f3fa3..34399dccb7 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.14_nozzle_0.2.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.14_nozzle_0.2.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.14_nozzle_0.2", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", "initial_layer_line_width": "0.25", "inner_wall_line_width": "0.22", - "instantiation": "false", "internal_solid_infill_line_width": "0.22", "ironing_inset": "0.11", "layer_height": "0.14", "line_width": "0.22", - "name": "fdm_process_ER20_Klipper_0.14_nozzle_0.2", "outer_wall_line_width": "0.22", "sparse_infill_line_width": "0.22", "support_bottom_z_distance": "0.14", @@ -18,6 +19,5 @@ "support_top_z_distance": "0.14", "top_shell_layers": "7", "top_surface_line_width": "0.22", - "type": "process", "wall_loops": "4" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.15_nozzle_0.5.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.15_nozzle_0.5.json index 8b9d0510d6..187eb955f0 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.15_nozzle_0.5.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.15_nozzle_0.5.json @@ -1,16 +1,17 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.15_nozzle_0.5", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bottom_shell_layers": "5", "bridge_flow": "1", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", "initial_layer_line_width": "0.52", "inner_wall_line_width": "0.55", - "instantiation": "false", "internal_solid_infill_line_width": "0.55", "ironing_inset": "0.21", "layer_height": "0.15", "line_width": "0.52", - "name": "fdm_process_ER20_Klipper_0.15_nozzle_0.5", "outer_wall_line_width": "0.52", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", @@ -22,6 +23,5 @@ "support_top_z_distance": "0.15", "top_shell_layers": "6", "top_shell_thickness": "0", - "top_surface_line_width": "0.52", - "type": "process" + "top_surface_line_width": "0.52" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.16.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.16.json index 838270870f..c2a2da9584 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.16.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.16.json @@ -1,18 +1,18 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.16", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "bottom_shell_layers": "5", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", - "instantiation": "false", "layer_height": "0.16", - "name": "fdm_process_ER20_Klipper_0.16", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", "overhang_3_4_speed": "10", "support_bottom_z_distance": "0.16", "support_top_z_distance": "0.16", "top_shell_layers": "6", - "top_shell_thickness": "0", - "type": "process" + "top_shell_thickness": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.18_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.18_nozzle_0.6.json index c43af7a161..637d483e3e 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.18_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.18_nozzle_0.6.json @@ -1,22 +1,22 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.18_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.18", "line_width": "0.62", - "name": "fdm_process_ER20_Klipper_0.18_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_bottom_z_distance": "0.18", "support_line_width": "0.62", "support_top_z_distance": "0.18", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.20.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.20.json index 0a0fbc96ca..4eb554ffa4 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.20.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.20.json @@ -1,18 +1,18 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.20", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "bottom_shell_layers": "5", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", - "instantiation": "false", "layer_height": "0.20", - "name": "fdm_process_ER20_Klipper_0.20", "overhang_1_4_speed": "60", "overhang_2_4_speed": "30", "overhang_3_4_speed": "10", "support_bottom_z_distance": "0.16", "support_top_z_distance": "0.16", "top_shell_layers": "5", - "top_shell_thickness": "0", - "type": "process" + "top_shell_thickness": "0" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24.json index d20c74bbf5..16fc9471ef 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24.json @@ -1,16 +1,16 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.24", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", - "instantiation": "false", "layer_height": "0.24", - "name": "fdm_process_ER20_Klipper_0.24", "support_bottom_z_distance": "0.16", "support_top_z_distance": "0.16", "support_threshold_angle": "35", "top_shell_layers": "5", "top_shell_thickness": "0", - "top_surface_line_width": "0.45", - "type": "process" + "top_surface_line_width": "0.45" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.6.json index eb55b212e5..69c93e65b8 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.24_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.24", "line_width": "0.62", - "name": "fdm_process_ER20_Klipper_0.24_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.8.json index bb639fd3db..272bee0193 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.24_nozzle_0.8.json @@ -1,21 +1,21 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.24_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.24", "line_width": "0.82", - "name": "fdm_process_ER20_Klipper_0.24_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", - "top_surface_line_width": "0.82", - "type": "process" + "top_surface_line_width": "0.82" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.25_nozzle_0.5.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.25_nozzle_0.5.json index 4de34c25a9..253a74cdbc 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.25_nozzle_0.5.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.25_nozzle_0.5.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.25_nozzle_0.5", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.52", "initial_layer_print_height": "0.2", "inner_wall_line_width": "0.52", - "instantiation": "false", "internal_solid_infill_line_width": "0.52", "ironing_inset": "0.21", "layer_height": "0.25", "line_width": "0.52", - "name": "fdm_process_ER20_Klipper_0.25_nozzle_0.5", "outer_wall_line_width": "0.52", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.52", "support_line_width": "0.52", - "top_surface_line_width": "0.52", - "type": "process" + "top_surface_line_width": "0.52" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.28.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.28.json index a38384ccd6..ea275d2f8a 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.28.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.28.json @@ -1,16 +1,16 @@ { + "type": "process", + "name": "fdm_process_ER20_Klipper_0.28", + "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", "bridge_flow": "1", "elefant_foot_compensation": "0", - "from": "system", - "inherits": "fdm_process_eryone_ER20_Klipper_common", - "instantiation": "false", "layer_height": "0.28", - "name": "fdm_process_ER20_Klipper_0.28", "support_bottom_z_distance": "0.16", "support_threshold_angle": "40", "support_top_z_distance": "0.16", "top_shell_layers": "4", "top_shell_thickness": "0", - "top_surface_line_width": "0.45", - "type": "process" + "top_surface_line_width": "0.45" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.30_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.30_nozzle_0.6.json index d9c7546b71..96353e5a49 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.30_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.30_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.30_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.3", "line_width": "0.62", - "name": "fdm_process_ER20_Klipper_0.30_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.32_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.32_nozzle_0.8.json index 926c1d2eb7..a4db98d968 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.32_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.32_nozzle_0.8.json @@ -1,21 +1,21 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.32_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.32", "line_width": "0.82", - "name": "fdm_process_ER20_Klipper_0.32_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", - "top_surface_line_width": "0.82", - "type": "process" + "top_surface_line_width": "0.82" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.36_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.36_nozzle_0.6.json index b460bfc6da..c3342ea896 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.36_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.36_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.36_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.36", "line_width": "0.62", - "name": "fdm_process_ER20_Klipper_0.36_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.40_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.40_nozzle_0.8.json index 0322029ca6..b1af14348b 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.40_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.40_nozzle_0.8.json @@ -1,22 +1,22 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.40_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.4", "line_width": "0.82", - "name": "fdm_process_ER20_Klipper_0.40_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", "top_surface_line_width": "0.82", - "top_surface_pattern": "monotonic", - "type": "process" + "top_surface_pattern": "monotonic" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.42_nozzle_0.6.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.42_nozzle_0.6.json index 2740014d1b..76d5c254d7 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.42_nozzle_0.6.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.42_nozzle_0.6.json @@ -1,20 +1,20 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.42_nozzle_0.6", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.62", "initial_layer_print_height": "0.3", "inner_wall_line_width": "0.62", - "instantiation": "false", "internal_solid_infill_line_width": "0.62", "ironing_inset": "0.31", "layer_height": "0.42", "line_width": "0.62", - "name": "fdm_process_ER20_Klipper_0.42_nozzle_0.6", "outer_wall_line_width": "0.62", "overhang_3_4_speed": "15", "sparse_infill_line_width": "0.62", "support_line_width": "0.62", - "top_surface_line_width": "0.62", - "type": "process" + "top_surface_line_width": "0.62" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.48_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.48_nozzle_0.8.json index 63391ccad7..32df0df51e 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.48_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.48_nozzle_0.8.json @@ -1,22 +1,22 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.48_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.48", "line_width": "0.82", - "name": "fdm_process_ER20_Klipper_0.48_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", "top_surface_line_width": "0.82", - "top_surface_pattern": "monotonic", - "type": "process" + "top_surface_pattern": "monotonic" } diff --git a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.56_nozzle_0.8.json b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.56_nozzle_0.8.json index 49c926381d..94a133d6a2 100644 --- a/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.56_nozzle_0.8.json +++ b/resources/profiles/Eryone/process/eryone_ER20_Klipper/fdm_process_ER20_Klipper_0.56_nozzle_0.8.json @@ -1,22 +1,22 @@ { - "bridge_flow": "1", - "from": "system", + "type": "process", + "name": "fdm_process_ER20_Klipper_0.56_nozzle_0.8", "inherits": "fdm_process_eryone_ER20_Klipper_common", + "from": "system", + "instantiation": "false", + "bridge_flow": "1", "initial_layer_line_width": "0.82", "initial_layer_print_height": "0.4", "inner_wall_line_width": "0.82", - "instantiation": "false", "internal_solid_infill_line_width": "0.82", "ironing_inset": "0.41", "layer_height": "0.56", "line_width": "0.82", - "name": "fdm_process_ER20_Klipper_0.56_nozzle_0.8", "outer_wall_line_width": "0.82", "overhang_3_4_speed": "25", "overhang_4_4_speed": "5", "sparse_infill_line_width": "0.82", "support_line_width": "0.82", "top_surface_line_width": "0.82", - "top_surface_pattern": "monotonic", - "type": "process" + "top_surface_pattern": "monotonic" } diff --git a/resources/profiles/FLSun.json b/resources/profiles/FLSun.json index 36d0129015..d8d91a09a0 100644 --- a/resources/profiles/FLSun.json +++ b/resources/profiles/FLSun.json @@ -1,6 +1,6 @@ { "name": "FLSun", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "FLSun configurations", "machine_model_list": [ diff --git a/resources/profiles/FLSun/filament/Generic ABS @FLSun S1.json b/resources/profiles/FLSun/filament/Generic ABS @FLSun S1.json index 3a57d47404..07bde5301d 100644 --- a/resources/profiles/FLSun/filament/Generic ABS @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic ABS @FLSun S1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @FLSun S1", - "inherits": "Generic ABS @FLSun", "renamed_from": "FLSun S1 ABS", + "inherits": "Generic ABS @FLSun", "from": "system", "setting_id": "a7U3u888FlJ6CSFb", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic ABS @FLSun T1.json b/resources/profiles/FLSun/filament/Generic ABS @FLSun T1.json index 36c684cdc6..54c0f5457e 100644 --- a/resources/profiles/FLSun/filament/Generic ABS @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic ABS @FLSun T1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @FLSun T1", - "inherits": "Generic ABS @FLSun", "renamed_from": "FLSun T1 ABS", + "inherits": "Generic ABS @FLSun", "from": "system", "setting_id": "j185WWfVulPxWJvQ", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic ABS @FLSun.json b/resources/profiles/FLSun/filament/Generic ABS @FLSun.json index 2daf007fe9..ce04f9a073 100644 --- a/resources/profiles/FLSun/filament/Generic ABS @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic ABS @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @FLSun", - "inherits": "fdm_filament_abs", "renamed_from": "FLSun Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "1lPapSrZbKMLBx6k", "filament_id": "OFY9muEs", diff --git a/resources/profiles/FLSun/filament/Generic ASA @FLSun S1.json b/resources/profiles/FLSun/filament/Generic ASA @FLSun S1.json index d605ac5519..e858be9f6c 100644 --- a/resources/profiles/FLSun/filament/Generic ASA @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic ASA @FLSun S1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @FLSun S1", - "inherits": "Generic ASA @FLSun", "renamed_from": "FLSun S1 ASA", + "inherits": "Generic ASA @FLSun", "from": "system", "setting_id": "qJeJII6CgHuaC4Iz", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic ASA @FLSun T1.json b/resources/profiles/FLSun/filament/Generic ASA @FLSun T1.json index c27f9e34dd..e7acf671d9 100644 --- a/resources/profiles/FLSun/filament/Generic ASA @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic ASA @FLSun T1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @FLSun T1", - "inherits": "Generic ASA @FLSun", "renamed_from": "FLSun T1 ASA", + "inherits": "Generic ASA @FLSun", "from": "system", "setting_id": "kj4PPnvuvvGDrDwA", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic ASA @FLSun.json b/resources/profiles/FLSun/filament/Generic ASA @FLSun.json index e86f82f441..681f5a381b 100644 --- a/resources/profiles/FLSun/filament/Generic ASA @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic ASA @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @FLSun", - "inherits": "fdm_filament_asa", "renamed_from": "FLSun Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "22OH64Yfg5sdyEmz", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/FLSun/filament/Generic PA @FLSun.json b/resources/profiles/FLSun/filament/Generic PA @FLSun.json index 49fe8c01fc..a47ceea70a 100644 --- a/resources/profiles/FLSun/filament/Generic PA @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PA @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @FLSun", - "inherits": "fdm_filament_pa", "renamed_from": "FLSun Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "hlHGTLqHjaRfMkqC", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/FLSun/filament/Generic PA-CF @FLSun.json b/resources/profiles/FLSun/filament/Generic PA-CF @FLSun.json index b6dc311dcf..370cdb2e6e 100644 --- a/resources/profiles/FLSun/filament/Generic PA-CF @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PA-CF @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @FLSun", - "inherits": "fdm_filament_pa", "renamed_from": "FLSun Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "xiLUY07SM81i1pPs", "filament_id": "OFQLcbps", diff --git a/resources/profiles/FLSun/filament/Generic PC @FLSun.json b/resources/profiles/FLSun/filament/Generic PC @FLSun.json index e4d81857d3..74f6bbfa1a 100644 --- a/resources/profiles/FLSun/filament/Generic PC @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PC @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @FLSun", - "inherits": "fdm_filament_pc", "renamed_from": "FLSun Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "Ok08F2LxNjxor6ph", "filament_id": "OFLakOUI", diff --git a/resources/profiles/FLSun/filament/Generic PETG @FLSun S1.json b/resources/profiles/FLSun/filament/Generic PETG @FLSun S1.json index 02506525dd..8af106f03d 100644 --- a/resources/profiles/FLSun/filament/Generic PETG @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic PETG @FLSun S1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @FLSun S1", - "inherits": "Generic PETG @FLSun", "renamed_from": "FLSun S1 PETG", + "inherits": "Generic PETG @FLSun", "from": "system", "setting_id": "LxDenrdsmz0QjMDE", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic PETG @FLSun T1.json b/resources/profiles/FLSun/filament/Generic PETG @FLSun T1.json index 64651bea1d..8a51e86e6b 100644 --- a/resources/profiles/FLSun/filament/Generic PETG @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic PETG @FLSun T1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @FLSun T1", - "inherits": "Generic PETG @FLSun", "renamed_from": "FLSun T1 PETG", + "inherits": "Generic PETG @FLSun", "from": "system", "setting_id": "n9wpUe32lTtq2iSS", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic PETG @FLSun.json b/resources/profiles/FLSun/filament/Generic PETG @FLSun.json index 84eaee1c7c..22dbbbf5e7 100644 --- a/resources/profiles/FLSun/filament/Generic PETG @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PETG @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @FLSun", - "inherits": "fdm_filament_pet", "renamed_from": "FLSun Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "pWuJLjWhYMutD92n", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/FLSun/filament/Generic PLA @FLSun S1.json b/resources/profiles/FLSun/filament/Generic PLA @FLSun S1.json index 5674ba8c27..9fa17d0e6b 100644 --- a/resources/profiles/FLSun/filament/Generic PLA @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic PLA @FLSun S1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @FLSun S1", - "inherits": "Generic PLA @FLSun", "renamed_from": "FLSun S1 PLA Generic", + "inherits": "Generic PLA @FLSun", "from": "system", "setting_id": "4f9vGTYsHDbZoVjs", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/FLSun/filament/Generic PLA @FLSun T1.json b/resources/profiles/FLSun/filament/Generic PLA @FLSun T1.json index 93b9ac08d4..d5a35a8138 100644 --- a/resources/profiles/FLSun/filament/Generic PLA @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic PLA @FLSun T1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @FLSun T1", - "inherits": "Generic PLA @FLSun", "renamed_from": "FLSun T1 PLA Generic", + "inherits": "Generic PLA @FLSun", "from": "system", "setting_id": "5aJUZ6r6jtnvck19", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/FLSun/filament/Generic PLA @FLSun.json b/resources/profiles/FLSun/filament/Generic PLA @FLSun.json index a4f8655ff9..f5696d5205 100644 --- a/resources/profiles/FLSun/filament/Generic PLA @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PLA @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @FLSun", - "inherits": "fdm_filament_pla", "renamed_from": "FLSun Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "JcpwaJCVC9MoJrPB", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun S1.json b/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun S1.json index af00b2272d..daf2d6cfc5 100644 --- a/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun S1.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA High Speed @FLSun S1", - "inherits": "Generic PLA High Speed @System", "renamed_from": "FLSun S1 PLA High Speed", + "inherits": "Generic PLA High Speed @System", "from": "system", "setting_id": "ONz6C8a3AMGWxqdK", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_multitool_ramming_flow": [ "10" ], diff --git a/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun T1.json b/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun T1.json index 7468aadd31..e53b94fe26 100644 --- a/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic PLA High Speed @FLSun T1.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA High Speed @FLSun T1", - "inherits": "Generic PLA High Speed @System", "renamed_from": "FLSun T1 PLA High Speed", + "inherits": "Generic PLA High Speed @System", "from": "system", "setting_id": "en1l0jgFX97t6qUi", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_multitool_ramming_flow": [ "10" ], diff --git a/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun S1.json b/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun S1.json index 0ec0d28da4..d4425663dc 100644 --- a/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun S1.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA Silk @FLSun S1", - "inherits": "Generic PLA Silk @System", "renamed_from": "FLSun S1 PLA Silk", + "inherits": "Generic PLA Silk @System", "from": "system", "setting_id": "NTJw0fbcn3JoOr0R", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_retraction_length": [ "nil" ], diff --git a/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun T1.json b/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun T1.json index 891697aa01..b5c18fb00b 100644 --- a/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic PLA Silk @FLSun T1.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA Silk @FLSun T1", - "inherits": "Generic PLA Silk @System", "renamed_from": "FLSun T1 PLA Silk", + "inherits": "Generic PLA Silk @System", "from": "system", "setting_id": "y2p7TTGI8XWIeiQY", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_retraction_length": [ "nil" ], diff --git a/resources/profiles/FLSun/filament/Generic PLA-CF @FLSun.json b/resources/profiles/FLSun/filament/Generic PLA-CF @FLSun.json index 87b301513e..e5e25b612c 100644 --- a/resources/profiles/FLSun/filament/Generic PLA-CF @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PLA-CF @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @FLSun", - "inherits": "fdm_filament_pla", "renamed_from": "FLSun Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "teBJEScAMecyn3JU", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/FLSun/filament/Generic PVA @FLSun.json b/resources/profiles/FLSun/filament/Generic PVA @FLSun.json index 9279ece682..0117b6fad5 100644 --- a/resources/profiles/FLSun/filament/Generic PVA @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic PVA @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @FLSun", - "inherits": "fdm_filament_pva", "renamed_from": "FLSun Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "hyVWJBubfQl497iO", "filament_id": "OFDvXujf", diff --git a/resources/profiles/FLSun/filament/Generic TPU @FLSun S1.json b/resources/profiles/FLSun/filament/Generic TPU @FLSun S1.json index 76e27d9be3..21fe1d4443 100644 --- a/resources/profiles/FLSun/filament/Generic TPU @FLSun S1.json +++ b/resources/profiles/FLSun/filament/Generic TPU @FLSun S1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @FLSun S1", - "inherits": "Generic TPU @FLSun", "renamed_from": "FLSun S1 TPU", + "inherits": "Generic TPU @FLSun", "from": "system", "setting_id": "xDnQih17nXmGPoPc", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic TPU @FLSun T1.json b/resources/profiles/FLSun/filament/Generic TPU @FLSun T1.json index 25f60f10e1..bfaea98bda 100644 --- a/resources/profiles/FLSun/filament/Generic TPU @FLSun T1.json +++ b/resources/profiles/FLSun/filament/Generic TPU @FLSun T1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @FLSun T1", - "inherits": "Generic TPU @FLSun", "renamed_from": "FLSun T1 TPU", + "inherits": "Generic TPU @FLSun", "from": "system", "setting_id": "TEakmydLXxrHti3G", "instantiation": "true", diff --git a/resources/profiles/FLSun/filament/Generic TPU @FLSun.json b/resources/profiles/FLSun/filament/Generic TPU @FLSun.json index 70d1b8c42a..199a85987a 100644 --- a/resources/profiles/FLSun/filament/Generic TPU @FLSun.json +++ b/resources/profiles/FLSun/filament/Generic TPU @FLSun.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @FLSun", - "inherits": "fdm_filament_tpu", "renamed_from": "FLSun Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "gJ3UZr4n4K8DPdBz", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/FLSun/machine/FLSun S1 0.4 nozzle.json b/resources/profiles/FLSun/machine/FLSun S1 0.4 nozzle.json index e75c40726b..a2adfba683 100644 --- a/resources/profiles/FLSun/machine/FLSun S1 0.4 nozzle.json +++ b/resources/profiles/FLSun/machine/FLSun S1 0.4 nozzle.json @@ -46,45 +46,59 @@ "80" ], "machine_max_acceleration_e": [ + "40000", "40000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "40000", "40000" ], "machine_max_jerk_e": [ + "100", "100" ], "machine_max_jerk_x": [ + "20000", "20000" ], "machine_max_jerk_y": [ + "20000", "20000" ], "machine_max_jerk_z": [ + "10000", "10000" ], "machine_max_speed_e": [ + "1200", "1200" ], "machine_max_speed_x": [ + "1200", "1200" ], "machine_max_speed_y": [ + "1200", "1200" ], "machine_max_speed_z": [ + "1200", "1200" ], "printable_area": [ diff --git a/resources/profiles/FLSun/machine/FLSun T1 0.4 nozzle.json b/resources/profiles/FLSun/machine/FLSun T1 0.4 nozzle.json index 3cff2526eb..a1d43dc592 100644 --- a/resources/profiles/FLSun/machine/FLSun T1 0.4 nozzle.json +++ b/resources/profiles/FLSun/machine/FLSun T1 0.4 nozzle.json @@ -46,45 +46,59 @@ "70" ], "machine_max_acceleration_e": [ + "30000", "30000" ], "machine_max_acceleration_extruding": [ + "30000", "30000" ], "machine_max_acceleration_retracting": [ + "30000", "30000" ], "machine_max_acceleration_x": [ + "30000", "30000" ], "machine_max_acceleration_y": [ + "30000", "30000" ], "machine_max_acceleration_z": [ + "30000", "30000" ], "machine_max_jerk_e": [ + "100", "100" ], "machine_max_jerk_x": [ + "20000", "20000" ], "machine_max_jerk_y": [ + "20000", "20000" ], "machine_max_jerk_z": [ + "10000", "10000" ], "machine_max_speed_e": [ + "1000", "1000" ], "machine_max_speed_x": [ + "1000", "1000" ], "machine_max_speed_y": [ + "1000", "1000" ], "machine_max_speed_z": [ + "1000", "1000" ], "printable_area": [ diff --git a/resources/profiles/Flashforge.json b/resources/profiles/Flashforge.json index 40e37cba03..be6e64da1e 100644 --- a/resources/profiles/Flashforge.json +++ b/resources/profiles/Flashforge.json @@ -1,7 +1,7 @@ { "name": "Flashforge", "url": "", - "version": "02.04.00.10", + "version": "02.04.00.11", "force_update": "0", "description": "Flashforge configurations", "machine_model_list": [ diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.6 nozzle.json index 7ba9ffc527..f394f8f15d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "fgEYZ1Mgyp1AvtwU", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.8 nozzle.json index d797114137..020a3ec800 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "cIxbQMVdG5K85rJr", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X.json index 82e08e3f49..ecdcc55df5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "9GXBeuCUrScJfmJB", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF Adventurer A5.json index 0ea70e0bf4..eef66d26e8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "rDW4AwKc7SD7WIxN", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5.json index 5e5ce18eea..30714730ad 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "ds0GgE1jssl4IbF3", "filament_id": "OFibWuBd", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5P.json index 9ea370b14b..ca1681ca27 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "UTWbwTYuXYbBx3uw", "filament_id": "OFibWuBd", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 HF nozzle.json index c38639dd89..5f0155e58a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "NttDJCrfB01uwMDl", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 nozzle.json index 9709d11e22..29115ab4d5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "hJd6dG6OdEffEFC7", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.8 HF nozzle.json index 2f3d072baf..8fed11ee6b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8yFCuCnEuI3dUvQy", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 HF.json index a6badb7396..763e98e344 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "np4fP5kghRlczOTT", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4.json index c70351a9b1..6ebc5b5fc5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8o2maTFOXq0XR6Dm", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 HF nozzle.json index d6be224ddc..bcf7f43a43 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vCsjC0UnKenzIR0O", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 nozzle.json index 9ff2f3f54a..d074cb6f53 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "xhxVdlmh5r7meoHo", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.8 HF nozzle.json index d2c5c73541..129253e9d8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "6dlQN4Xhd6kGZ0Qn", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P HF.json index c4b58df04c..18f6622fa6 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "r8WVFPozL8f5oLVJ", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P.json index ebf003f20d..17cc2d9f95 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "xw0pZNmhw1K4tPQ1", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS Basic.json b/resources/profiles/Flashforge/filament/Flashforge ABS Basic.json index 8be3cb0913..b2bb4df5d5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS Basic.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS Basic.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "m6QLC2UaS3fW298i", "filament_id": "OFibWuBd", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge ABS Basic" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4 0.6 nozzle.json index 398f80f8a5..1289d1c7ef 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Nx3Px0Zu356IKShT", "filament_id": "OFYTIMbj", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4.json index 3fd0dc97ea..f4bf737da4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "d4EGsmMeEDCOUBF2", "filament_id": "OFYTIMbj", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "complete_print_exhaust_fan_speed": [ "50" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P 0.6 nozzle.json index 043e0ea208..e0a4aa3260 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "9ziPFKsjESbw1pXL", "filament_id": "OFYTIMbj", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P.json index 77148bf480..25550aded3 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS-CF @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "NzJJs6yrSik5xuyX", "filament_id": "OFYTIMbj", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "complete_print_exhaust_fan_speed": [ "50" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5.json index 8cb591fa47..0d4d387a4e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "UinlbuXNbad2kN0s", "filament_id": "OFojbdhR", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5P.json index 3fefbd7a96..c1cb75784b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ABS-GF @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "ycgiXY41kqNgslE3", "filament_id": "OFojbdhR", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA @FF AD5M 0.25 Nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA @FF AD5M 0.25 Nozzle.json index f7d1332ec2..ee9f015d7a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA @FF AD5M 0.25 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA @FF AD5M 0.25 Nozzle.json @@ -4,10 +4,10 @@ "inherits": "Generic ASA @Flashforge", "from": "system", "filament_id": "OFJS560n", + "instantiation": "false", "filament_vendor": [ "Flashforge" ], - "instantiation": "false", "compatible_printers": [ "Flashforge Adventurer 5M 0.25 Nozzle", "Flashforge Adventurer 5M Pro 0.25 Nozzle" diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5M 0.25 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5M 0.25 nozzle.json index 0f99d476fc..a80eb8aac6 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5M 0.25 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5M 0.25 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "kjS4k8nrIdNNNoWw", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge ASA Basic @FF AD5M 0.25 nozzle" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.25 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.25 nozzle.json index 9a3aac8573..d626f4b25e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.25 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.25 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Y647IFVkk5JIXzte", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.6 nozzle.json index 7a199389af..84907ec84b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vaOyXUcrJ97KE7ZW", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.8 nozzle.json index 3c2e7173bf..55a3bb3550 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "iLWq5pJ3ox9EAM1Z", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X.json index 68f66a1f6b..b58051e0be 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "i7PUPYxy0Z9weyyA", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF Adventurer A5.json index 80943c015a..05dc0925a5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "FY9mcqOyuu1Gqq1m", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5.json index 5aec1c1d8b..ad94105eb5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "UUSDyOetXSOuBIUd", "filament_id": "OFFFg2Pf", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5P.json index 18ae2c78f1..9afefb0909 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "2r0kwhklE24Hp94O", "filament_id": "OFFFg2Pf", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 HF nozzle.json index 66ae12c06c..87e870ecae 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "w8O6oenp0NymzCqf", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 nozzle.json index 166d3a01ab..03849119fe 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "thhmWRzNYLYJOeR2", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.8 HF nozzle.json index 54e47a5e64..bfa2769868 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "g5jiz6Q6or23BIo7", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 HF.json index 01db10d49d..66db692dd2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "7xmWlHHNMvXBKdYS", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4.json index 9cdc87b1e5..8e81c9b855 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "r0B8KfZ1mNWMvGqE", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 HF nozzle.json index d8801abca8..ae0473e389 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "CBLZqLhkwf5XKO12", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 nozzle.json index 1cc08eabb3..30234b7f4c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Df3anJxiRXLVO9hw", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.8 HF nozzle.json index 30787c9de1..3ba4b3f7fe 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Nu4WvBWuEhazZfh5", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P HF.json index 5b73e31a49..465105b8dc 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "hF0h4ye3hMDtEba1", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P.json index 05223314f5..b85d3cf82a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "3isZCWr4CBjFtGDX", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA Basic.json b/resources/profiles/Flashforge/filament/Flashforge ASA Basic.json index 2500eacd3f..100726da10 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA Basic.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA Basic.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "SU6r879TbQMUFCij", "filament_id": "OFFFg2Pf", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge ASA Basic" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5.json index 5cd421f15c..7daa8cfda2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5.json @@ -6,6 +6,9 @@ "setting_id": "TqU1elqwuVr9EhTA", "filament_id": "OFq0TY7C", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5P.json index c61eb8159b..7119ae83d9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA-CF @FF C5P.json @@ -6,6 +6,9 @@ "setting_id": "nMczAtoc5W0J2WkS", "filament_id": "OFq0TY7C", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5.json index de98bbdf41..c5cebbe5e0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "941E5MaAyFY3iv4V", "filament_id": "OFrZDhVt", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5P.json index 0bff2a9e2c..ab61e17048 100644 --- a/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge ASA-GF @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "RdmsxyUGUX8Ot4oj", "filament_id": "OFrZDhVt", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5.json index 608d143031..5f7e75ad38 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "ckwc7U0Q2eKHmCxY", "filament_id": "OFvaLVML", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5P.json index 14a3d39616..eda0021d7c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "AEQYrT7e4Q5J2G6C", "filament_id": "OFvaLVML", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 Pro 0.4 nozzle", "Flashforge Creator 5 Pro 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 HF nozzle.json index bb2f4387b9..b6071e5dc1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "jUNUZhE0BJyB64fC", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 nozzle.json index 597e24ade7..93a88f3576 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "0qMEqo9YMDLSVafs", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.8 HF nozzle.json index 5b17792267..b71f191b47 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ek749gIdUAPq6WxT", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 HF.json index b79fa3d0d2..91a8add8fe 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "tEohTtyHofD6l6o3", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "complete_print_exhaust_fan_speed": [ "50" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4.json index 96b5849040..e1d3687137 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "oLeLrIjFJzoZha3E", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 HF nozzle.json index cb385fd395..fac11c2185 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "HXGUlYY4X5IHhL3R", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 nozzle.json index a32508d8b0..a7932d87e9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "g22Cv3zy3h5BhJYK", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.8 HF nozzle.json index b2958e0032..08db515203 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "aDzBXuvN7IuSP5sa", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P HF.json index bbbaebe8b8..4b2c461dfb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "CIj24REX7BA8zPHQ", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "complete_print_exhaust_fan_speed": [ "50" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P.json index bc52c94e5b..205591ea81 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge HIPS @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "yAGyGjF6uDrjfjLn", "filament_id": "OFvaLVML", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.6 nozzle.json index c1dd59623c..4f87423ffd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vOqAGzaYLz0XdRvC", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.8 nozzle.json index 21198590ac..6d80e34383 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "KSuxZ3fpQz0khDSz", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X.json index 23703621f3..4e3f23c94c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "o4B1kAToVny7jw0M", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF Adventurer A5.json index 5825f17141..9eb341d698 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ZpNEEHTtvhMJS8Kv", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5.json index a48606e3c0..a74c501133 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "kpRved5M3NktqIYn", "filament_id": "OFDxxTpW", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5P.json index 9ceca02a50..72be5b0240 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "ypxgjHl9uIMyZIce", "filament_id": "OFDxxTpW", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 HF nozzle.json index 28565a5c3b..abd6ad90f2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "q9UbakUmZPzG3xU0", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 nozzle.json index 592b3fe094..deb7150b48 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "IL18Lu0qHx1RVqKD", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.8 HF nozzle.json index e4b953f089..52d9c81da9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "2FQib7fZjcwfCnm2", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 HF.json index 3534f1a60b..6d7728b5d9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "CtwOm90WWD4S7U6j", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4.json index 5a47b94941..fe42a7839c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "kvULpm0WhKiSPj8V", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 HF nozzle.json index 26df92ae7b..6915366030 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "CUU7knzm4cbe1giE", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 nozzle.json index b936141d13..51ca8798b7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "gcYvL572cumWZdnl", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.8 HF nozzle.json index f53c9c41e3..c8c5e5a53e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "cx99AH0C575XxAj9", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P HF.json index 263224a1ea..ec23e9a241 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "RrrKoR7MVD8IFQlq", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P.json index ff09b6e445..80dcdfccd6 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "7VEPGuR16wNukAX2", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PETG.json b/resources/profiles/Flashforge/filament/Flashforge HS PETG.json index 3ee8ed9e42..dd06f811c5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PETG.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PETG.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "H9uwlPw6m6Nf7qH5", "filament_id": "OFDxxTpW", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge HS PETG" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5M 0.25 Nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5M 0.25 Nozzle.json index d511cdafe6..35d20cded2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5M 0.25 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5M 0.25 Nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "OmDped3weZ4uHAtY", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Adventurer 5M 0.25 Nozzle", "Flashforge Adventurer 5M Pro 0.25 Nozzle" diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.6 nozzle.json index 082b03f19b..2c2162d5cf 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "oD592bif4ra0ADco", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.8 nozzle.json index 6571d871b4..5c11af86f6 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ldhMY6F7v6nK8wwf", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X.json index a5b788402d..df25c44944 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "5vzOmbjHbkJXrgYM", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF Adventurer A5.json index 9f34aa44af..2df2ee66c3 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "2L7FS5JeAyPb3y0s", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5.json index 85c0b17327..2106876030 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "xSJk7LFpYKmckPQh", "filament_id": "OFIK2H3G", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5P.json index 667e4045b9..08dfa6d74a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "xdFZUsj1cNLXdvT6", "filament_id": "OFIK2H3G", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 HF nozzle.json index ba4f6bc6d9..2ccf5b9e65 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "hzxRPyH1fqarsMuN", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 nozzle.json index 4e69e17253..4b0b75ad6c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "oJsLlIIpxwGSoJTv", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.8 HF nozzle.json index ad8f07ef26..551945e272 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "hJbNZ381ERkZ0KUB", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 HF.json index f202e50f11..81a37ad4f5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "BqavrNpwhXDXcZ3r", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4.json index 7472f78b02..a77b12bced 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "cgf4Qk4iHZh7zHN5", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 HF nozzle.json index 2bc30165fc..737ba3b476 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "p31K69Srld6o4sQ2", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 nozzle.json index b5308a0f8c..ef76855837 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "MwbYvnRIzlNmH81h", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.8 HF nozzle.json index 2c2ee97348..613fb82ce1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "rKhHmkqXYD2xN4K9", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P HF.json index 88184f5a92..caef6473f1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Dshsi3O7NvYYjXJt", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P.json index cd59be156d..d127543ac1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "mfnL6QEevCmTmOL0", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 0.6 HF nozzle.json index 3281932fe8..1541e28697 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "AGLHrHKWye0YTtNK", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 HF.json index f5de82a8bb..c924aa4ee5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "px8qzmB2yFLoNl83", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P 0.6 HF nozzle.json index da6fd90d98..ff90bc0593 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "mwuIEsBz5bXEV68w", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P HF.json index bb2d6256b6..0721d38cc0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "TielygFT88owWg4J", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.6 nozzle.json index 149406f025..59dbba6ad3 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "It2NI6OFhNEUvulz", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.8 HF nozzle.json index 22b1a35dcb..a7c152efc5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4 0.8 HF nozzle.json @@ -1,15 +1,15 @@ { "type": "filament", "name": "Flashforge HS PLA Burnt Ti@FF G4 0.8 HF nozzle", - "inherits": "Generic PLA @Flashforge G3U 0.6 Nozzle", "renamed_from": "Flashforge PLA Buint Ti @FF G4 0.8 nozzle;Flashforge PLA Buint Ti FF G4 0.8 nozzle", + "inherits": "Generic PLA @Flashforge G3U 0.6 Nozzle", "from": "system", "setting_id": "Qt3huWxoYpMEqEN6", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.6 nozzle.json index 6fb09f1458..59609aa49d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Y3XuavnnOMoHLGHA", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.8 HF nozzle.json index dccc672613..8361d79c60 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA Burnt Ti@FF G4P 0.8 HF nozzle.json @@ -1,15 +1,15 @@ { "type": "filament", "name": "Flashforge HS PLA Burnt Ti@FF G4P 0.8 HF nozzle", - "inherits": "Generic PLA @Flashforge G3U 0.6 Nozzle", "renamed_from": "Flashforge PLA Buint Ti @FF G4P 0.8 nozzle;Flashforge PLA Buint Ti FF G4P 0.8 nozzle", + "inherits": "Generic PLA @Flashforge G3U 0.6 Nozzle", "from": "system", "setting_id": "2HUxAWeolJIlxPs1", "filament_id": "OF8O09RG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA+ @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA+ @FF Adventurer A5.json index 22c1c9870f..c2bd7154f7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA+ @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA+ @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "V4jIUQzxoZkK50mn", "filament_id": "OFXB8ZI7", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge HS PLA.json b/resources/profiles/Flashforge/filament/Flashforge HS PLA.json index 8002ac7ba9..58f8fca603 100644 --- a/resources/profiles/Flashforge/filament/Flashforge HS PLA.json +++ b/resources/profiles/Flashforge/filament/Flashforge HS PLA.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vdaZBnDsmUC1fhDp", "filament_id": "OFIK2H3G", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge HS PLA" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 0.6 HF nozzle.json index f5d60553e6..dabb15e3cd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "u7rolQaTQz9U6veH", "filament_id": "OFEvEfw5", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 HF.json index 8b10616a83..c8b9164985 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "qTGTwiliWj3dSo9y", "filament_id": "OFEvEfw5", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4.json index ec1ded13ea..00c98624be 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "wAkuJRTLWxGyBU0b", "filament_id": "OFEvEfw5", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P 0.6 HF nozzle.json index bc05757132..066cc81a69 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "dbs29hQSQl9zuWis", "filament_id": "OFEvEfw5", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P HF.json index 1e5eb664ec..9c13b3abb5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "XGNPvS2ps7Xn2fpx", "filament_id": "OFEvEfw5", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P.json index 21ee8da2a6..1125a33164 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "h33iEGZ7wPeBYKYQ", "filament_id": "OFEvEfw5", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5.json index 2b4f6fc95a..27eade4316 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "e58C9MdOWikIbbVR", "filament_id": "OFGxuI0n", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5P.json index b75438e584..4681375016 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "RX2Tg8KpwQpCbkLI", "filament_id": "OFGxuI0n", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4.json index 3379bd5c39..e6e036a4db 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "C4DfYuQgDXIgK7mk", "filament_id": "OFGxuI0n", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4P.json index 07653a9002..e52bc920d8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PA-CF @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Yu7hL4izNsgDVqMT", "filament_id": "OFGxuI0n", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 HF nozzle.json index e88cbb31c3..f6aa5e7a0b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PC @FF G4 0.6 HF nozzle", - "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "renamed_from": "FlashForge PC @FF G4 0.6 HF nozzle;FlashForge PC FF G4 0.6 HF nozzle", + "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "from": "system", "setting_id": "Tj504IYSj6mUDR6E", "filament_id": "OFWXCbVF", diff --git a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 nozzle.json index 6b1decef09..a4eb9726c5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PC @FF G4 0.6 nozzle", - "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "renamed_from": "FlashForge PC @FF G4 0.6 nozzle;FlashForge PC FF G4 0.6 nozzle", + "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "from": "system", "setting_id": "VfhBf8676qCWatKP", "filament_id": "OFWXCbVF", diff --git a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.8 HF nozzle.json index e1740fb30d..d08b0bb2f7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4 0.8 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PC @FF G4 0.8 HF nozzle", - "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "renamed_from": "FlashForge PC @FF G4 0.8 HF nozzle;FlashForge PC FF G4 0.8 HF nozzle", + "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "from": "system", "setting_id": "ILBm9zXX5U4Oh82h", "filament_id": "OFWXCbVF", diff --git a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 HF nozzle.json index 11ec475184..70b46e169e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PC @FF G4P 0.6 HF nozzle", - "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "renamed_from": "FlashForge PC @FF G4P 0.6 HF nozzle;FlashForge PC FF G4P 0.6 HF nozzle", + "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "from": "system", "setting_id": "Kj6KWBfSuFALX2sd", "filament_id": "OFWXCbVF", diff --git a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 nozzle.json index 38ca36a685..466e515c74 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PC @FF G4P 0.6 nozzle", - "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "renamed_from": "FlashForge PC @FF G4P 0.6 nozzle;FlashForge PC FF G4P 0.6 nozzle", + "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "from": "system", "setting_id": "XjAM4PMXLCBwdgQf", "filament_id": "OFWXCbVF", diff --git a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.8 HF nozzle.json index dfdda7bfe2..ea43b47767 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PC @FF G4P 0.8 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PC @FF G4P 0.8 HF nozzle", - "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "renamed_from": "FlashForge PC @FF G4P 0.8 HF nozzle;FlashForge PC FF G4P 0.8 HF nozzle", + "inherits": "FusRock S-PAHT @G3U 0.6 Nozzle", "from": "system", "setting_id": "icAIkgRCZAjz6apM", "filament_id": "OFWXCbVF", diff --git a/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5.json index 7157336d3f..0a0fd2d622 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5.json @@ -6,6 +6,9 @@ "setting_id": "3bguiaEtUsS8ULHW", "filament_id": "OFrjacXf", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5P.json index b550ae743f..7d19965089 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PET-CF @FF C5P.json @@ -6,6 +6,9 @@ "setting_id": "W6i9E22BVo11TeCm", "filament_id": "OFrjacXf", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Basic.json b/resources/profiles/Flashforge/filament/Flashforge PETG Basic.json index 3d5c4f4b0c..f257a24995 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Basic.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Basic.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YLLJ4xZI704GReej", "filament_id": "OFYYeMyQ", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "60" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.6 nozzle.json index e15f011f1f..3c4126159a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "dFZ1MmHjj1AAIaMm", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.8 nozzle.json index a3d431030f..a93a6ed04a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Ro3rt7IAJrA5aZD6", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X.json index 7cc361d89d..05e1b984eb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "cTxrnqzr2wVt4Nj7", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF Adventurer A5.json index b1a6a9f7e5..f81aba4130 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "rPy6e6kaIt2tI34j", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "60" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5.json index 0a1b47b916..14dbf52b99 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "QA1KD03F0zj2zsVi", "filament_id": "OFXiArjA", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5P.json index 69cb6ee5e8..2cafbe8043 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "EU8Q0XLjED23MNer", "filament_id": "OFXiArjA", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 HF nozzle.json index 746eb1cc61..5493fc1566 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8x6yU2U8d5f67N73", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 nozzle.json index ecafe03349..92e11c5a7b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "4W0nfaSSZdg2HQkh", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.8 HF nozzle.json index 94b757887a..ef509a6e8d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "AJcugKx4qHPJ3JAT", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 HF.json index 8308064c52..ccd4fedb6e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "R0nZuLXEo5qA6Mt8", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4.json index 8c1de1d947..c2ac1bc1f1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Ql2BBBymzqEG7GKk", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 HF nozzle.json index 60bb0ae243..f509ebd2e4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "KU5tDHAKja1sCoHm", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 nozzle.json index 24ed205273..83f839dc15 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "sb6jD3UZmb0DNIsC", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.8 HF nozzle.json index d993d05592..821f640057 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "4BB1wJLtsXus5eyY", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P HF.json index d8bdc53caa..bde4793410 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "m7oJx47UMlFctMkX", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P.json index 1bd2c4cdbf..c478014ab4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ozD2wU5UiORTtJsa", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Pro.json b/resources/profiles/Flashforge/filament/Flashforge PETG Pro.json index df9948d863..ca41082534 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Pro.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Pro.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "IQfUoy7gTmVmBDL5", "filament_id": "OFXiArjA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "60" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.6 nozzle.json index 2d29ad79b5..ec4cbe4150 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Ht7wzk8l0b1kv5tZ", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.8 nozzle.json index f1b7a3b4ab..8b1521d82b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "NJFHpa5HFHIyHSWu", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X.json index 252e51750d..b96a53dc08 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "UaObrRNSTwitC6jr", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "close_fan_the_first_x_layers": [ "2" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF Adventurer A5.json index 15ccd1d0ac..864e757268 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "axOWrjnN5lofH9qM", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "60" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5.json index ed8c6fd0bb..6b931f2732 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "TtXy042wtT6nF3WB", "filament_id": "OFwjMiKL", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5P.json index b6395b0325..34271c74c7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "66OWHhGyuaFISu6v", "filament_id": "OFwjMiKL", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 HF nozzle.json index 2ab27e8567..0b2fa34dcb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "K8WkJmFy2V1zhYQO", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 nozzle.json index b3c10e9970..723bd68852 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "LLK1hwKZhDU8SaGJ", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.8 HF nozzle.json index 8c29f5a466..840424a6ca 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "LaUF2HJtBnpZF7Cd", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 HF.json index f38a075dea..3e4dd0451e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "OUToXk8ddS1RPPUK", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4.json index d907e48ab5..f4204e031e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ywff8rI39XKjcocY", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 HF nozzle.json index 0dfa3dfee2..5c61d8dfde 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "kuCvwo6Phr6Ywhm4", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 nozzle.json index 91c49b1c85..cbb85f11e4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Z2E69w9AevYg15tl", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.8 HF nozzle.json index 0ac80ad83a..5ea183e50c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "RkQaxwTjhJK0A3zr", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P HF.json index c920f757e5..dbfc255ff1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YBQTMes2S9iJjKDf", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P.json index 0213d9e14b..e454323a33 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "lCngVWG3q0FWsnrG", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent.json b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent.json index 7502aa35b6..7e7beee06e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG Transparent.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG Transparent.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "3Gv6MJ3RRja5pbOM", "filament_id": "OFwjMiKL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "60" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.6 nozzle.json index a516f371a2..4b02af402f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "bcqYod61blJRzhK2", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.8 nozzle.json index 7a51f2615a..3218ae7e22 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "CnFKOi7fFyS8QlKK", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X.json index e401baa389..eaa57a517b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "eKWJW36I5fVHwjWD", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF Adventurer A5.json index c4001061f2..e257f61b10 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "aDSOS4PWssYHk8Fh", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5.json index 52901dd534..3e0640128f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "RXRERfs2oQKewpPS", "filament_id": "OFuFEtKX", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 0.4 nozzle", "Flashforge Creator 5 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5P.json index dda9226bcd..59da2d552d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "8Ns75F5n2fdQ8sDk", "filament_id": "OFuFEtKX", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "compatible_printers": [ "Flashforge Creator 5 Pro 0.4 nozzle", "Flashforge Creator 5 Pro 0.6 nozzle", diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4 0.6 nozzle.json index 71c68991d0..b01dc6e877 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "4EgMPzlVo1rTeQ1e", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4.json index b0b2ec7360..7106a199cd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "K9ME1F4oJkPi8jRu", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P 0.6 nozzle.json index 668e1af37a..67e4d0bcf4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "9jCp0gTjB3Mt95Mj", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P.json index a0200ebe49..1f40be2ec7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "d5OleuNNZBJK9vxH", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PETG-CF.json b/resources/profiles/Flashforge/filament/Flashforge PETG-CF.json index 57b297768c..4c6b3b130c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PETG-CF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PETG-CF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "MpG61mwVUtJ7t602", "filament_id": "OFuFEtKX", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PETG-CF" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.6 nozzle.json index 7c929b1363..044604a134 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "gMmhMDqjmJfAYcbV", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.8 nozzle.json index 7f66423bbe..98b2473f4c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "0OsrtqfIxrEJMwac", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X.json index f698b05b32..f0d25bf349 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "fuzWVrfZqekMETLK", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF Adventurer A5.json index 6fdc1bdb17..87760ea716 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "HCpI817HAWckXBtk", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5.json index 6893946556..60befa66ee 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "FmUnckQofjunAtwr", "filament_id": "OFJ3F2jm", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5P.json index 9a7c7080a0..aaac7134ad 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "Q0RsVOPLuMByur9c", "filament_id": "OFJ3F2jm", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 HF nozzle.json index 4ed8203529..7d6df18572 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "R54l7TcwsjdPHvNB", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 nozzle.json index 731b59748d..2a32b29f00 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "MELEwYupDkT2DPxL", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.8 HF nozzle.json index 24eb70b646..c740682350 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "uGLvOoPAfksLO43M", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 HF.json index b9ab2a97ec..232a7294d8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "gGpKvk3rnLuTjOwo", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4.json index 2d81ff10df..fb1e3faa7d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Yopqnj4b5ZVwigGx", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 HF nozzle.json index 9c6d20e0e0..32ff549bb5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "QEfQrqMwApuSMqih", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 nozzle.json index 1285b05257..61c89f8c95 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "BAPIn3eJAPGpscRJ", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.8 HF nozzle.json index 784f6dfd17..be05a3d90e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "44BmRNRb6vlPq8qe", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P HF.json index 4fdcf94869..aa5960059f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ltJbhoAeAec9gxrS", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P.json index 57305d4cc5..736c0f4a41 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "GxdZiXdqns72ibQl", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Basic.json b/resources/profiles/Flashforge/filament/Flashforge PLA Basic.json index 12a8f6cd79..48c4ec6983 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Basic.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Basic.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "5XKGaHUjxHECbnHO", "filament_id": "OFJ3F2jm", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Basic" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.6 nozzle.json index 4f5eca6889..445ea80872 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "TF6BeOl0patjpPaa", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.8 nozzle.json index 950effa7cd..b6fbfe419b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "nkYeEBo8NdkJulAP", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X.json index bf6dfb230f..2cce8c7bd8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "yEDfsOsogfZbNBVX", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF Adventurer A5.json index 2eeb85526c..8547fa026a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "o1Fl6t8nFCKZoj3Q", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5.json index 23bfa9be0c..95b8e02fad 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "xZmQdh487UMtvBRu", "filament_id": "OFMkAW6r", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5P.json index 6f5e1afb0e..d1871c007d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "rc00SOyIg30uE3Da", "filament_id": "OFMkAW6r", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 HF nozzle.json index 31a99ea10e..6448467d0e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "G2Et7kPHptMESzQ0", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 nozzle.json index 07fe12f973..06de5aed71 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "zsOdmFGBSF9UySMN", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.8 HF nozzle.json index 3a778e5472..ed80aad827 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "oxRMuvBMu9qdQWUQ", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 HF.json index 8657a4010e..f644a8ab18 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "5hwNJvvLtb75XBBg", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4.json index c185b26f3d..9b06bfcd58 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "mGj8VEyOnnogpkmF", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 HF nozzle.json index 9742b8aefc..fd5370bf4a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "JDcRA6apekWLXPvH", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 nozzle.json index 4d3681736e..79fd7a6636 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "b5GJpvKYktP4vZpj", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.8 HF nozzle.json index 6eb75a8f52..f4057e2860 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "RjUpQV6iQxTircwj", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P HF.json index 26609fd995..1f181537a2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "9DEZ6SmFdgfluhsR", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P.json index e660d0f569..b5528cac52 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "girTMkusNTfY04rz", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change.json b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change.json index 29f68b0f62..c216b7fd22 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Color Change.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Color Change.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "pCQ2qmeXUyJzP7kS", "filament_id": "OFMkAW6r", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Color Change" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.6 nozzle.json index d66bf2b24c..7b10963fef 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "y8TNaRebTrmFem10", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.8 nozzle.json index 65dffd3601..37c76958e0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "qju0AMvvq0B5Glny", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X.json index 1067b50067..b49adc2988 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "o8gGBOEcNvlbZxGW", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF Adventurer A5.json index a833b55331..2347ddf9ad 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "4rpfTTgZrsVDwxI9", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5.json index 2ce8486cb0..407744a897 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "0RkkIcIUFgwOFTBY", "filament_id": "OFJJ0Ar3", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5P.json index 373a81bcdc..7320f6e19c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "9qVabnSl8xfKSIYX", "filament_id": "OFJJ0Ar3", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 HF nozzle.json index efb7dad130..3bb954210b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "koEC7DteUoXHUd2z", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 nozzle.json index 64b442938c..70e94be7c1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "D69fWcXioFcpoUjC", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.8 HF nozzle.json index d20dc55d41..5b3136029c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "rfiQUncdSExEaK0U", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 HF.json index 346dfad0a0..7415d88645 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "WX8lK8efXIVcpjFf", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4.json index 3b999c0734..139be55915 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Tzvo3oILQJc4SQko", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 HF nozzle.json index 1b8e75eb32..93387df7e9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Y5gm20O4yCCDIoC0", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 nozzle.json index d39114697f..9b2d3bdae3 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "80vSQxnHfd5ZUy5h", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.8 HF nozzle.json index 185440fba4..d8cc2481f4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "UZi7T5VoasmXWyH5", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P HF.json index ec0581df11..265b4f865c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "6UlSb4fqHIMdMxkO", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P.json index c1818186cb..8a87da7aab 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "H2Cr4B5VUaxyYsN0", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy.json b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy.json index 785e26ace5..4e7bc2c581 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Galaxy.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "NJrc0UZ54Fq8MaqF", "filament_id": "OFJJ0Ar3", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Galaxy" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA LITE @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA LITE @FF Adventurer A5.json index 36e0a64d69..dc00b7b598 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA LITE @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA LITE @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "2QZaQyg66IJPbsSc", "filament_id": "OFDDdgHM", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.6 nozzle.json index 3e106a6eda..301ed1b8c0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "GdvXL8SrKrYHxSgZ", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.8 nozzle.json index 446137267f..9074bdd547 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "SLYD2YcQTQgbSjIF", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X.json index d605b1e444..3d1da264d5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "kOobFSlqEG9Qe0d1", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF Adventurer A5.json index 0be02b85f5..c81af34a7c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "GqNeJoH4M1IVAXrZ", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5.json index 5efeada6af..66fc70e7ed 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "4sE1LTVVuRglRbpD", "filament_id": "OFdqkWtz", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5P.json index 485a3b51a2..d69b537c6a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "jEUZyaEIBf2eXXeh", "filament_id": "OFdqkWtz", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.6 HF nozzle.json index 0b58399215..1f8feef089 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "xPPSRmadqfqCtRF2", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.8 HF nozzle.json index 792049300a..e3a3fc5ee1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "aWVXIk1xVa9URR1D", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 HF.json index a218752f68..93632d0992 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "KhBF7hHHVPzqiAca", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4.json index 615e05d2e6..d570838ab4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "sTplnj3gMAzwtLWE", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.6 HF nozzle.json index 65e6995584..bb66eccb3a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vXPXOKD8vNJlujM1", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.8 HF nozzle.json index 7704d5f2b8..9a99a237a3 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "purqxjmWiflDrnik", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P HF.json index b9f94e604e..f11ea26336 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "qraQ97uusigB63hv", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P.json index 5ce6582146..d96d107b83 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Z1NCX8XMyIVlOlWn", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous.json b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous.json index 46151a4496..7228ed0f99 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Luminous.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Luminous.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "s620OFLTgFT4Ds2A", "filament_id": "OFdqkWtz", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Luminous" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.6 nozzle.json index 2774450e57..32ec6b37ec 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "BVmVfNCuy8HDhcEI", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.8 nozzle.json index f03dc70fd1..0fa484f6b6 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "WRMePGzDGdEGiqNv", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X.json index f009759cad..f6b304da2b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "thnbuaLDDlGrkrdY", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF Adventurer A5.json index 33a2228f8d..cc0a51eacf 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Jk7PRQkF2lFEtI8Q", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5.json index 230a723624..a9637b4b2d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5.json @@ -1,15 +1,18 @@ { "type": "filament", "name": "Flashforge PLA Matte @FF C5", - "inherits": "Generic PLA @System", "renamed_from": "Flashforge PLA Matte @FF C5;Flashforge PLA Matte FF C5", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "ct3nO6w9j58gqDI0", "filament_id": "OF6qAuyi", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5P.json index 0d7543cc09..8386a4424a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF C5P.json @@ -1,15 +1,18 @@ { "type": "filament", "name": "Flashforge PLA Matte @FF C5P", - "inherits": "Generic PLA @System", "renamed_from": "Flashforge PLA Matte @FF C5P;Flashforge PLA Matte FF C5P", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "Bn2BaG7f1tkvlyYI", "filament_id": "OF6qAuyi", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 HF nozzle.json index 2ff2a07363..d3df0a765c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8b9q1FfVljPmKoEt", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 nozzle.json index f49e19c292..7263fb66b5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "o9dOrLgL6efF19O1", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.8 HF nozzle.json index 98e44f21f4..7036ec3ffa 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "QoRmDvhoeGi6Z2xv", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 HF.json index 7eda7a4b62..599e8dc771 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "dHyuoORAUGLtlGkJ", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4.json index 698511967d..a8c257fea1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "OgqVyIHfy3U8Dc6d", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 HF nozzle.json index c868aa0137..2e8676a2a2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "feXpVbDM5ON5mwg0", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 nozzle.json index fc205bb684..5f9ff2e3bb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "XMnZQ1AxXPJqpqRX", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.8 HF nozzle.json index 42dc4c9c15..ef6c9b3010 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Ke0bRKPNKSsVMO1Y", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P HF.json index 1d76131870..0345d9b8a4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "IRC2n4GaofxvvyTt", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P.json index 63d6f372e3..661fd7e800 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "RN4wdTL0qccM4huZ", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Matte.json b/resources/profiles/Flashforge/filament/Flashforge PLA Matte.json index 781357b1a1..b747e3a26b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Matte.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Matte.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ipMevDMORKqZYdvD", "filament_id": "OF6qAuyi", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_max_volumetric_speed": [ "22" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.6 nozzle.json index 27caf06739..33f787d3d3 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "uusF7Vz94HOwoQF0", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.8 nozzle.json index 4f01562a04..2e3bd9c33a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "sHZWzrZO8PP0QYZR", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X.json index f85391cb2b..6bec10ee8d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "bxwjEFI8HmNY8JI6", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF Adventurer A5.json index 1ef06a756b..4cd41a44f7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Gs8hS5CpV3W62pjs", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5.json index d382637556..35fa843ada 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5.json @@ -1,15 +1,18 @@ { "type": "filament", "name": "Flashforge PLA Metal @FF C5", - "inherits": "Generic PLA @System", "renamed_from": "Flashforge PLA Metal @FF C5;Flashforge PLA Metal FF C5", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "AdjRSTc9RZG6mJ1e", "filament_id": "OFAebKg8", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5P.json index 965b6fe595..fc69dcf2a2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF C5P.json @@ -1,15 +1,18 @@ { "type": "filament", "name": "Flashforge PLA Metal @FF C5P", - "inherits": "Generic PLA @System", "renamed_from": "Flashforge PLA Metal @FF C5P;Flashforge PLA Metal FF C5P", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "k0AQO2dGbk0qvxzO", "filament_id": "OFAebKg8", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 HF nozzle.json index 8fcf56e6b6..b50b30e1fd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "5xqdqoj2l50FegPF", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 nozzle.json index 352adaa681..6e8d01fc22 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "R79SbWA9i2OAu2ee", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.8 HF nozzle.json index 8d78236629..422abb7e48 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "zjIN4KzIOwI1VwOc", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 HF.json index aaabcaac60..8fbedcac7d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "UxMNNil2KnWvAJ4q", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4.json index b1035a4629..53c81cc9df 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "57i6iKrVYUS5UiBT", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 HF nozzle.json index bf06971c23..2ce77f2098 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "IYPw8a9tkpuf95uH", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 nozzle.json index 7d85d6e56f..5be845c3cb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "I0bULoVAbtVfQoCy", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.8 HF nozzle.json index 9c6e1b92b0..cb7ca9ce1e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "DbPo3ay2e4a002AB", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P HF.json index a79ce03a5b..d386502160 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "uztv4hhm2O3T93zZ", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P.json index 82bf12c247..948e047ffa 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "UFWWrhfgS7N36Y8W", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Metal.json b/resources/profiles/Flashforge/filament/Flashforge PLA Metal.json index 90d419bfa5..4110cc586c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Metal.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Metal.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "UD5i0ijsirfieUvb", "filament_id": "OFAebKg8", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Metal" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.6 nozzle.json index d56ed06c1e..38e48d781b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "t9lPSFnwLDk0ARIp", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.8 nozzle.json index 423b8743a7..db4ee0563d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "SBSlOEwZSvZHeX4r", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X.json index 0ab1f650f2..92cf8d55ab 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "DbWTm2H71izMWmpx", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF Adventurer A5.json index 416c8bf207..5f2a38e02c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vTVCr1id0cTtMzuE", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5.json index e02f21dbd3..668707306e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5.json @@ -1,15 +1,18 @@ { "type": "filament", "name": "Flashforge PLA Pro @FF C5", - "inherits": "Generic PLA @System", "renamed_from": "Flashforge PLA Pro @FF C5;Flashforge PLA Pro FF C5", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "30eBjTZFg6vDZkc0", "filament_id": "OFm4SivL", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5P.json index fedd74b2c5..0805a77333 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF C5P.json @@ -1,15 +1,18 @@ { "type": "filament", "name": "Flashforge PLA Pro @FF C5P", - "inherits": "Generic PLA @System", "renamed_from": "Flashforge PLA Pro @FF C5P;Flashforge PLA Pro FF C5P", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "xOvxorpWP37CQCfi", "filament_id": "OFm4SivL", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 HF nozzle.json index f3dd8e04cf..6012a3cc75 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YcXuvz3qYHtVoWxv", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 nozzle.json index 7dc8528606..6fa23af370 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "prItyXNphhuPCAce", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.8 HF nozzle.json index 57e815ab25..9d518f1c67 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "83zDmjaAgxxIt7KU", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 HF.json index 35bce9d866..31e86195bd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "px3O28Olb9LExqfT", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4.json index b04f49d81b..a86a8d4c73 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "QYgsCCHP3Khqrzh3", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 HF nozzle.json index 07b82edf7f..390ccaa53f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "1ro9wHPYhuMHNiYe", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 nozzle.json index 433318fc86..d4829bab74 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "4W4a7c9ugUVwvvmn", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.8 HF nozzle.json index 87031ba66b..3902337856 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "CloRo3qxvzxHZuIP", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P HF.json index 281a34a2c5..6f89effb8d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "QgUbP07tIXmFysEb", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P.json index 8d29d1823c..d5b49f18eb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "6mvGOtkPZT6ROboo", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Pro.json b/resources/profiles/Flashforge/filament/Flashforge PLA Pro.json index e70b87f9a9..cf0dd71a81 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Pro.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Pro.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vI875WYbMyQeMwlh", "filament_id": "OFm4SivL", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Pro" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5M 0.25 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5M 0.25 nozzle.json index b232f00632..1005ecbcf0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5M 0.25 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5M 0.25 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "gxl3i7jTwkzrKxF4", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Silk @FF AD5M 0.25 nozzle" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.6 nozzle.json index 3bbc1afcb1..ac59ca225a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YH9IHXOFMKwcTLyA", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.8 nozzle.json index 36a3c15a4f..2a55fcc117 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "IfAieG0OAG807xlu", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X.json index ce5ecdb2aa..db75066f14 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "N6J7QqQ7TIgM3MyW", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "50" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF Adventurer A5.json index e157b16c6d..5c7f51a024 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "XXmeUWaLyVCTDS6G", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5.json index de9c9be46a..4ff076c635 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "OIsfpi49wEoF0ekO", "filament_id": "OFgjgN35", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5P.json index f82bc5efc4..996e0c3052 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "xxeZ6VPjRFevxDnK", "filament_id": "OFgjgN35", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 HF nozzle.json index ec7a71f35f..b1de1db0c9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "2GZp8yjrY1OioFDi", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 nozzle.json index 36090afaf7..fff6e7d313 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "U0XtCVUhIMnidhbR", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.8 HF nozzle.json index 558015cb87..777fd93940 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8j9kaYy3ghkF81Cu", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 HF.json index c37e0f6341..7286eca6aa 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "E0LeJwSxaniDkB0b", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4.json index b7f4f619ec..46a4b9e268 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8rggqgJ9kg9yLE28", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 HF nozzle.json index 047cdcf879..df57e3437e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "uY4OWhIytHMz4rWq", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 nozzle.json index b5f36b7483..dcd315eb34 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YSkkXd9EhhEHvGpf", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.8 HF nozzle.json index a41d10e40a..c2b25925c5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "XlxXZj9Wi1D6IwCE", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P HF.json index e95f7ad1de..fd347929e6 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "IPyXBSnMCAikjI9V", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P.json index df4894cdb1..d11fb0e157 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "f3gJsovSmDKoA7BP", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Silk.json b/resources/profiles/Flashforge/filament/Flashforge PLA Silk.json index 15239129d4..5f4826c112 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Silk.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Silk.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vZb7BvbyVWkZv3rR", "filament_id": "OFgjgN35", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Silk" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.6 nozzle.json index 3786cf7abb..6c0baf8308 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "o8lsEnMIiHHorJhb", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.8 nozzle.json index c7fb93bca2..017caafcf1 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "oXlxQJY0K6Dnri7e", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X.json index b6802db1b4..834976ea9a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "XKpFulrvvrfE56va", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF Adventurer A5.json index b7954c6677..f9983c2e2e 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "dscnwSfbrGWiS4Um", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 HF nozzle.json index 5cf32f2c38..1871eeddf9 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "yeh5cd0tAHtHzdoQ", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 nozzle.json index 27380eb9e7..4a227d08f0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "q2Zi0YluaYpG3Ktf", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 HF.json index 42df4a0ea9..60e1fa25d4 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4 HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "1qXV6AJqPpAwX1YK", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4.json index 7a11476c06..dd14fdd6ce 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YsyGGOGqUVkEqkIr", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 HF nozzle.json index 4a975e6f20..044d335abb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "UVvd018dTbygqTgy", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 nozzle.json index 0781dd641f..a064b07063 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "F0k8kkgWM5FkLAzo", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P HF.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P HF.json index 9b4065c982..0b5677dffd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P HF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P HF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Oapl8InwbkwNSIDl", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P.json index 35ccf42632..65552aff78 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "NiB6Yb4b0auyn9KQ", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle.json b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle.json index 4be3dba6ea..5f91c27894 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA Sparkle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "LYtdPgec1hBLhoQA", "filament_id": "OFV5c8hG", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA Sparkle" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.6 nozzle.json index 245e401283..a6f9bfe060 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "QRyISvTy06kCwxKo", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.8 nozzle.json index f456d8c7db..0fe961c8dd 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "rmnF24E3SuwzRscH", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X.json index a39646f621..c167401434 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "BXPI5Pkp7a6pLrCh", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF Adventurer A5.json index 542045cdeb..6589ef2776 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "EpC2ItdGUxFV7x1y", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5.json index a1b271569e..ef53b045ca 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "rBm25DRY1PAkEJ4r", "filament_id": "OF9cAwMK", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5P.json index 189dba715a..4860f2c41f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "xReo12oteZ4ECNJN", "filament_id": "OF9cAwMK", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4 0.6 nozzle.json index 292cf5972c..34eec41e5c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "9PgjgxU7pLl2Dfpe", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4.json index 0faba78623..0a3aff8808 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "RuNKzuIsw7F1ogmG", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P 0.6 nozzle.json index 77a590f1d6..036e937e59 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "YPuMCHNGDWh0FpIB", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P.json index 3bd2e72000..5c2741e7a0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "3uC056Y171ZjnQE6", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-CF.json b/resources/profiles/Flashforge/filament/Flashforge PLA-CF.json index 10f87a860a..418e644f56 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-CF.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-CF.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "JxNlb64lTODaaQhU", "filament_id": "OF9cAwMK", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge PLA-CF" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PLA-SILK @FF AD5M 0.25 Nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PLA-SILK @FF AD5M 0.25 Nozzle.json index 4242f0f8a5..315d522084 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PLA-SILK @FF AD5M 0.25 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PLA-SILK @FF AD5M 0.25 Nozzle.json @@ -4,10 +4,10 @@ "inherits": "Generic PLA-Silk @Flashforge", "from": "system", "filament_id": "OFV8Mxqx", + "instantiation": "false", "filament_vendor": [ "Flashforge" ], - "instantiation": "false", "compatible_printers": [ "Flashforge Adventurer 5M 0.25 Nozzle", "Flashforge Adventurer 5M Pro 0.25 Nozzle" diff --git a/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5.json index e559b22a88..cef2cbbfa0 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5.json @@ -6,6 +6,9 @@ "setting_id": "DhC7iFgNKCAq4Zkt", "filament_id": "OFLC1oRH", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5P.json index 96fa32ad12..25ecaebd67 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPA-CF @FF C5P.json @@ -6,6 +6,9 @@ "setting_id": "Jws2AaLWaNyZhqX4", "filament_id": "OFLC1oRH", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 HF nozzle.json index 3df5398f11..11277a4ffa 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS @FF G4 0.6 HF nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS @FF G4 0.6 HF nozzle;FlashForge PPS FF G4 0.6 HF nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "5x1ye2DAm3GvzmZJ", "filament_id": "OFlgMgNM", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 nozzle.json index 1de4d51745..5eced86546 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS @FF G4 0.6 nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS @FF G4 0.6 nozzle;FlashForge PPS FF G4 0.6 nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "yZoLC24CeKEyvkgA", "filament_id": "OFlgMgNM", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.8 HF nozzle.json index e8014ddfec..c43b7b3290 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4 0.8 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS @FF G4 0.8 HF nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS @FF G4 0.8 HF nozzle;FlashForge PPS FF G4 0.8 HF nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "EsrSpDB3Kx35qb76", "filament_id": "OFlgMgNM", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4.json index fd2f854067..1aab3f1755 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "6NjEQ6RJKUAOrSLw", "filament_id": "OFlgMgNM", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 HF nozzle.json index f731181d65..fd9323cc7d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS @FF G4P 0.6 HF nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS @FF G4P 0.6 HF nozzle;FlashForge PPS FF G4P 0.6 HF nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "Uu82gm86ESeidnRT", "filament_id": "OFlgMgNM", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 nozzle.json index 3eab34befc..ef12c6a66d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS @FF G4P 0.6 nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS @FF G4P 0.6 nozzle;FlashForge PPS FF G4P 0.6 nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "G6pIMZA5RC15kJoC", "filament_id": "OFlgMgNM", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.8 HF nozzle.json index a2662d8cc9..7c48a9f82a 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P 0.8 HF nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS @FF G4P 0.8 HF nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS @FF G4P 0.8 HF nozzle;FlashForge PPS FF G4P 0.8 HF nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "SsK15iSJxrQWI5wy", "filament_id": "OFlgMgNM", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P.json index b841f62e6c..294fe8d4eb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "vFMKqNjQjlNxwvDI", "filament_id": "OFlgMgNM", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_chamber_temp_control": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5.json index 58b2d242a8..ce58dc7c7f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5.json @@ -6,6 +6,9 @@ "setting_id": "ihXPnFERMjbBgrP5", "filament_id": "OFTSXxzE", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5P.json index 5f261953b3..7b8cab5254 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF C5P.json @@ -6,6 +6,9 @@ "setting_id": "UWFjBmSpUkZLBvoO", "filament_id": "OFTSXxzE", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4 0.6 nozzle.json index b33fcb95c9..0ca1140813 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS-CF @FF G4 0.6 nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS-CF @FF G4 0.6 nozzle;FlashForge PPS-CF FF G4 0.6 nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "mMTi9QaW5xVch3an", "filament_id": "OFTSXxzE", diff --git a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4P 0.6 nozzle.json index 48edb216c5..fabbaf7068 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge PPS-CF @FF G4P 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Flashforge PPS-CF @FF G4P 0.6 nozzle", - "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "renamed_from": "FlashForge PPS-CF @FF G4P 0.6 nozzle;FlashForge PPS-CF FF G4P 0.6 nozzle", + "inherits": "FusRock PET-CF @G3U 0.6 Nozzle", "from": "system", "setting_id": "dSI79hoaa9jLGvhz", "filament_id": "OFTSXxzE", diff --git a/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5.json index 90d94b9c29..ca3216eef5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "rSYGG2ni41NDVw6l", "filament_id": "OFaaddbQ", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5P.json index 03fdb6117e..6348ec601f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge PVA @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "nwgbMjLRJLtJ04ri", "filament_id": "OFaaddbQ", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge R PLA @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge R PLA @FF Adventurer A5.json index e5511d5622..c17d507b4f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge R PLA @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge R PLA @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "sN7eGcbuGZxGrbR5", "filament_id": "OFT02Lz9", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 HF nozzle.json index 1514862e44..725349ad2d 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "f75oElm4zB0hukIj", "filament_id": "OFSDfduA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 nozzle.json index d6fda96505..7298c982fe 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "o4KYTpJF6KksX2mg", "filament_id": "OFSDfduA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.8 HF nozzle.json index 27d6515ccb..9c710563ed 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "HUSkDZL6rCpz0lRk", "filament_id": "OFSDfduA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 HF nozzle.json index 7db519170a..f96b992d49 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "8xgu0AnMuKbPWyVd", "filament_id": "OFSDfduA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 nozzle.json index 2123c33993..73df34ec44 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "Rgqt3MjxOye5EaFt", "filament_id": "OFSDfduA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.8 HF nozzle.json index a5ce644702..65e0df12a8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 65D @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "PBFsW5qhVbQteYh5", "filament_id": "OFSDfduA", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.6 nozzle.json index 897054d8ee..7fd3fce86f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "TPbHmcFyPyjvoERv", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.8 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.8 nozzle.json index adb4820faa..474c793788 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.8 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X 0.8 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "zLMgsyDmdoXHhqFv", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X.json index 5c5f690cd2..8233c9eab7 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF AD5X.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ThakVhjfpgnAlEVH", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF Adventurer A5.json index 19b0981798..e8c9ee8f67 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "2MT9C2rvvQ3uU1lG", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "cool_plate_temp": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 HF nozzle.json index b67887cc8b..b244df24ce 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "M0ozqaD3jSKoD6fm", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 nozzle.json index ae6049673b..fd12c0a3e8 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "ob8IkvzNt9CWCzbk", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.8 HF nozzle.json index 37bef9c3f6..792a504a01 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "NzxX1lyRJ7wLUihV", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4.json index c5b24e9e04..083214475b 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "4FIGiheSGvSJPw3s", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 HF nozzle.json index 23cd8d6326..0ebf8ad04c 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "1GNqSBaQitzhYSx7", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 nozzle.json index eb2a423bca..441792c4d5 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.6 nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "eOhMygyxaccdov7o", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.8 HF nozzle.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.8 HF nozzle.json index f4b91222e7..5e41834400 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.8 HF nozzle.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P 0.8 HF nozzle.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "LxooKiOkRncktNLf", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P.json index 9e675ccd52..656106c830 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A @FF G4P.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "HdoJfbQr0uwQ6Vwb", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU 95A.json b/resources/profiles/Flashforge/filament/Flashforge TPU 95A.json index aa2f6251dc..1d1ea62a65 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU 95A.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU 95A.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "J4EaFhnpkLDcl5wH", "filament_id": "OFSqIcJC", + "instantiation": "true", "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "filament_settings_id": [ "Flashforge TPU 95A" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5.json index 5a4e304862..7098dd4ac2 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "fd5bACFa33J7aTdp", "filament_id": "OF8GtyKJ", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5P.json index 428afe7f1c..80b1f9964f 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU-64D @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "hrcELA2qEMkZ6Wvj", "filament_id": "OF8GtyKJ", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5.json index 407e92aed8..6faa7d3a58 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "Lis7BZ3lMkoX5KQt", "filament_id": "OFwlZ7gH", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5P.json index 611724b460..a2dc8ab5fb 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU-90A @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "xY03Hiidu5YNSUyZ", "filament_id": "OFwlZ7gH", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5.json b/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5.json index 0c27bb94c6..69e930a3ff 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "AHu6wNV3zcPBusOF", "filament_id": "OFx0WlzS", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "additional_cooling_fan_speed": [ "40" ], diff --git a/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5P.json b/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5P.json index e3b05721e6..bf11fa31ae 100644 --- a/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Flashforge TPU-95A @FF C5P.json @@ -5,10 +5,13 @@ "from": "system", "setting_id": "8MBRqfLIRdhxk1dF", "filament_id": "OFx0WlzS", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Flashforge" ], - "instantiation": "true", "activate_air_filtration": [ "1" ], diff --git a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5.json b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5.json index 5ad0cca8f6..31c5d807d4 100644 --- a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5.json +++ b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5.json @@ -1,12 +1,15 @@ { "type": "filament", "name": "FusRock PAHT-CF @FF C5", - "inherits": "Generic PA-CF @System", "renamed_from": "Flashforge PAHT-CF @FF C5;Flashforge PAHT-CF FF C5", + "inherits": "Generic PA-CF @System", "from": "system", "setting_id": "gZqAGVOlWR79n7hN", "filament_id": "OFKW5hEW", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "FusRock" ], diff --git a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5P.json b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5P.json index b23f871add..952f16aa4e 100644 --- a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5P.json +++ b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF C5P.json @@ -1,12 +1,15 @@ { "type": "filament", "name": "FusRock PAHT-CF @FF C5P", - "inherits": "Generic PA-CF @System", "renamed_from": "Flashforge PAHT-CF @FF C5P;Flashforge PAHT-CF FF C5P", + "inherits": "Generic PA-CF @System", "from": "system", "setting_id": "nJF1lCOavNNh4yHs", "filament_id": "OFKW5hEW", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "FusRock" ], diff --git a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4.json b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4.json index 2fb2e00e21..0a963b57ac 100644 --- a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4.json +++ b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock PAHT-CF @FF G4", - "inherits": "Generic PLA-CF10 @Flashforge", "renamed_from": "Flashforge PAHT-CF @FF G4;Flashforge PAHT-CF FF G4", + "inherits": "Generic PLA-CF10 @Flashforge", "from": "system", "setting_id": "nH6pwFYsPyBzL1EB", "filament_id": "OFKW5hEW", diff --git a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4P.json b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4P.json index 263323a60a..d4f32a7962 100644 --- a/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4P.json +++ b/resources/profiles/Flashforge/filament/FusRock PAHT-CF @FF G4P.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock PAHT-CF @FF G4P", - "inherits": "Generic PLA-CF10 @Flashforge", "renamed_from": "Flashforge PAHT-CF @FF G4P;Flashforge PAHT-CF FF G4P", + "inherits": "Generic PLA-CF10 @Flashforge", "from": "system", "setting_id": "wmWMf3MfmbfZx2o8", "filament_id": "OFKW5hEW", diff --git a/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5.json b/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5.json index c5d429456d..e76983e211 100644 --- a/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5.json +++ b/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5.json @@ -6,6 +6,9 @@ "setting_id": "O3tz36NNMoagELL0", "filament_id": "OF0AquDh", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "FusRock" ], diff --git a/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5P.json b/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5P.json index bb1ccc7292..5ee5ad5303 100644 --- a/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5P.json +++ b/resources/profiles/Flashforge/filament/FusRock S-Multi @FF C5P.json @@ -6,6 +6,9 @@ "setting_id": "Gg9H6I32fOqoLSqE", "filament_id": "OF0AquDh", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "FusRock" ], diff --git a/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5.json b/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5.json index b895fd4370..148f941f09 100644 --- a/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5.json +++ b/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5.json @@ -6,6 +6,9 @@ "setting_id": "pV5QERvRuROIZTOa", "filament_id": "OFCn83wF", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "FusRock" ], diff --git a/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5P.json b/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5P.json index 6845961090..1237e3d98b 100644 --- a/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5P.json +++ b/resources/profiles/Flashforge/filament/FusRock S-PAHT @FF C5P.json @@ -6,6 +6,9 @@ "setting_id": "0i7VkquM4n0uFaXH", "filament_id": "OFCn83wF", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "FusRock" ], diff --git a/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-CF @G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-CF @G3U 0.6 Nozzle.json index b1112d508d..2ac906fb34 100644 --- a/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-CF @G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-CF @G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock PAHT-CF @G3U 0.6 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "FusRock Generic PAHT-CF @G3U 0.6 Nozzle;FusRock Generic PAHT-CF G3U 0.6 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "axB3SEA3AC7rmxiZ", "filament_id": "OFKW5hEW", diff --git a/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-GF.json b/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-GF.json index 0e29324831..6f2d0dddb1 100644 --- a/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-GF.json +++ b/resources/profiles/Flashforge/filament/FusRock/FusRock PAHT-GF.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock PAHT-GF", - "inherits": "FusRock PAHT-CF", "renamed_from": "FusRock Generic PAHT-GF", + "inherits": "FusRock PAHT-CF", "from": "system", "setting_id": "yJJEULB0ra4GAS8Q", "filament_id": "OFcVLpNA", diff --git a/resources/profiles/Flashforge/filament/FusRock/FusRock PET-CF @G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/FusRock/FusRock PET-CF @G3U 0.6 Nozzle.json index b82f7ef4a9..e0ee54b6b3 100644 --- a/resources/profiles/Flashforge/filament/FusRock/FusRock PET-CF @G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/FusRock/FusRock PET-CF @G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock PET-CF @G3U 0.6 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "FusRock Generic PET-CF @G3U 0.6 Nozzle;FusRock Generic PET-CF G3U 0.6 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "Gyw0XH6UtYQqtgx9", "filament_id": "OFDu1qE7", diff --git a/resources/profiles/Flashforge/filament/FusRock/FusRock PET-GF.json b/resources/profiles/Flashforge/filament/FusRock/FusRock PET-GF.json index 6a224aded2..c886d48276 100644 --- a/resources/profiles/Flashforge/filament/FusRock/FusRock PET-GF.json +++ b/resources/profiles/Flashforge/filament/FusRock/FusRock PET-GF.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock PET-GF", - "inherits": "FusRock PET-CF", "renamed_from": "FusRock Generic PET-GF", + "inherits": "FusRock PET-CF", "from": "system", "setting_id": "ZFIkUVZOklX8jUrT", "filament_id": "OFzwA5Z9", diff --git a/resources/profiles/Flashforge/filament/FusRock/FusRock S-Multi @G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/FusRock/FusRock S-Multi @G3U 0.6 Nozzle.json index 80f5577529..8ffe7ef103 100644 --- a/resources/profiles/Flashforge/filament/FusRock/FusRock S-Multi @G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/FusRock/FusRock S-Multi @G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock S-Multi @G3U 0.6 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "FusRock Generic S-Multi @G3U 0.6 Nozzle;FusRock Generic S-Multi G3U 0.6 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "HvimUHzfNcDRrUBq", "filament_id": "OF0AquDh", diff --git a/resources/profiles/Flashforge/filament/FusRock/FusRock S-PAHT @G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/FusRock/FusRock S-PAHT @G3U 0.6 Nozzle.json index 858da9c1bb..653f47de7c 100644 --- a/resources/profiles/Flashforge/filament/FusRock/FusRock S-PAHT @G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/FusRock/FusRock S-PAHT @G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FusRock S-PAHT @G3U 0.6 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "FusRock Generic S-PAHT @G3U 0.6 Nozzle;FusRock Generic S-PAHT G3U 0.6 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "JUiz70mbp7RRSPia", "filament_id": "OFCn83wF", diff --git a/resources/profiles/Flashforge/filament/Generic ABS @Flashforge G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/Generic ABS @Flashforge G3U 0.6 Nozzle.json index 0176ef471f..18dbc7b49c 100644 --- a/resources/profiles/Flashforge/filament/Generic ABS @Flashforge G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic ABS @Flashforge G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Flashforge G3U 0.6 Nozzle", - "inherits": "Generic ABS @Flashforge", "renamed_from": "Flashforge Generic ABS @G3U 0.6 Nozzle;Flashforge Generic ABS G3U 0.6 Nozzle", + "inherits": "Generic ABS @Flashforge", "from": "system", "setting_id": "tzuKCtXYbGw6WB2c", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Flashforge/filament/Generic ABS @Flashforge.json b/resources/profiles/Flashforge/filament/Generic ABS @Flashforge.json index a7cfc16967..0c7fdf561e 100644 --- a/resources/profiles/Flashforge/filament/Generic ABS @Flashforge.json +++ b/resources/profiles/Flashforge/filament/Generic ABS @Flashforge.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Flashforge", - "inherits": "fdm_filament_abs", "renamed_from": "Flashforge Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "CJXM3PoVEjf4kYnz", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Flashforge/filament/Generic ASA @Flashforge G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/Generic ASA @Flashforge G3U 0.6 Nozzle.json index 3ecb1b1c67..3213e52e71 100644 --- a/resources/profiles/Flashforge/filament/Generic ASA @Flashforge G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic ASA @Flashforge G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Flashforge G3U 0.6 Nozzle", - "inherits": "Generic ASA @Flashforge", "renamed_from": "Flashforge Generic ASA @G3U 0.6 Nozzle;Flashforge Generic ASA G3U 0.6 Nozzle", + "inherits": "Generic ASA @Flashforge", "from": "system", "setting_id": "9wfcw1ifKVGOXx5G", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Flashforge/filament/Generic BVOH @FF C5.json b/resources/profiles/Flashforge/filament/Generic BVOH @FF C5.json index 0e77a94bd8..11ca1a9d74 100644 --- a/resources/profiles/Flashforge/filament/Generic BVOH @FF C5.json +++ b/resources/profiles/Flashforge/filament/Generic BVOH @FF C5.json @@ -34,6 +34,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "3.5" ], diff --git a/resources/profiles/Flashforge/filament/Generic BVOH @FF C5P.json b/resources/profiles/Flashforge/filament/Generic BVOH @FF C5P.json index 6679b74a66..b6cd31a55a 100644 --- a/resources/profiles/Flashforge/filament/Generic BVOH @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Generic BVOH @FF C5P.json @@ -37,6 +37,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "3.5" ], diff --git a/resources/profiles/Flashforge/filament/Generic HIPS @Flashforge G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/Generic HIPS @Flashforge G3U 0.6 Nozzle.json index 84c43def44..0948b4b9a8 100644 --- a/resources/profiles/Flashforge/filament/Generic HIPS @Flashforge G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic HIPS @Flashforge G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic HIPS @Flashforge G3U 0.6 Nozzle", - "inherits": "Generic ABS @Flashforge", "renamed_from": "Flashforge Generic HIPS @G3U 0.6 Nozzle;Flashforge Generic HIPS G3U 0.6 Nozzle", + "inherits": "Generic ABS @Flashforge", "from": "system", "setting_id": "wsAmSziSQ4UEHucg", "filament_id": "OFsFon5l", diff --git a/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.6 Nozzle.json index 77095049c2..25366c54fb 100644 --- a/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Flashforge G3U 0.6 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "Flashforge Generic PETG @G3U 0.6 Nozzle;Flashforge Generic PETG G3U 0.6 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "ptfqxSWRVMFXRqzD", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.8 Nozzle.json b/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.8 Nozzle.json index f0ebbde186..f97a46088d 100644 --- a/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.8 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic PETG @Flashforge G3U 0.8 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Flashforge G3U 0.8 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "Flashforge Generic PETG @G3U 0.8 Nozzle;Flashforge Generic PETG G3U 0.8 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "UhrHMgzzppLirT8M", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Flashforge/filament/Generic PETG @Flashforge.json b/resources/profiles/Flashforge/filament/Generic PETG @Flashforge.json index b53946e06c..6cf3196412 100644 --- a/resources/profiles/Flashforge/filament/Generic PETG @Flashforge.json +++ b/resources/profiles/Flashforge/filament/Generic PETG @Flashforge.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Flashforge", - "inherits": "fdm_filament_pet", "renamed_from": "Flashforge Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "pd9YWgt8IGXdiiUV", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.6 Nozzle.json index a44330253e..85e6d41043 100644 --- a/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Flashforge G3U 0.6 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "Flashforge Generic PETG-CF @G3U 0.6 Nozzle;Flashforge Generic PETG-CF G3U 0.6 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "xYtwo7Ddkfh5PLIz", "filament_id": "OFoYSJKi", diff --git a/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.8 Nozzle.json b/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.8 Nozzle.json index 3f5f92e8bc..76d477a95e 100644 --- a/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.8 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic PETG-CF @Flashforge G3U 0.8 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Flashforge G3U 0.8 Nozzle", - "inherits": "Generic PETG @Flashforge", "renamed_from": "Flashforge Generic PETG-CF @G3U 0.8 Nozzle;Flashforge Generic PETG-CF G3U 0.8 Nozzle", + "inherits": "Generic PETG @Flashforge", "from": "system", "setting_id": "v3HCxK10mQARiRTZ", "filament_id": "OFoYSJKi", diff --git a/resources/profiles/Flashforge/filament/Generic PLA @FF C5.json b/resources/profiles/Flashforge/filament/Generic PLA @FF C5.json index 12f0d129bc..df25efccb9 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA @FF C5.json +++ b/resources/profiles/Flashforge/filament/Generic PLA @FF C5.json @@ -49,6 +49,9 @@ "filament_cooling_moves": [ "2" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_loading_speed": [ "10" ], diff --git a/resources/profiles/Flashforge/filament/Generic PLA @FF C5P.json b/resources/profiles/Flashforge/filament/Generic PLA @FF C5P.json index 0f9ccae55c..e7e3e0d186 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Generic PLA @FF C5P.json @@ -43,6 +43,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "18" ], diff --git a/resources/profiles/Flashforge/filament/Generic PLA @Flashforge.json b/resources/profiles/Flashforge/filament/Generic PLA @Flashforge.json index 2a7b642470..8c8984059c 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA @Flashforge.json +++ b/resources/profiles/Flashforge/filament/Generic PLA @Flashforge.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Flashforge", - "inherits": "fdm_filament_pla", "renamed_from": "Flashforge Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "keWbSonGBWos68ag", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5.json b/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5.json index 2087257bcb..18e926c6b1 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5.json +++ b/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5.json @@ -40,6 +40,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "12" ], diff --git a/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5P.json b/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5P.json index a5de4c8f4a..f2987ca9bf 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Generic PLA Silk @FF C5P.json @@ -43,6 +43,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "12" ], diff --git a/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.6 Nozzle.json b/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.6 Nozzle.json index af864f7f8e..cb0f27a120 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.6 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.6 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Flashforge G3U 0.6 Nozzle", - "inherits": "Generic PLA @Flashforge", "renamed_from": "Flashforge Generic PLA-CF @G3U 0.6 Nozzle;Flashforge Generic PLA-CF G3U 0.6 Nozzle", + "inherits": "Generic PLA @Flashforge", "from": "system", "setting_id": "3vXm1hn43igE1xww", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.8 Nozzle.json b/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.8 Nozzle.json index 798dff9458..9b43dfadac 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.8 Nozzle.json +++ b/resources/profiles/Flashforge/filament/Generic PLA-CF @Flashforge G3U 0.8 Nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Flashforge G3U 0.8 Nozzle", - "inherits": "Generic PLA @Flashforge", "renamed_from": "Flashforge Generic PLA-CF @G3U 0.8 Nozzle;Flashforge Generic PLA-CF G3U 0.8 Nozzle", + "inherits": "Generic PLA @Flashforge", "from": "system", "setting_id": "f1rqvqunGS94fw7q", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Flashforge/filament/Generic PLA-Silk @Flashforge.json b/resources/profiles/Flashforge/filament/Generic PLA-Silk @Flashforge.json index d8eabacaa0..f831b9b690 100644 --- a/resources/profiles/Flashforge/filament/Generic PLA-Silk @Flashforge.json +++ b/resources/profiles/Flashforge/filament/Generic PLA-Silk @Flashforge.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-Silk @Flashforge", - "inherits": "fdm_filament_pla", "renamed_from": "Flashforge Generic PLA-Silk", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "TPRkxgDXxVhPC1ws", "filament_id": "OFi6PfUM", diff --git a/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5.json b/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5.json index d34dc09ee4..ffd86b3f25 100644 --- a/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5.json +++ b/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5.json @@ -41,6 +41,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "1.02" ], diff --git a/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5P.json b/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5P.json index 7b90c39711..499a3b0658 100644 --- a/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Generic TPU-64D @FF C5P.json @@ -44,6 +44,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "1.02" ], diff --git a/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5.json b/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5.json index de84158ff1..4e57706c46 100644 --- a/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5.json +++ b/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5.json @@ -41,6 +41,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "1.02" ], diff --git a/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5P.json b/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5P.json index dae60389c1..597b919fbe 100644 --- a/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Generic TPU-90A @FF C5P.json @@ -44,6 +44,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "1.02" ], diff --git a/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5.json b/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5.json index 66f0535b0b..9f7dcd3e03 100644 --- a/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5.json +++ b/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5.json @@ -41,6 +41,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "1.02" ], diff --git a/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5P.json b/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5P.json index f44c131661..eaa6eacd93 100644 --- a/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5P.json +++ b/resources/profiles/Flashforge/filament/Generic TPU-95A @FF C5P.json @@ -44,6 +44,9 @@ "fan_min_speed": [ "70" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "1.02" ], diff --git a/resources/profiles/Flashforge/filament/Kexcelled TPU 64D @FF Adventurer A5.json b/resources/profiles/Flashforge/filament/Kexcelled TPU 64D @FF Adventurer A5.json index 285af63564..95de8ab8b2 100644 --- a/resources/profiles/Flashforge/filament/Kexcelled TPU 64D @FF Adventurer A5.json +++ b/resources/profiles/Flashforge/filament/Kexcelled TPU 64D @FF Adventurer A5.json @@ -5,10 +5,10 @@ "from": "system", "setting_id": "OB4I8nwZn8sCcCcF", "filament_id": "OF20zavY", + "instantiation": "true", "filament_vendor": [ "Kexcelled" ], - "instantiation": "true", "cool_plate_temp": [ "40" ], diff --git a/resources/profiles/Flashforge/machine/Flashforge Adventurer 4 Series 0.6 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Adventurer 4 Series 0.6 nozzle.json index 357e50666a..fe24c8c825 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Adventurer 4 Series 0.6 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Adventurer 4 Series 0.6 nozzle.json @@ -22,9 +22,11 @@ ], "host_type": "flashforge", "machine_max_acceleration_extruding": [ + "5000", "5000" ], "machine_max_speed_z": [ + "30", "30" ] } diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.25 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.25 nozzle.json index c3cb7aa570..3f49f72c9e 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.25 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.25 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.4 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.4 nozzle.json index 474e697fa1..bb59171e96 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.4 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.4 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.6 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.6 nozzle.json index a10c65d83e..21aee9e9a1 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.6 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.6 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.8 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.8 nozzle.json index 0e3a29a2ad..1e4a9ced6c 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.8 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 0.8 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.25 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.25 nozzle.json index 911c09f29c..5faaefa754 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.25 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.25 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.4 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.4 nozzle.json index ec69837a3a..644248c9af 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.4 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.4 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.6 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.6 nozzle.json index d3d189d4e9..4a6f4db2f8 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.6 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.6 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.8 nozzle.json b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.8 nozzle.json index e596675ad0..bcd21f54e9 100644 --- a/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.8 nozzle.json +++ b/resources/profiles/Flashforge/machine/Flashforge Creator 5 Pro 0.8 nozzle.json @@ -70,66 +70,162 @@ "machine_end_gcode": ";end_gcode\nG1 X150 Y150 E-1.2 F12000", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_x": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_y": [ + "30000", + "20000", + "30000", + "20000", + "30000", + "20000", "30000", "20000" ], "machine_max_acceleration_z": [ + "300", + "500", + "300", + "500", + "300", + "500", "300", "500" ], "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", "3", "3" ], "machine_max_junction_deviation": [ + "0", + "0", + "0", + "0", + "0", + "0", "0", "0" ], "machine_max_speed_e": [ + "30", + "30", + "30", + "30", + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_y": [ + "600", + "600", + "600", + "600", + "600", + "600", "600", "600" ], "machine_max_speed_z": [ + "20", + "20", + "20", + "20", + "20", + "20", "20", "20" ], @@ -168,8 +264,18 @@ ], "nozzle_height": "4", "nozzle_hrc": "0", - "nozzle_type": "hardened_steel", - "nozzle_volume": "0", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "0", + "0", + "0", + "0" + ], "parking_pos_retraction": "0", "pellet_modded_printer": "0", "preferred_orientation": "0", diff --git a/resources/profiles/FlyingBear.json b/resources/profiles/FlyingBear.json index 8c09e115e2..04dac46c58 100644 --- a/resources/profiles/FlyingBear.json +++ b/resources/profiles/FlyingBear.json @@ -1,6 +1,6 @@ { "name": "FlyingBear", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "1", "description": "FlyingBear configurations", "machine_model_list": [ diff --git a/resources/profiles/FlyingBear/filament/Generic ABS @FlyingBear.json b/resources/profiles/FlyingBear/filament/Generic ABS @FlyingBear.json index b0de37a64b..c35e6def0c 100644 --- a/resources/profiles/FlyingBear/filament/Generic ABS @FlyingBear.json +++ b/resources/profiles/FlyingBear/filament/Generic ABS @FlyingBear.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @FlyingBear", - "inherits": "fdm_filament_abs", "renamed_from": "FlyingBear Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "2aW5bka7pvQhHGqF", "filament_id": "OFY9muEs", diff --git a/resources/profiles/FlyingBear/filament/Generic PA-CF @FlyingBear.json b/resources/profiles/FlyingBear/filament/Generic PA-CF @FlyingBear.json index 37448910ed..6a21bf1f04 100644 --- a/resources/profiles/FlyingBear/filament/Generic PA-CF @FlyingBear.json +++ b/resources/profiles/FlyingBear/filament/Generic PA-CF @FlyingBear.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @FlyingBear", - "inherits": "fdm_filament_pa", "renamed_from": "FlyingBear Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "5hw49IVGTMbie2Zr", "filament_id": "OFQLcbps", diff --git a/resources/profiles/FlyingBear/filament/Generic PC @FlyingBear.json b/resources/profiles/FlyingBear/filament/Generic PC @FlyingBear.json index 926494718b..91a4def417 100644 --- a/resources/profiles/FlyingBear/filament/Generic PC @FlyingBear.json +++ b/resources/profiles/FlyingBear/filament/Generic PC @FlyingBear.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @FlyingBear", - "inherits": "fdm_filament_pc", "renamed_from": "FlyingBear Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "HU6kkNtEXGubYV0U", "filament_id": "OFLakOUI", diff --git a/resources/profiles/FlyingBear/filament/Generic PETG @FlyingBear.json b/resources/profiles/FlyingBear/filament/Generic PETG @FlyingBear.json index 77079afc33..c14cb5258f 100644 --- a/resources/profiles/FlyingBear/filament/Generic PETG @FlyingBear.json +++ b/resources/profiles/FlyingBear/filament/Generic PETG @FlyingBear.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @FlyingBear", - "inherits": "fdm_filament_pet", "renamed_from": "FlyingBear Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "D5Zk6ykY8TX3gs0Z", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/FlyingBear/filament/Generic PLA @FlyingBear.json b/resources/profiles/FlyingBear/filament/Generic PLA @FlyingBear.json index 159f3da22b..b62cae5202 100644 --- a/resources/profiles/FlyingBear/filament/Generic PLA @FlyingBear.json +++ b/resources/profiles/FlyingBear/filament/Generic PLA @FlyingBear.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @FlyingBear", - "inherits": "fdm_filament_pla", "renamed_from": "FlyingBear Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "g7zPgD6P3bbwm5gv", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/FlyingBear/filament/Generic TPU @FlyingBear.json b/resources/profiles/FlyingBear/filament/Generic TPU @FlyingBear.json index c33b3757be..8b462ad936 100644 --- a/resources/profiles/FlyingBear/filament/Generic TPU @FlyingBear.json +++ b/resources/profiles/FlyingBear/filament/Generic TPU @FlyingBear.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @FlyingBear", - "inherits": "fdm_filament_tpu", "renamed_from": "FlyingBear Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "Xdx2FIIQiqSz7DpN", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/FlyingBear/filament/Ghost7/FlyingBear PLA Basic @Ghost7.json b/resources/profiles/FlyingBear/filament/Ghost7/FlyingBear PLA Basic @Ghost7.json index 85a926f7e9..01adb95891 100644 --- a/resources/profiles/FlyingBear/filament/Ghost7/FlyingBear PLA Basic @Ghost7.json +++ b/resources/profiles/FlyingBear/filament/Ghost7/FlyingBear PLA Basic @Ghost7.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "FlyingBear PLA Basic @Ghost7", - "inherits": "fdm_filament_pla @Ghost7", "renamed_from": "FlyingBear PLA @Ghost7", + "inherits": "fdm_filament_pla @Ghost7", "from": "system", "setting_id": "3JBTG6IDrBCnvIhf", "filament_id": "OF3fwO8b", diff --git a/resources/profiles/InfiMech.json b/resources/profiles/InfiMech.json index 78c54e0b4d..fb8e63b962 100644 --- a/resources/profiles/InfiMech.json +++ b/resources/profiles/InfiMech.json @@ -1,6 +1,6 @@ { "name": "InfiMech", - "version": "02.04.00.06", + "version": "02.04.00.07", "force_update": "1", "description": "InfiMech configurations", "machine_model_list": [ diff --git a/resources/profiles/InfiMech/filament/Generic ABS @InfiMech.json b/resources/profiles/InfiMech/filament/Generic ABS @InfiMech.json index 80b479de75..305a441fac 100644 --- a/resources/profiles/InfiMech/filament/Generic ABS @InfiMech.json +++ b/resources/profiles/InfiMech/filament/Generic ABS @InfiMech.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @InfiMech", - "inherits": "fdm_filament_abs", "renamed_from": "InfiMech Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "HRLECASD9Ko4Xxof", "filament_id": "OFY9muEs", diff --git a/resources/profiles/InfiMech/filament/Generic PA-CF @InfiMech.json b/resources/profiles/InfiMech/filament/Generic PA-CF @InfiMech.json index 0c202c609c..162e322696 100644 --- a/resources/profiles/InfiMech/filament/Generic PA-CF @InfiMech.json +++ b/resources/profiles/InfiMech/filament/Generic PA-CF @InfiMech.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @InfiMech", - "inherits": "fdm_filament_pa", "renamed_from": "InfiMech Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "IRYJpvGGjpF4ofY1", "filament_id": "OFQLcbps", diff --git a/resources/profiles/InfiMech/filament/Generic PC @InfiMech.json b/resources/profiles/InfiMech/filament/Generic PC @InfiMech.json index a37d5db2b7..ca98f3db10 100644 --- a/resources/profiles/InfiMech/filament/Generic PC @InfiMech.json +++ b/resources/profiles/InfiMech/filament/Generic PC @InfiMech.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @InfiMech", - "inherits": "fdm_filament_pc", "renamed_from": "InfiMech Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "W0oujcCps06G6yNB", "filament_id": "OFLakOUI", diff --git a/resources/profiles/InfiMech/filament/Generic PETG @InfiMech.json b/resources/profiles/InfiMech/filament/Generic PETG @InfiMech.json index 55162d9852..f57df9a1fc 100644 --- a/resources/profiles/InfiMech/filament/Generic PETG @InfiMech.json +++ b/resources/profiles/InfiMech/filament/Generic PETG @InfiMech.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @InfiMech", - "inherits": "fdm_filament_pet", "renamed_from": "InfiMech Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "sAi8oKez7NGKo1wy", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/InfiMech/filament/Generic PLA @InfiMech.json b/resources/profiles/InfiMech/filament/Generic PLA @InfiMech.json index 4d2d7dc402..fecad691df 100644 --- a/resources/profiles/InfiMech/filament/Generic PLA @InfiMech.json +++ b/resources/profiles/InfiMech/filament/Generic PLA @InfiMech.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @InfiMech", - "inherits": "fdm_filament_pla", "renamed_from": "InfiMech Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "tdnlzJyNB6zpQS8w", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/InfiMech/filament/Generic TPU @InfiMech.json b/resources/profiles/InfiMech/filament/Generic TPU @InfiMech.json index bc2b0c37a8..58e7605d3e 100644 --- a/resources/profiles/InfiMech/filament/Generic TPU @InfiMech.json +++ b/resources/profiles/InfiMech/filament/Generic TPU @InfiMech.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @InfiMech", - "inherits": "fdm_filament_tpu", "renamed_from": "InfiMech Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "kK1S7YP8vgTJeFPO", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/LH.json b/resources/profiles/LH.json index 09e5d17e35..43d0afc572 100644 --- a/resources/profiles/LH.json +++ b/resources/profiles/LH.json @@ -1,7 +1,7 @@ { "name": "LH", "url": "https://github.com/lhndo/LH-Stinger", - "version": "02.04.00.06", + "version": "02.04.00.07", "force_update": "0", "description": "LH 3D Printer Configuration", "machine_model_list": [ diff --git a/resources/profiles/LH/filament/LHS ABS.json b/resources/profiles/LH/filament/LHS ABS.json index 2e7ee48e32..f31f1c0392 100644 --- a/resources/profiles/LH/filament/LHS ABS.json +++ b/resources/profiles/LH/filament/LHS ABS.json @@ -1,11 +1,11 @@ { - "name": "LHS ABS", "type": "filament", - "filament_id": "OFztQ7rO", - "setting_id": "EQxNYC7BdGEA2iiD", - "from": "system", - "instantiation": "true", + "name": "LHS ABS", "inherits": "fdm_filament_asa", + "from": "system", + "setting_id": "EQxNYC7BdGEA2iiD", + "filament_id": "OFztQ7rO", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -352,4 +352,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LH/filament/LHS ASA.json b/resources/profiles/LH/filament/LHS ASA.json index 4cc096cb90..8495669ef7 100644 --- a/resources/profiles/LH/filament/LHS ASA.json +++ b/resources/profiles/LH/filament/LHS ASA.json @@ -1,11 +1,11 @@ { - "name": "LHS ASA", - "filament_id": "OFaP2SsH", - "setting_id": "hoq5bKHUb9DE1ezj", "type": "filament", - "from": "system", - "instantiation": "true", + "name": "LHS ASA", "inherits": "fdm_filament_asa", + "from": "system", + "setting_id": "hoq5bKHUb9DE1ezj", + "filament_id": "OFaP2SsH", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -349,4 +349,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LH/filament/LHS PCTG.json b/resources/profiles/LH/filament/LHS PCTG.json index 2f2a7d2fd6..515158064f 100644 --- a/resources/profiles/LH/filament/LHS PCTG.json +++ b/resources/profiles/LH/filament/LHS PCTG.json @@ -1,11 +1,11 @@ { - "name": "LHS PCTG", "type": "filament", - "filament_id": "OFBJAdLw", - "setting_id": "dKWttiAQNwymKsIC", - "from": "system", - "instantiation": "true", + "name": "LHS PCTG", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "dKWttiAQNwymKsIC", + "filament_id": "OFBJAdLw", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -349,4 +349,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LH/filament/LHS PETG.json b/resources/profiles/LH/filament/LHS PETG.json index 2956267dab..88893460dd 100644 --- a/resources/profiles/LH/filament/LHS PETG.json +++ b/resources/profiles/LH/filament/LHS PETG.json @@ -1,11 +1,11 @@ { - "name": "LHS PETG", "type": "filament", - "filament_id": "OFRJ325z", - "setting_id": "aZdY1M44ui7Rtj8r", - "from": "system", - "instantiation": "true", + "name": "LHS PETG", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "aZdY1M44ui7Rtj8r", + "filament_id": "OFRJ325z", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -349,4 +349,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LH/filament/LHS PLA.json b/resources/profiles/LH/filament/LHS PLA.json index 87ef788b7d..d52996d0a9 100644 --- a/resources/profiles/LH/filament/LHS PLA.json +++ b/resources/profiles/LH/filament/LHS PLA.json @@ -1,11 +1,11 @@ { - "name": "LHS PLA", "type": "filament", - "filament_id": "OFyoBZdm", - "setting_id": "M8WSwqD1iQkQntpy", - "from": "system", - "instantiation": "true", + "name": "LHS PLA", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "M8WSwqD1iQkQntpy", + "filament_id": "OFyoBZdm", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -349,4 +349,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LH/filament/LHS TPU Foamy 78A.json b/resources/profiles/LH/filament/LHS TPU Foamy 78A.json index 3be659400a..db9a24428a 100644 --- a/resources/profiles/LH/filament/LHS TPU Foamy 78A.json +++ b/resources/profiles/LH/filament/LHS TPU Foamy 78A.json @@ -1,11 +1,11 @@ { - "name": "LHS TPU Foamy 78A", "type": "filament", - "filament_id": "OFngcE81", - "setting_id": "FWyg21qHmAKeihMn", - "from": "system", - "instantiation": "true", + "name": "LHS TPU Foamy 78A", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "FWyg21qHmAKeihMn", + "filament_id": "OFngcE81", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -349,4 +349,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LH/filament/LHS TPU.json b/resources/profiles/LH/filament/LHS TPU.json index f503425bd4..6c6fd5cf99 100644 --- a/resources/profiles/LH/filament/LHS TPU.json +++ b/resources/profiles/LH/filament/LHS TPU.json @@ -1,11 +1,11 @@ { - "name": "LHS TPU", "type": "filament", - "filament_id": "OFIZMQwM", - "setting_id": "ILgpZYIqYGH6mqdI", - "from": "system", - "instantiation": "true", + "name": "LHS TPU", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "ILgpZYIqYGH6mqdI", + "filament_id": "OFIZMQwM", + "instantiation": "true", "compatible_printers": [ "LH Stinger 0.4 nozzle", "LH Stinger MMU 0.4 nozzle" @@ -349,4 +349,4 @@ "volumetric_speed_coefficients": [ "" ] -} \ No newline at end of file +} diff --git a/resources/profiles/LONGER.json b/resources/profiles/LONGER.json index b4d6c3a1fb..7ce53329e1 100644 --- a/resources/profiles/LONGER.json +++ b/resources/profiles/LONGER.json @@ -1,6 +1,6 @@ { "name": "LONGER", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "LONGER configurations", "machine_model_list": [ diff --git a/resources/profiles/LONGER/machine/LONGER LK10 (0.2 nozzle).json b/resources/profiles/LONGER/machine/LONGER LK10 (0.2 nozzle).json index 93a11e4a66..71b70e7fc8 100644 --- a/resources/profiles/LONGER/machine/LONGER LK10 (0.2 nozzle).json +++ b/resources/profiles/LONGER/machine/LONGER LK10 (0.2 nozzle).json @@ -33,36 +33,47 @@ ], "thumbnails_format": "PNG", "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "10000", "10000" ], "machine_max_acceleration_travel": [ + "10000", "10000" ], "machine_max_acceleration_x": [ + "10000", "10000" ], "machine_max_acceleration_y": [ + "10000", "10000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ] } diff --git a/resources/profiles/LONGER/machine/LONGER LK10 (0.4 nozzle).json b/resources/profiles/LONGER/machine/LONGER LK10 (0.4 nozzle).json index ce8f8b9580..5073e5e3c2 100644 --- a/resources/profiles/LONGER/machine/LONGER LK10 (0.4 nozzle).json +++ b/resources/profiles/LONGER/machine/LONGER LK10 (0.4 nozzle).json @@ -33,36 +33,47 @@ ], "thumbnails_format": "PNG", "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "10000", "10000" ], "machine_max_acceleration_travel": [ + "10000", "10000" ], "machine_max_acceleration_x": [ + "10000", "10000" ], "machine_max_acceleration_y": [ + "10000", "10000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ] } diff --git a/resources/profiles/LONGER/machine/LONGER LK10 (0.6 nozzle).json b/resources/profiles/LONGER/machine/LONGER LK10 (0.6 nozzle).json index a99639d18d..9dee6b44a9 100644 --- a/resources/profiles/LONGER/machine/LONGER LK10 (0.6 nozzle).json +++ b/resources/profiles/LONGER/machine/LONGER LK10 (0.6 nozzle).json @@ -33,36 +33,47 @@ ], "thumbnails_format": "PNG", "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "10000", "10000" ], "machine_max_acceleration_travel": [ + "10000", "10000" ], "machine_max_acceleration_x": [ + "10000", "10000" ], "machine_max_acceleration_y": [ + "10000", "10000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ] } diff --git a/resources/profiles/LONGER/machine/LONGER LK10 (0.8 nozzle).json b/resources/profiles/LONGER/machine/LONGER LK10 (0.8 nozzle).json index 0493d30520..222e47453e 100644 --- a/resources/profiles/LONGER/machine/LONGER LK10 (0.8 nozzle).json +++ b/resources/profiles/LONGER/machine/LONGER LK10 (0.8 nozzle).json @@ -33,36 +33,47 @@ ], "thumbnails_format": "PNG", "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "10000", "10000" ], "machine_max_acceleration_travel": [ + "10000", "10000" ], "machine_max_acceleration_x": [ + "10000", "10000" ], "machine_max_acceleration_y": [ + "10000", "10000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "12", "12" ] } diff --git a/resources/profiles/Lulzbot.json b/resources/profiles/Lulzbot.json index 39042cbe9a..5f0eb2a917 100644 --- a/resources/profiles/Lulzbot.json +++ b/resources/profiles/Lulzbot.json @@ -1,7 +1,7 @@ { "name": "Lulzbot", "url": "https://ohai.lulzbot.com/group/taz-6/", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Lulzbot configurations", "machine_model_list": [ diff --git a/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot Mini 1.json b/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot Mini 1.json index 1e5c2163f1..63f59fcbb9 100644 --- a/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot Mini 1.json +++ b/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot Mini 1.json @@ -11,6 +11,9 @@ "filament_density": [ "1.06" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "6" ], diff --git a/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot.json b/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot.json index 95d8a2274c..e7590dc5f8 100644 --- a/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot.json +++ b/resources/profiles/Lulzbot/filament/Generic ABS @Lulzbot.json @@ -1,14 +1,17 @@ { "type": "filament", "name": "Generic ABS @Lulzbot", - "inherits": "Generic ABS @System", "renamed_from": "Lulzbot 2.85mm ABS", + "inherits": "Generic ABS @System", "from": "system", "setting_id": "Mtn4Fh3Lp6KlAxjo", "instantiation": "true", "filament_diameter": [ "2.85" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "6" ], diff --git a/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot Mini 1.json b/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot Mini 1.json index bfddec7add..5b7bf6a70e 100644 --- a/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot Mini 1.json +++ b/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot Mini 1.json @@ -11,6 +11,9 @@ "filament_density": [ "1.24" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "6" ], diff --git a/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot.json b/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot.json index 825df8bdc8..3a45b4f117 100644 --- a/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot.json +++ b/resources/profiles/Lulzbot/filament/Generic PETG @Lulzbot.json @@ -1,14 +1,17 @@ { "type": "filament", "name": "Generic PETG @Lulzbot", - "inherits": "Generic PETG @System", "renamed_from": "Lulzbot 2.85mm PETG", + "inherits": "Generic PETG @System", "from": "system", "setting_id": "dqj6O9NIPAaq8wWz", "instantiation": "true", "filament_diameter": [ "2.85" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "6" ], diff --git a/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot Mini 1.json b/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot Mini 1.json index 07cae7accc..3a0a3f5549 100644 --- a/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot Mini 1.json +++ b/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot Mini 1.json @@ -11,6 +11,9 @@ "filament_density": [ "1.25" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "8" ], diff --git a/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot.json b/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot.json index d08d72ee53..29dae86c0e 100644 --- a/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot.json +++ b/resources/profiles/Lulzbot/filament/Generic PLA @Lulzbot.json @@ -1,14 +1,17 @@ { "type": "filament", "name": "Generic PLA @Lulzbot", - "inherits": "Generic PLA @System", "renamed_from": "Lulzbot 2.85mm PLA", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "3evRjso1wNxd9nV3", "instantiation": "true", "filament_diameter": [ "2.85" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "8" ], diff --git a/resources/profiles/M3D.json b/resources/profiles/M3D.json index a4231e878e..9140a8797b 100644 --- a/resources/profiles/M3D.json +++ b/resources/profiles/M3D.json @@ -1,6 +1,6 @@ { "name": "M3D", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "Configuration for M3D printers", "machine_model_list": [ diff --git a/resources/profiles/M3D/machine/M3D Enabler D7500 0.4 nozzle.json b/resources/profiles/M3D/machine/M3D Enabler D7500 0.4 nozzle.json index 9888c656b8..ad15070b64 100644 --- a/resources/profiles/M3D/machine/M3D Enabler D7500 0.4 nozzle.json +++ b/resources/profiles/M3D/machine/M3D Enabler D7500 0.4 nozzle.json @@ -32,27 +32,35 @@ "machine_end_gcode": "M104 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG1 X0 Y140\nG1 Y150 F4000\nM18 X Y E\nM18 S36000", "machine_load_filament_time": "0.5", "machine_max_acceleration_e": [ + "10000", "10000" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "400", "400" ], "machine_max_speed_e": [ + "30", "30" ], "machine_max_speed_x": [ + "60", "60" ], "machine_max_speed_y": [ + "60", "60" ], "machine_max_speed_z": [ + "12", "12" ], "machine_start_gcode": "M104 S{first_layer_temperature[0]} ; Begin Heating\n\nG91 ; Relative coordinates\nG1 Z10 ; Lift the head abit\nG90 ; Back to absolute coordinates\nG28 ; Home All\nG1 Z10 F500 ; Dont want to burn the bed while heating\nM109 S{first_layer_temperature[0]} ; Wait for pre-heat\n; Prime the extruder\nG92 E0 ; Set Extruder position to be 0\nG1 E5 F100 ; Extrude a bit in the air\nG1 X0 Y5 Z0.1 F500 ; Touch Down\nG92 E0 ; Set Extruder position to be 0\nG1 X100 Z0.3 E10 F500 ; Nozzle wipe\nG92 E0 ; Set Extruder position to be 0", diff --git a/resources/profiles/M3D/machine/M3D Enabler D8500 0.4 nozzle.json b/resources/profiles/M3D/machine/M3D Enabler D8500 0.4 nozzle.json index e57e6aeb8e..ee54cae8e5 100644 --- a/resources/profiles/M3D/machine/M3D Enabler D8500 0.4 nozzle.json +++ b/resources/profiles/M3D/machine/M3D Enabler D8500 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "machine", "name": "M3D Enabler D8500 0.4 nozzle", - "inherits": "fdm_machine_common", "renamed_from": "M3D Enabler D8500 MM", + "inherits": "fdm_machine_common", "from": "system", "setting_id": "xdGprcdFiVkG5vT2", "instantiation": "true", @@ -37,34 +37,50 @@ "machine_end_gcode": "; ===== ORCA END GCODE =====\nM400\nM83\nG92 E0\nG1 E-17 F1800 ; retract BEFORE any moves or power changes\n\n; Now lift and park\nG91\nG1 Z2 F2000\nG90\nG1 X100 Y160 F3000 ; parking point\n\n; Power down in order\nM104 T0 S0\nM104 T1 S0\nM106 S50 ; keep fan at ~50% while cooling (adjust if desired)\n; (Leave steppers on by omitting M84)\n; ===== END ORCA END GCODE =====\n", "machine_load_filament_time": "0.5", "machine_max_acceleration_e": [ + "10000", + "10000", "10000", "10000" ], "machine_max_acceleration_x": [ + "2000", + "2000", "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", + "2000", "2000", "2000" ], "machine_max_acceleration_z": [ + "400", + "400", "400", "400" ], "machine_max_speed_e": [ + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "400", + "400", "400", "400" ], "machine_max_speed_y": [ + "300", + "300", "300", "300" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], @@ -86,7 +102,10 @@ "0.4", "0.4" ], - "nozzle_type": "brass", + "nozzle_type": [ + "brass", + "brass" + ], "print_host": "m3d-enabler.local", "printable_area": [ "0x0", diff --git a/resources/profiles/M3D/process/0.15mm Standard @M3D Enabler D8500.json b/resources/profiles/M3D/process/0.15mm Standard @M3D Enabler D8500.json index 10c103af8d..a1e96478ed 100644 --- a/resources/profiles/M3D/process/0.15mm Standard @M3D Enabler D8500.json +++ b/resources/profiles/M3D/process/0.15mm Standard @M3D Enabler D8500.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.15mm Standard @M3D Enabler D8500", - "inherits": "fdm_process_common", "renamed_from": "0.15mm MM @D8500", + "inherits": "fdm_process_common", "from": "system", "setting_id": "69ArGbue7nQ5gO2r", "instantiation": "true", diff --git a/resources/profiles/M3D/process/0.20mm Standard @M3D Enabler D8500.json b/resources/profiles/M3D/process/0.20mm Standard @M3D Enabler D8500.json index dabf8c2dd0..1b24b64d8b 100644 --- a/resources/profiles/M3D/process/0.20mm Standard @M3D Enabler D8500.json +++ b/resources/profiles/M3D/process/0.20mm Standard @M3D Enabler D8500.json @@ -1,8 +1,8 @@ { "type": "process", "name": "0.20mm Standard @M3D Enabler D8500", - "inherits": "fdm_process_common", "renamed_from": "0.20mm MM @D8500", + "inherits": "fdm_process_common", "from": "system", "setting_id": "gg3RzTI5TgWRX2Hh", "instantiation": "true", diff --git a/resources/profiles/MagicMaker.json b/resources/profiles/MagicMaker.json index 08e5774547..f223b51f10 100644 --- a/resources/profiles/MagicMaker.json +++ b/resources/profiles/MagicMaker.json @@ -1,6 +1,6 @@ { "name": "MagicMaker", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "MagicMaker configurations", "machine_model_list": [ diff --git a/resources/profiles/MagicMaker/filament/Generic PEEK @MM.json b/resources/profiles/MagicMaker/filament/Generic PEEK @MM.json index 6915058856..101f4049e4 100644 --- a/resources/profiles/MagicMaker/filament/Generic PEEK @MM.json +++ b/resources/profiles/MagicMaker/filament/Generic PEEK @MM.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PEEK @MM", - "inherits": "fdm_filament_peek", "renamed_from": "MM Generic PEEK", + "inherits": "fdm_filament_peek", "from": "system", "setting_id": "2xiVNAQTwBaiLjJn", "filament_id": "OFz5oHgf", diff --git a/resources/profiles/MagicMaker/machine/MM BoneKing 0.4 nozzle.json b/resources/profiles/MagicMaker/machine/MM BoneKing 0.4 nozzle.json index 91054a666d..1ff55a7702 100644 --- a/resources/profiles/MagicMaker/machine/MM BoneKing 0.4 nozzle.json +++ b/resources/profiles/MagicMaker/machine/MM BoneKing 0.4 nozzle.json @@ -76,6 +76,7 @@ "Generic PLA @System" ], "machine_max_acceleration_e": [ + "10000", "10000" ], "machine_max_acceleration_extruding": [ diff --git a/resources/profiles/MagicMaker/machine/MM hj SK 0.4 nozzle.json b/resources/profiles/MagicMaker/machine/MM hj SK 0.4 nozzle.json index c1b219aae0..ef1cd2354c 100644 --- a/resources/profiles/MagicMaker/machine/MM hj SK 0.4 nozzle.json +++ b/resources/profiles/MagicMaker/machine/MM hj SK 0.4 nozzle.json @@ -51,6 +51,7 @@ "extruder_clearance_height_to_rod": "32", "extruder_clearance_radius": "50", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_speed_e": [ diff --git a/resources/profiles/MagicMaker/machine/MM hqs SF 0.4 nozzle.json b/resources/profiles/MagicMaker/machine/MM hqs SF 0.4 nozzle.json index fdfc49385a..6dff59135f 100644 --- a/resources/profiles/MagicMaker/machine/MM hqs SF 0.4 nozzle.json +++ b/resources/profiles/MagicMaker/machine/MM hqs SF 0.4 nozzle.json @@ -49,6 +49,7 @@ "extruder_clearance_height_to_rod": "32", "extruder_clearance_radius": "50", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_speed_e": [ diff --git a/resources/profiles/MagicMaker/machine/MM hqs hj 0.4 nozzle.json b/resources/profiles/MagicMaker/machine/MM hqs hj 0.4 nozzle.json index 9760c8382b..8e147c5284 100644 --- a/resources/profiles/MagicMaker/machine/MM hqs hj 0.4 nozzle.json +++ b/resources/profiles/MagicMaker/machine/MM hqs hj 0.4 nozzle.json @@ -60,6 +60,7 @@ "extruder_clearance_height_to_rod": "32", "extruder_clearance_radius": "50", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_speed_e": [ diff --git a/resources/profiles/MagicMaker/machine/MM slb 0.4 nozzle.json b/resources/profiles/MagicMaker/machine/MM slb 0.4 nozzle.json index 7c71afe855..fd64db2ef7 100644 --- a/resources/profiles/MagicMaker/machine/MM slb 0.4 nozzle.json +++ b/resources/profiles/MagicMaker/machine/MM slb 0.4 nozzle.json @@ -49,6 +49,7 @@ "extruder_clearance_height_to_rod": "32", "extruder_clearance_radius": "50", "machine_max_acceleration_e": [ + "4000", "4000" ], "machine_max_speed_e": [ diff --git a/resources/profiles/Meltingplot.json b/resources/profiles/Meltingplot.json index 654d955380..78277c2966 100644 --- a/resources/profiles/Meltingplot.json +++ b/resources/profiles/Meltingplot.json @@ -1,6 +1,6 @@ { "name": "Meltingplot", - "version": "02.04.00.00", + "version": "02.04.00.01", "force_update": "0", "description": "Meltingplot configurations", "machine_model_list": [ diff --git a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.4 nozzle.json index 1f759767fa..d0e99e29e7 100644 --- a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "AL4mb7soA7L0FKTb", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "10" ], diff --git a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.6 nozzle.json index c7984aa06d..0d4a82630a 100644 --- a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "OCnoqOQbcfgikNmA", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "15" ], diff --git a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.8 nozzle.json index a28a1feca0..7a416adeb2 100644 --- a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "HO2NCV1i1l21mokh", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "20" ], diff --git a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @1.0 nozzle.json index 545acdf113..afe41dfb47 100644 --- a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "dRH4HfWHQPwo33cP", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "25" ], diff --git a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt.json b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt.json index b9f864f79f..6ef4a397b2 100644 --- a/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt.json +++ b/resources/profiles/Meltingplot/filament/Extrudr PLA NX2 Matt.json @@ -6,6 +6,9 @@ "setting_id": "qmPRaTcPlmtk6zB2", "filament_id": "OF1PznHI", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Extrudr" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.4 nozzle.json index 837e55a36f..d5838a8bbc 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "NjuuWYHSc7IlwWAy", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "11" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.6 nozzle.json index d73964b709..add93bc87d 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "md24RPsRyxBhGRoW", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "16" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.8 nozzle.json index 82c5ed8935..c5e7bcb0ca 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ABS @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "Y2LYeWL7Zxel3m0c", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "22" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ABS @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ABS @1.0 nozzle.json index a74a3a1925..e69535f635 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ABS @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ABS @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "G2UYPHTEWjun65jj", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "27" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ABS.json b/resources/profiles/Meltingplot/filament/Meltingplot ABS.json index c947cd55e9..391c1b2233 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ABS.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ABS.json @@ -6,6 +6,9 @@ "setting_id": "zVQixgSSn1jm1c7n", "filament_id": "OFVIMei2", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.4 nozzle.json index f567231b8d..4257ef5d1e 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "4EBXMyiXoLrw5rLC", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "11" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.6 nozzle.json index 96553662a8..82313a70a6 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "2UdzXwYGT5nqtcdK", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "16" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.8 nozzle.json index 9e6d846c7f..92e4fb5ad2 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ASA @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "4hk1aKrMkppVYH4z", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "22" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ASA @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot ASA @1.0 nozzle.json index e8bc7d7a32..6f69297c3f 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ASA @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ASA @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "JRSnSdwkvrQx8uH8", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "27" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot ASA.json b/resources/profiles/Meltingplot/filament/Meltingplot ASA.json index 180ef14e39..908fef6e95 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot ASA.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot ASA.json @@ -6,6 +6,9 @@ "setting_id": "5VuPxdOXfTIidM4X", "filament_id": "OFRdywGp", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.4 nozzle.json index 5fd012ed93..ee4e17948e 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "yUlzU6KMVx8bpxj1", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "7" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.6 nozzle.json index 4ece916d20..a07615dfd6 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "9XzYyYbJ4jnO4nhJ", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "11" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.8 nozzle.json index b1b4d489f8..edd3918a77 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "BMbLehqxegpSvMci", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "15" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @1.0 nozzle.json index b2ab6f3cf5..197bf260b4 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "7R3XuQlzD8IHq4PZ", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "18" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT.json b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT.json index 6b2852b4b2..f1a9f8f3d4 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PA6 CF HT.json @@ -6,6 +6,9 @@ "setting_id": "kzlYLTM6H5CgpQ8y", "filament_id": "OFdPevOo", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.4 nozzle.json index f828906a7c..e3696dd899 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "2fkQa1BwTGZbSi2z", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "10" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.6 nozzle.json index 11b9bb2550..c2d529b818 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "PcNAj2kwuUNBAjQE", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "16" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.8 nozzle.json index 20039024ce..91e9f9aef8 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "70EwKatuncZBKgoD", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "21" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @1.0 nozzle.json index 9913b5f812..7995a32bfa 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15 @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "X2yhWBjK4j46bUYW", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "26" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15.json b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15.json index f932be9d05..4166040fad 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PET-CF15.json @@ -6,6 +6,9 @@ "setting_id": "IdqfEh7xRXKTYmV3", "filament_id": "OFJdf5nt", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.4 nozzle.json index 55df65bb99..edef02255f 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "2ohDGd34awK2DVbV", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "9" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.6 nozzle.json index 5d77c69c8f..fc5cd4fc2d 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "DZe1WokuOM5byttU", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "14" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.8 nozzle.json index 4e5f16b411..699bb146a2 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PETG @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "LwFY7N8Uisy6ivOV", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "18" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PETG @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PETG @1.0 nozzle.json index cdc4620078..87129aae8e 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PETG @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PETG @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "kR8Vbizk0CPciCbD", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "23" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PETG.json b/resources/profiles/Meltingplot/filament/Meltingplot PETG.json index d6ed4e25cb..f6085221b2 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PETG.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PETG.json @@ -6,6 +6,9 @@ "setting_id": "dsW7JrzWhKAY1fey", "filament_id": "OFvlreVF", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.4 nozzle.json index 4ec8bc1fb5..70794f0c92 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "T3OEfrhyZ6ISyv20", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "11" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.6 nozzle.json index 054bc03ab6..17bc575326 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "hsgzwjPc26BJ4sQu", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "16" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.8 nozzle.json index 7fa45fc182..21860142a0 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PLA @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "cz6RkfsQ0hJE0hYG", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "22" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PLA @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot PLA @1.0 nozzle.json index bbb19233db..f7d2138e9c 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PLA @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PLA @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "H3n0VPl3CymiK9VN", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "27" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot PLA.json b/resources/profiles/Meltingplot/filament/Meltingplot PLA.json index 60575e7aa6..d6eaeebaed 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot PLA.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot PLA.json @@ -6,6 +6,9 @@ "setting_id": "ONpaHlfJVJyh7Shb", "filament_id": "OFwXRVbB", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.4 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.4 nozzle.json index 6804806002..96c2e1a130 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.4 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.4 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "i5ttRpqpqF3Kg8IF", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "11" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.6 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.6 nozzle.json index a80febac3f..766ac02cc6 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.6 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.6 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "Vbm6NJb4il6QAU6v", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "16" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.8 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.8 nozzle.json index 3815b36da9..df6e98bf92 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.8 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @0.8 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "jYrElhVPtK2Dpb9K", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "22" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @1.0 nozzle.json b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @1.0 nozzle.json index 51ccd444e2..b9e3adad88 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot TitanX @1.0 nozzle.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot TitanX @1.0 nozzle.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "lQDEFxTsxFsT5A4n", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "27" ], diff --git a/resources/profiles/Meltingplot/filament/Meltingplot TitanX.json b/resources/profiles/Meltingplot/filament/Meltingplot TitanX.json index 5082e6e19e..f3ae8c8a23 100644 --- a/resources/profiles/Meltingplot/filament/Meltingplot TitanX.json +++ b/resources/profiles/Meltingplot/filament/Meltingplot TitanX.json @@ -6,6 +6,9 @@ "setting_id": "LDPRmxlvX97NXF0F", "filament_id": "OFyYfgDM", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Meltingplot" ], diff --git a/resources/profiles/OpenEYE.json b/resources/profiles/OpenEYE.json index 36f4ae9fac..07ba99b088 100644 --- a/resources/profiles/OpenEYE.json +++ b/resources/profiles/OpenEYE.json @@ -1,7 +1,7 @@ { "name": "OpenEYE", "url": "http://www.openeye.tech", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "0", "description": "OpenEYE Printers Configurations", "machine_model_list": [ diff --git a/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json b/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json index 8a3ce9de77..591bb61c09 100644 --- a/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json +++ b/resources/profiles/OpenEYE/machine/OpenEYE Peacock V2 0.4 nozzle.json @@ -1,9 +1,12 @@ { + "type": "machine", + "name": "OpenEYE Peacock V2 0.4 nozzle", + "inherits": "fdm_openeye_common", + "from": "system", + "setting_id": "iJqPJqKBFJvagyMn", + "instantiation": "true", "default_print_profile": "0.20mm Standard @OpenEYE Peacock V2", "default_bed_type": "Textured PEI Plate", - "from": "system", - "inherits": "fdm_openeye_common", - "instantiation": "true", "adaptive_bed_mesh_margin": "10", "bed_mesh_max": "211,211", "bed_mesh_min": "1.5,7", @@ -29,7 +32,6 @@ "machine_pause_gcode": "PAUSE", "machine_start_gcode": "SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nMMU_START_SETUP INITIAL_TOOL={initial_tool} TOTAL_TOOLCHANGES=!total_toolchanges! REFERENCED_TOOLS=!referenced_tools! TOOL_COLORS=!colors! TOOL_TEMPS=!temperatures! TOOL_MATERIALS=!materials! FILAMENT_NAMES=!filament_names! PURGE_VOLUMES=!purge_volumes!\nMMU_START_CHECK\nSTART_PRINT BED_TEMP=[bed_temperature_initial_layer] EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TYPE=\"{curr_bed_type}\" MESH_MIN={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} MESH_MAX={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE_MARGIN={adaptive_bed_mesh_margin}\n; Enter YOUR exist start_print macro call here (minus purging logic because tool may not be loaded yet)\nMMU_START_LOAD_INITIAL_TOOL\n; Optionally add YOUR additional start logic (like purging) here to run just prior to start\nSTART_PRINT_SECONDARY\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} ; For pause at layer functionality and better print stats", "machine_unload_filament_time": "30", - "name": "OpenEYE Peacock V2 0.4 nozzle", "nozzle_diameter": [ "0.4" ], @@ -43,9 +45,6 @@ "printer_model": "OpenEYE Peacock V2", "printer_variant": "0.4", "retract_lift_below": [ - "180", "180" - ], - "setting_id": "iJqPJqKBFJvagyMn", - "type": "machine" + ] } diff --git a/resources/profiles/OrcaArena.json b/resources/profiles/OrcaArena.json index 9bb97fb232..582bd47577 100644 --- a/resources/profiles/OrcaArena.json +++ b/resources/profiles/OrcaArena.json @@ -1,7 +1,7 @@ { "name": "Orca Arena Printer", "url": "", - "version": "02.04.00.07", + "version": "02.04.00.08", "force_update": "0", "description": "Orca Arena configuration files", "machine_model_list": [ diff --git a/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena 0.2 nozzle.json b/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena 0.2 nozzle.json index f98408fe0f..06fafc1e6d 100644 --- a/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena 0.2 nozzle.json +++ b/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @OrcaArena 0.2 nozzle", - "inherits": "Generic ABS @OrcaArena base", "renamed_from": "OrcaArena Generic ABS @0.2 nozzle;OrcaArena Generic ABS 0.2 nozzle", + "inherits": "Generic ABS @OrcaArena base", "from": "system", "setting_id": "mzx0hG9Xe9fIrkrW", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena.json index 2a505d7ca1..3cdcc432e7 100644 --- a/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic ABS @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @OrcaArena", - "inherits": "Generic ABS @OrcaArena base", "renamed_from": "OrcaArena Generic ABS", + "inherits": "Generic ABS @OrcaArena base", "from": "system", "setting_id": "ftTPQmVmsaD0n1GF", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena 0.2 nozzle.json b/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena 0.2 nozzle.json index 77bd051b4e..dfa3a1c768 100644 --- a/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena 0.2 nozzle.json +++ b/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @OrcaArena 0.2 nozzle", - "inherits": "Generic ASA @OrcaArena base", "renamed_from": "OrcaArena Generic ASA @0.2 nozzle;OrcaArena Generic ASA 0.2 nozzle", + "inherits": "Generic ASA @OrcaArena base", "from": "system", "setting_id": "rtFj6gFceWHdzTmO", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena.json index 0ee8d6cc20..5566524b6b 100644 --- a/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic ASA @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @OrcaArena", - "inherits": "Generic ASA @OrcaArena base", "renamed_from": "OrcaArena Generic ASA", + "inherits": "Generic ASA @OrcaArena base", "from": "system", "setting_id": "V2Z1rxHqIqIuwP5O", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PA @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PA @OrcaArena.json index 87b0a67ed8..bd158cb214 100644 --- a/resources/profiles/OrcaArena/filament/Generic PA @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PA @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @OrcaArena", - "inherits": "fdm_filament_pa", "renamed_from": "OrcaArena Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "KScdeqdB3UR6uvxs", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/OrcaArena/filament/Generic PA-CF @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PA-CF @OrcaArena.json index 2d928201b7..725379b2b2 100644 --- a/resources/profiles/OrcaArena/filament/Generic PA-CF @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PA-CF @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @OrcaArena", - "inherits": "fdm_filament_pa", "renamed_from": "OrcaArena Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "xANIesGhsXwbTn3J", "filament_id": "OFQLcbps", diff --git a/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena 0.2 nozzle.json b/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena 0.2 nozzle.json index ad15f49a69..cfad14e592 100644 --- a/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena 0.2 nozzle.json +++ b/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @OrcaArena 0.2 nozzle", - "inherits": "Generic PC @OrcaArena base", "renamed_from": "OrcaArena Generic PC @0.2 nozzle;OrcaArena Generic PC 0.2 nozzle", + "inherits": "Generic PC @OrcaArena base", "from": "system", "setting_id": "AEKvB4RVBo2zOkdg", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena.json index b4302c3c47..8d912f314d 100644 --- a/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PC @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @OrcaArena", - "inherits": "Generic PC @OrcaArena base", "renamed_from": "OrcaArena Generic PC", + "inherits": "Generic PC @OrcaArena base", "from": "system", "setting_id": "He4O4h8oEFsySDIJ", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena 0.2 nozzle.json b/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena 0.2 nozzle.json index 1be2988356..f61bd4a93c 100644 --- a/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena 0.2 nozzle.json +++ b/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @OrcaArena 0.2 nozzle", - "inherits": "Generic PETG @OrcaArena base", "renamed_from": "OrcaArena Generic PETG @0.2 nozzle;OrcaArena Generic PETG 0.2 nozzle", + "inherits": "Generic PETG @OrcaArena base", "from": "system", "setting_id": "ZstQ3h8DGCpRWQJN", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena.json index ad3260fe1c..1535697b43 100644 --- a/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PETG @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @OrcaArena", - "inherits": "Generic PETG @OrcaArena base", "renamed_from": "OrcaArena Generic PETG", + "inherits": "Generic PETG @OrcaArena base", "from": "system", "setting_id": "3puaC0EwFLvEnGH2", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PETG-CF @Arena X1C.json b/resources/profiles/OrcaArena/filament/Generic PETG-CF @Arena X1C.json index f8741a22a9..464391a198 100644 --- a/resources/profiles/OrcaArena/filament/Generic PETG-CF @Arena X1C.json +++ b/resources/profiles/OrcaArena/filament/Generic PETG-CF @Arena X1C.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Arena X1C", - "inherits": "Generic PETG-CF @OrcaArena base", "renamed_from": "OrcaArena Generic PETG-CF @Arena X1C;OrcaArena Generic PETG-CF Arena X1C", + "inherits": "Generic PETG-CF @OrcaArena base", "from": "system", "setting_id": "MeIL8qLFZytjvYrF", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena 0.2 nozzle.json b/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena 0.2 nozzle.json index 074732db01..03561223e1 100644 --- a/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena 0.2 nozzle.json +++ b/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @OrcaArena 0.2 nozzle", - "inherits": "Generic PLA @OrcaArena base", "renamed_from": "OrcaArena Generic PLA @0.2 nozzle;OrcaArena Generic PLA 0.2 nozzle", + "inherits": "Generic PLA @OrcaArena base", "from": "system", "setting_id": "HjJH9JT9x9sFtVES", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena.json index 9018f24583..df02e7a649 100644 --- a/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PLA @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @OrcaArena", - "inherits": "Generic PLA @OrcaArena base", "renamed_from": "OrcaArena Generic PLA", + "inherits": "Generic PLA @OrcaArena base", "from": "system", "setting_id": "TfkkCc6rILxDiZhR", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PLA Silk @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PLA Silk @OrcaArena.json index 6afb0e48a2..69fbf67886 100644 --- a/resources/profiles/OrcaArena/filament/Generic PLA Silk @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PLA Silk @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @OrcaArena", - "inherits": "Generic PLA Silk @OrcaArena base", "renamed_from": "OrcaArena Generic PLA Silk", + "inherits": "Generic PLA Silk @OrcaArena base", "from": "system", "setting_id": "rvJjX9QsHM1O1CGD", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PLA-CF @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PLA-CF @OrcaArena.json index ced9245904..6e5423f31b 100644 --- a/resources/profiles/OrcaArena/filament/Generic PLA-CF @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PLA-CF @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @OrcaArena", - "inherits": "Generic PLA-CF @OrcaArena base", "renamed_from": "OrcaArena Generic PLA-CF", + "inherits": "Generic PLA-CF @OrcaArena base", "from": "system", "setting_id": "vexlQFuvVzpsYT0Z", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena 0.2 nozzle.json b/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena 0.2 nozzle.json index 417ef65683..65f69a90ab 100644 --- a/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena 0.2 nozzle.json +++ b/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @OrcaArena 0.2 nozzle", - "inherits": "Generic PVA @OrcaArena base", "renamed_from": "OrcaArena Generic PVA @0.2 nozzle;OrcaArena Generic PVA 0.2 nozzle", + "inherits": "Generic PVA @OrcaArena base", "from": "system", "setting_id": "jX00tEZaqsJvpoBT", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena.json index bf9cbcda7a..575fa261c0 100644 --- a/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic PVA @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @OrcaArena", - "inherits": "Generic PVA @OrcaArena base", "renamed_from": "OrcaArena Generic PVA", + "inherits": "Generic PVA @OrcaArena base", "from": "system", "setting_id": "S9TMm0n7t54fKHoM", "instantiation": "true", diff --git a/resources/profiles/OrcaArena/filament/Generic TPU @OrcaArena.json b/resources/profiles/OrcaArena/filament/Generic TPU @OrcaArena.json index 75fcc13a79..84ae780686 100644 --- a/resources/profiles/OrcaArena/filament/Generic TPU @OrcaArena.json +++ b/resources/profiles/OrcaArena/filament/Generic TPU @OrcaArena.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @OrcaArena", - "inherits": "fdm_filament_tpu", "renamed_from": "OrcaArena Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "GBRnBtqYf9H8pQKU", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/OrcaFilamentLibrary.json b/resources/profiles/OrcaFilamentLibrary.json index f54e45df5a..d5f972a222 100644 --- a/resources/profiles/OrcaFilamentLibrary.json +++ b/resources/profiles/OrcaFilamentLibrary.json @@ -1,6 +1,6 @@ { "name": "OrcaFilamentLibrary", - "version": "02.04.00.13", + "version": "02.04.00.18", "force_update": "0", "description": "Orca Filament Library", "filament_list": [ @@ -472,6 +472,10 @@ "name": "Bambu PETG HF @base", "sub_path": "filament/Bambu/Bambu PETG HF @base.json" }, + { + "name": "Bambu PETG Matte @base", + "sub_path": "filament/Bambu/Bambu PETG Matte @base.json" + }, { "name": "Bambu PETG Translucent @base", "sub_path": "filament/Bambu/Bambu PETG Translucent @base.json" @@ -708,6 +712,10 @@ "name": "Bambu PLA Impact @base", "sub_path": "filament/Bambu/Bambu PLA Impact @base.json" }, + { + "name": "Bambu PLA Lite @base", + "sub_path": "filament/Bambu/Bambu PLA Lite @base.json" + }, { "name": "Bambu PLA Marble @base", "sub_path": "filament/Bambu/Bambu PLA Marble @base.json" @@ -720,6 +728,10 @@ "name": "Bambu PLA Metal @base", "sub_path": "filament/Bambu/Bambu PLA Metal @base.json" }, + { + "name": "Bambu PLA Pure @base", + "sub_path": "filament/Bambu/Bambu PLA Pure @base.json" + }, { "name": "Bambu PLA Silk @base", "sub_path": "filament/Bambu/Bambu PLA Silk @base.json" @@ -736,6 +748,14 @@ "name": "Bambu PLA Tough @base", "sub_path": "filament/Bambu/Bambu PLA Tough @base.json" }, + { + "name": "Bambu PLA Tough+ @base", + "sub_path": "filament/Bambu/Bambu PLA Tough+ @base.json" + }, + { + "name": "Bambu PLA Translucent @base", + "sub_path": "filament/Bambu/Bambu PLA Translucent @base.json" + }, { "name": "Bambu PLA Wood @base", "sub_path": "filament/Bambu/Bambu PLA Wood @base.json" @@ -1192,6 +1212,14 @@ "name": "BETA TPU Matte @base", "sub_path": "filament/BETA/BETA TPU Matte @base.json" }, + { + "name": "Bambu TPU 85A @base", + "sub_path": "filament/Bambu/Bambu TPU 85A @base.json" + }, + { + "name": "Bambu TPU 90A @base", + "sub_path": "filament/Bambu/Bambu TPU 90A @base.json" + }, { "name": "Bambu TPU 95A @base", "sub_path": "filament/Bambu/Bambu TPU 95A @base.json" @@ -1200,6 +1228,10 @@ "name": "Bambu TPU 95A HF @base", "sub_path": "filament/Bambu/Bambu TPU 95A HF @base.json" }, + { + "name": "Bambu TPU for AMS @base", + "sub_path": "filament/Bambu/Bambu TPU for AMS @base.json" + }, { "name": "COEX TPE 30D @base", "sub_path": "filament/COEX/COEX TPE 30D @base.json" @@ -1944,6 +1976,10 @@ "name": "Bambu PETG HF @System", "sub_path": "filament/Bambu/Bambu PETG HF @System.json" }, + { + "name": "Bambu PETG Matte @System", + "sub_path": "filament/Bambu/Bambu PETG Matte @System.json" + }, { "name": "Bambu PETG Translucent @System", "sub_path": "filament/Bambu/Bambu PETG Translucent @System.json" @@ -2652,6 +2688,10 @@ "name": "Bambu PLA Impact @System", "sub_path": "filament/Bambu/Bambu PLA Impact @System.json" }, + { + "name": "Bambu PLA Lite @System", + "sub_path": "filament/Bambu/Bambu PLA Lite @System.json" + }, { "name": "Bambu PLA Marble @System", "sub_path": "filament/Bambu/Bambu PLA Marble @System.json" @@ -2664,6 +2704,10 @@ "name": "Bambu PLA Metal @System", "sub_path": "filament/Bambu/Bambu PLA Metal @System.json" }, + { + "name": "Bambu PLA Pure @System", + "sub_path": "filament/Bambu/Bambu PLA Pure @System.json" + }, { "name": "Bambu PLA Silk @System", "sub_path": "filament/Bambu/Bambu PLA Silk @System.json" @@ -2680,6 +2724,14 @@ "name": "Bambu PLA Tough @System", "sub_path": "filament/Bambu/Bambu PLA Tough @System.json" }, + { + "name": "Bambu PLA Tough+ @System", + "sub_path": "filament/Bambu/Bambu PLA Tough+ @System.json" + }, + { + "name": "Bambu PLA Translucent @System", + "sub_path": "filament/Bambu/Bambu PLA Translucent @System.json" + }, { "name": "Bambu PLA Wood @System", "sub_path": "filament/Bambu/Bambu PLA Wood @System.json" @@ -3892,6 +3944,14 @@ "name": "BETA TPU Matte @BBL X1C", "sub_path": "filament/BETA/BBL/BETA TPU Matte @BBL X1C.json" }, + { + "name": "Bambu TPU 85A @System", + "sub_path": "filament/Bambu/Bambu TPU 85A @System.json" + }, + { + "name": "Bambu TPU 90A @System", + "sub_path": "filament/Bambu/Bambu TPU 90A @System.json" + }, { "name": "Bambu TPU 95A @System", "sub_path": "filament/Bambu/Bambu TPU 95A @System.json" @@ -3900,6 +3960,10 @@ "name": "Bambu TPU 95A HF @System", "sub_path": "filament/Bambu/Bambu TPU 95A HF @System.json" }, + { + "name": "Bambu TPU for AMS @System", + "sub_path": "filament/Bambu/Bambu TPU for AMS @System.json" + }, { "name": "COEX TPE 30D @BBL A1", "sub_path": "filament/COEX/BBL/COEX TPE 30D @BBL A1.json" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL H2D.json index b02dd7539c..d656750212 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL H2D.json @@ -9,6 +9,7 @@ "65" ], "fan_max_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL P1P.json index 8210765185..f04ace20fe 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL P1P.json @@ -6,6 +6,7 @@ "setting_id": "MPYyfCKMsJZy8GaY", "instantiation": "true", "fan_max_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL X1C.json index 196053eb0a..c7d4e82ed6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA ABS @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "vMA7EhgNDT4MwMRr", "instantiation": "true", "fan_max_speed": [ + "60", "60" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PEBA 90A @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PEBA 90A @BBL H2D.json index a5b0a4e46b..a165447b05 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PEBA 90A @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PEBA 90A @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "91b8WTzvOky9wAVK", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -113,6 +114,7 @@ "1" ], "nozzle_temperature_range_high": [ + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL H2D 0.4 nozzle.json index c508f9041c..057c9f8242 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "KnKvUsD4rSpQU413", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL X1C.json index 5547610fcf..04710b1fa5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "uM6wHdt0N5ftZRge", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL H2D 0.4 nozzle.json index 19f8879c41..7e48c959e7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "JHg4y0pxAOtoJSuw", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL X1C.json index 353498bf5c..4912d88dab 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Fluorescence @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "pCetfFvyLLw3vS2j", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL H2D 0.4 nozzle.json index 7d4b3bb5d5..fedcc166de 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "ijW4zvNAQ3DIK984", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL X1C.json index 18c99695f4..c8a290d952 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glitter @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "UI220qldPoLY8VZN", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL H2D 0.4 nozzle.json index 9196aff31b..40643ae178 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "3s9w3mH6M4OdbrUV", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL X1C.json index 42a4521212..789ea04781 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Glow @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "wv5FRKdnsHaIFA7L", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL H2D 0.4 nozzle.json index b468069cb7..794d273b55 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "GqmCuPg6baUxeoYS", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL X1C.json index 48c3f30535..64edc74c5a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Gradient @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "oYJjUiaCI4UBZ0ur", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL H2D 0.4 nozzle.json index f8bc99dd97..1550a34be4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL H2D 0.4 nozzle.json @@ -18,6 +18,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ @@ -109,6 +110,7 @@ "0" ], "fan_max_speed": [ + "30", "30" ], "hole_coef_2": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL X1C.json index d67f8d619e..b58c82e3f2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG HF @BBL X1C.json @@ -9,6 +9,7 @@ "20" ], "fan_min_speed": [ + "20", "20" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL H2D 0.4 nozzle.json index 5f6706766a..1bae511a03 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "DpWgpTiKdm70Xt1i", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL X1C.json index b0e0ee39ca..59bb2ed2b0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Heat Color Change @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "3lJe6ftSHQDkQZ1S", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL H2D 0.4 nozzle.json index decfcb73a1..9597d6cf2c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "RxCTxdvym4iNOB5j", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL X1C.json index 49ac9206f0..92d80895bf 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Marble @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "3BgsPAgilo1MgtOV", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL H2D 0.4 nozzle.json index 3287a32971..f092a437d8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "sqz8Vluq7GMd3siv", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL X1C.json index d8f5548ba0..432feb1f44 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Matte @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "NXgqYCqHeVCgFF3I", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL H2D 0.4 nozzle.json index c04e4513b5..5493034671 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "giq8BW6qcwz91e4C", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL X1C.json index eaa3a9dae2..bd40641cf8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG Metallic @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "tZzoc2LdgWkpEiox", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL H2D 0.4 nozzle.json index 03f0000a35..664acba408 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL H2D 0.4 nozzle.json @@ -6,9 +6,11 @@ "setting_id": "Ic0NUfwLmR0NSh5q", "instantiation": "true", "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL X1C.json index 32eaa333cf..f379f7822c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG UV Color Change @BBL X1C.json @@ -6,6 +6,7 @@ "setting_id": "BUKCpukEUmocfz3v", "instantiation": "true", "fan_min_speed": [ + "20", "20" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL H2D 0.4 nozzle.json index 22af1e06ff..2baf05c347 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL H2D 0.4 nozzle.json @@ -18,9 +18,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL P1P 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL P1P 0.4 nozzle.json index f1a7334810..818f5cfa7f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL P1P 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL P1P 0.4 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL X1C 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL X1C 0.4 nozzle.json index 273260a31f..59a3c628e1 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL X1C 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-CF @BBL X1C 0.4 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL H2D 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL H2D 0.4 nozzle.json index 277d1915b1..7b819b21b9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL H2D 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL H2D 0.4 nozzle.json @@ -18,9 +18,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL P1P 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL P1P 0.4 nozzle.json index a94fc48630..ec1c4d0d6c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL P1P 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL P1P 0.4 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL X1C 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL X1C 0.4 nozzle.json index db3ecc90d9..d17270dc91 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL X1C 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PETG-GF @BBL X1C 0.4 nozzle.json @@ -9,9 +9,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "5", "5" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL H2D.json index 97e462a487..0ee70ddaa9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "LZBgJ5xFtzrt3v02", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -24,9 +25,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL P1P.json index 99214e744d..2630b20b48 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Basic @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Chameleon @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Chameleon @BBL P1P.json index ea66c51982..07a08de4ae 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Chameleon @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Chameleon @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Fluorescence @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Fluorescence @BBL P1P.json index a786a7aa36..d03578a040 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Fluorescence @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Fluorescence @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glitter @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glitter @BBL P1P.json index c7cb14bea3..c938541308 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glitter @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glitter @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glow @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glow @BBL P1P.json index f19705f369..7054e30d3c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glow @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Glow @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Gradient @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Gradient @BBL P1P.json index 15b6d22f5e..5797b492b0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Gradient @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Gradient @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Heat Color Change @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Heat Color Change @BBL P1P.json index b789e28638..6ba21121f6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Heat Color Change @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Heat Color Change @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Speed @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Speed @BBL P1P.json index b2f9e5ad9d..741ec66d99 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Speed @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Speed @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Temp @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Temp @BBL H2D.json index 4047850988..d47c4fddb6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Temp @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA High Temp @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "5F1rml3AGNMD6F1g", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Marble @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Marble @BBL P1P.json index a198637db6..eccd20aeeb 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Marble @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Marble @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL H2D.json index bc595e11b5..cb47647899 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "Zw3CZVyBon930GCH", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL P1P.json index 6331679d0c..aaee41348e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Matte @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metal @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metal @BBL P1P.json index 512647c8ac..bd9857150f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metal @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metal @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metallic @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metallic @BBL P1P.json index cdb7e0a72d..3438bd4c8c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metallic @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Metallic @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL H2D.json index 605e1e9a37..b82556d9db 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "Mth7IAdxkWf7pSSj", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -24,9 +25,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL P1P.json index 35d88a6d9f..8f85e07ab2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA PRO @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk @BBL H2D.json index 943bdfaf11..76525381a6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "qXuac1ixZ4VdWMyA", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk+ @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk+ @BBL H2D.json index 35d9da0d5c..da4b170101 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk+ @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Silk+ @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "4aj9YjpmJDQoTIv7", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "eng_plate_temp": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL P1P.json index 3ab7af716f..b009240a89 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_retract_before_wipe": [ @@ -110,6 +111,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL X1C.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL X1C.json index 0c564fe5d0..5d3cafd4c7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL X1C.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Transparent @BBL X1C.json @@ -99,6 +99,7 @@ "0" ], "nozzle_temperature_range_low": [ + "200", "200" ], "nozzle_temperature": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA UV Color Change @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA UV Color Change @BBL P1P.json index 15309bbca5..fee733bc53 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA UV Color Change @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA UV Color Change @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Wood @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Wood @BBL P1P.json index 62d5a28a78..09fb339399 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Wood @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Wood @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_flow_ratio": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL H2D.json index 4b1b4b9a50..cc5a192fda 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "ZtgqauY30xyhRIB3", "instantiation": "true", "additional_cooling_fan_speed": [ + "75", "75" ], "counter_coef_2": [ @@ -27,9 +28,11 @@ "55" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "60", "60" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL P1P.json index a40b68fbc3..14995c7334 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA Youth @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA-CF @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA-CF @BBL P1P.json index d7e1cf9423..a5015a81c3 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA-CF @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA PLA-CF @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_long_retractions_when_cut": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 90A @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 90A @BBL H2D.json index 8eb8e80392..d1533707ee 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 90A @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 90A @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "lm5PEdmOJODAz6KJ", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -113,6 +114,7 @@ "1" ], "nozzle_temperature_range_high": [ + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 95A @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 95A @BBL H2D.json index 62cdeadad1..dad06c4758 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 95A @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 95A @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "k6clcTFJXTGVdmZg", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 98A @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 98A @BBL H2D.json index ab3c0989cb..eb4cdc710e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 98A @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU 98A @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "p0qjTRymaVctbU11", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU Matte @BBL H2D.json b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU Matte @BBL H2D.json index a1571446ab..ccb5715f92 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU Matte @BBL H2D.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/BETA/BBL/BETA TPU Matte @BBL H2D.json @@ -6,6 +6,7 @@ "setting_id": "PeJPI88l3Ui7jZnj", "instantiation": "true", "additional_cooling_fan_speed": [ + "100", "100" ], "eng_plate_temp": [ @@ -113,6 +114,7 @@ "1" ], "nozzle_temperature_range_high": [ + "250", "250" ], "nozzle_temperature": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @System.json index 30b5938bd1..6409e3aaa7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @System.json @@ -6,15 +6,35 @@ "setting_id": "iXiD2dx3qXFVPHRi", "instantiation": "true", "fan_max_speed": [ + "60", + "60", + "60", + "60", + "60", "60" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_max_volumetric_speed": [ - "16" + "12", + "20", + "25", + "12", + "18", + "18" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @base.json index 62c2f3bc84..9005778d8f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS @base.json @@ -7,9 +7,22 @@ "instantiation": "false", "description": "When printing this filament, there's a risk of warping and low layer adhesion strength. To get better results, please refer to this wiki: Printing Tips for High Temp / Engineering materials.", "filament_cost": [ - "24.99" + "15.99" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @System.json index 2a0c04401e..9c3b25c7f4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @System.json @@ -6,9 +6,19 @@ "setting_id": "mxgv6vFKgwBAF1Gw", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @base.json index 5cdd145c56..368f6415e0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ABS-GF @base.json @@ -13,15 +13,33 @@ "30" ], "filament_cost": [ - "29.99" + "26.99" ], "filament_density": [ "1.08" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @System.json index d94e4e4d83..85d822e0e7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @System.json @@ -6,12 +6,27 @@ "setting_id": "NEYuPnFvaHGhAdpD", "instantiation": "true", "fan_min_speed": [ + "25", + "25", + "25", + "25", + "25", "25" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @base.json index 432f106879..b848dda3a7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA @base.json @@ -16,16 +16,34 @@ "35" ], "filament_cost": [ - "31.99" + "26.99" ], "filament_density": [ "1.05" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_max_volumetric_speed": [ - "12" + "12", + "20", + "25", + "12", + "20", + "20" ], "filament_vendor": [ "Bambu Lab" @@ -37,9 +55,19 @@ "100" ], "nozzle_temperature": [ + "270", + "270", + "270", + "270", + "270", "270" ], "nozzle_temperature_initial_layer": [ + "270", + "270", + "270", + "270", + "270", "270" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-Aero @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-Aero @base.json index 8343f4f8cb..0b020ea032 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-Aero @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-Aero @base.json @@ -16,18 +16,41 @@ "30" ], "filament_cost": [ - "49.99" + "46.99" ], "filament_density": [ "0.99" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.52", + "0.52", + "0.52", + "0.52", + "0.52", "0.52" ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_retraction_length": [ + "1.5", + "1.5", + "1.5", + "1.5", + "1.5", "1.5" ], "filament_type": [ @@ -37,15 +60,35 @@ "Bambu Lab" ], "filament_wipe_distance": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_z_hop_types": [ + "Normal Lift", + "Normal Lift", + "Normal Lift", + "Normal Lift", + "Normal Lift", "Normal Lift" ], "nozzle_temperature": [ + "270", + "270", + "270", + "270", + "270", "270" ], "nozzle_temperature_initial_layer": [ + "270", + "270", + "270", + "270", + "270", "270" ], "overhang_fan_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-CF @base.json index 66abe8195a..96a8350b01 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu ASA-CF @base.json @@ -15,15 +15,33 @@ "25" ], "filament_cost": [ - "36.99" + "33.99" ], "filament_density": [ "1.02" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.9", + "0.9", + "0.9", + "0.9", + "0.9", "0.9" ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_type": [ @@ -39,9 +57,19 @@ "100" ], "nozzle_temperature": [ + "275", + "275", + "275", + "275", + "275", "275" ], "nozzle_temperature_initial_layer": [ + "275", + "275", + "275", + "275", + "275", "275" ], "nozzle_temperature_range_low": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @System.json index cadf540846..8ff5ce30ef 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @System.json @@ -6,15 +6,35 @@ "setting_id": "XTve0TGrHzrMdBnZ", "instantiation": "true", "nozzle_temperature_initial_layer": [ + "290", + "290", + "290", + "290", + "290", "290" ], "nozzle_temperature": [ + "290", + "290", + "290", + "290", + "290", "290" ], "fan_max_speed": [ + "30", + "30", + "30", + "30", + "30", "30" ], "fan_min_speed": [ + "10", + "10", + "10", + "10", + "10", "10" ], "fan_cooling_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @base.json index 00df3d58ef..f42452c512 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA-CF @base.json @@ -12,7 +12,20 @@ "filament_density": [ "1.09" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.96", + "0.96", + "0.96", + "0.96", + "0.96", "0.96" ], "filament_type": [ @@ -21,12 +34,6 @@ "filament_vendor": [ "Bambu Lab" ], - "nozzle_temperature": [ - "280" - ], - "nozzle_temperature_initial_layer": [ - "280" - ], "overhang_fan_speed": [ "40" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-CF @base.json index 578e30294c..304890617d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-CF @base.json @@ -16,12 +16,25 @@ "10" ], "filament_cost": [ - "79.99" + "76.99" ], "filament_density": [ "1.10" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.96", + "0.96", + "0.96", + "0.96", + "0.96", "0.96" ], "filament_type": [ @@ -31,9 +44,19 @@ "Bambu Lab" ], "nozzle_temperature": [ + "275", + "275", + "275", + "275", + "275", "275" ], "nozzle_temperature_initial_layer": [ + "275", + "275", + "275", + "275", + "275", "275" ], "overhang_fan_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @System.json index 337bcfae2c..9180402eaa 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @System.json @@ -9,12 +9,27 @@ "60" ], "filament_max_volumetric_speed": [ + "8", + "10.5", + "10.5", + "8", + "10.5", "10.5" ], "nozzle_temperature": [ + "265", + "265", + "265", + "265", + "265", "265" ], "nozzle_temperature_initial_layer": [ + "265", + "265", + "265", + "265", + "265", "265" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @base.json index c9eb830cad..09a6d7ca59 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PA6-GF @base.json @@ -6,6 +6,9 @@ "filament_id": "OFNk8bxk", "instantiation": "false", "description": "When printing this filament, there's a risk of nozzle clogging, oozing, warping and low layer adhesion strength. To get better results, please refer to this wiki: Printing Tips for High Temp / Engineering materials.", + "additional_fan_full_speed_layer": [ + "2" + ], "fan_cooling_layer_time": [ "5" ], @@ -16,12 +19,25 @@ "10" ], "filament_cost": [ - "59.99" + "56.99" ], "filament_density": [ "1.14" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.96", + "0.96", + "0.96", + "0.96", + "0.96", "0.96" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PAHT-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PAHT-CF @base.json index a028b7f7dc..d30f0be200 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PAHT-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PAHT-CF @base.json @@ -6,6 +6,9 @@ "filament_id": "OF2VFe4J", "instantiation": "false", "description": "When printing this filament, there's a risk of nozzle clogging, oozing, warping and low layer adhesion strength. To get better results, please refer to this wiki: Printing Tips for High Temp / Engineering materials.", + "additional_fan_full_speed_layer": [ + "2" + ], "fan_cooling_layer_time": [ "5" ], @@ -16,12 +19,25 @@ "10" ], "filament_cost": [ - "94.99" + "91.99" ], "filament_density": [ "1.06" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.96", + "0.96", + "0.96", + "0.96", + "0.96", "0.96" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @System.json index 2de9e190d2..f11e3cc8bb 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @System.json @@ -6,10 +6,23 @@ "setting_id": "piqS3ekvyUfN9dgG", "instantiation": "true", "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "slow_down_layer_time": [ "12" ], - "compatible_printers": [] + "compatible_printers": [], + "filament_max_volumetric_speed": [ + "12", + "12", + "30", + "12", + "12", + "20" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @base.json index 5ce775f0d0..56f22a6f3f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC @base.json @@ -5,13 +5,29 @@ "from": "system", "filament_id": "OFKhMPeX", "instantiation": "false", + "filament_cost": [ + "36.99" + ], + "filament_density": [ + "1.185" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_vendor": [ "Bambu Lab" ], - "filament_cost": [ - "39.99" - ], "filament_flow_ratio": [ + "0.94", + "0.94", + "0.94", + "0.94", + "0.94", "0.94" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @System.json index a3abfb5bd5..3f650afda5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @System.json @@ -6,6 +6,11 @@ "setting_id": "m7TaVFWJZUqzf0rP", "instantiation": "true", "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @base.json index 18c02b41a1..7afe6f6ed6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PC FR @base.json @@ -6,12 +6,25 @@ "filament_id": "OFg57Nmc", "instantiation": "false", "filament_cost": [ - "0" + "51.99" ], "filament_density": [ "1.19" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.94", + "0.94", + "0.94", + "0.94", + "0.94", "0.94" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PET-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PET-CF @base.json index fe22a52a0a..84673cb64b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PET-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PET-CF @base.json @@ -28,12 +28,25 @@ "10" ], "filament_cost": [ - "84.99" + "81.99" ], "filament_density": [ "1.29" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_max_volumetric_speed": [ + "8", + "8", + "8", + "8", + "8", "8" ], "filament_multitool_ramming_flow": [ @@ -52,9 +65,19 @@ "100" ], "nozzle_temperature": [ + "270", + "270", + "270", + "270", + "270", "270" ], "nozzle_temperature_initial_layer": [ + "270", + "270", + "270", + "270", + "270", "270" ], "nozzle_temperature_range_high": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @System.json index 0eb5c7c460..9a73056129 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @System.json @@ -6,12 +6,27 @@ "setting_id": "CCfgYCmjECjEC2ZS", "instantiation": "true", "filament_max_volumetric_speed": [ - "13" + "10", + "18", + "21", + "10", + "15", + "15" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @base.json index 117416a251..086af82c6a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Basic @base.json @@ -28,16 +28,26 @@ "10" ], "filament_cost": [ - "24.99" + "13.99" ], "filament_density": [ "1.25" ], - "filament_flow_ratio": [ - "0.95" + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" ], - "filament_max_volumetric_speed": [ - "8" + "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", + "0.95" ], "filament_multitool_ramming_flow": [ "8" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @System.json index ac9a5c3db0..97c8436453 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @System.json @@ -9,13 +9,28 @@ "20" ], "fan_min_speed": [ + "20", + "20", + "20", + "20", + "20", "20" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ - "18" + "18", + "10", + "10", + "18", + "10", + "10" ], "overhang_fan_speed": [ "100" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @base.json index ef4a817974..323b8bcae6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG HF @base.json @@ -27,16 +27,34 @@ "10" ], "filament_cost": [ - "24.99" + "15.99" ], "filament_density": [ "1.28" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ - "0.95" + "0.95", + "0.952", + "0.952", + "0.95", + "0.952", + "0.952" ], "filament_max_volumetric_speed": [ - "12" + "12", + "26", + "30", + "12", + "21", + "21" ], "filament_vendor": [ "Bambu Lab" @@ -48,9 +66,19 @@ "70" ], "nozzle_temperature": [ + "245", + "245", + "245", + "245", + "245", "245" ], "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", "230" ], "nozzle_temperature_range_high": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Matte @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Matte @System.json new file mode 100644 index 0000000000..04597dba2f --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Matte @System.json @@ -0,0 +1,49 @@ +{ + "type": "filament", + "name": "Bambu PETG Matte @System", + "inherits": "Bambu PETG Matte @base", + "from": "system", + "setting_id": "iFrbXE36ZPfvbGeb", + "instantiation": "true", + "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "10", + "15", + "21", + "10", + "15", + "15" + ], + "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", + "18" + ], + "nozzle_temperature": [ + "250", + "250", + "250", + "250", + "250", + "250" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245", + "245", + "245", + "245", + "245" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Matte @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Matte @base.json new file mode 100644 index 0000000000..7d6b8a692e --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Matte @base.json @@ -0,0 +1,82 @@ +{ + "type": "filament", + "name": "Bambu PETG Matte @base", + "inherits": "fdm_filament_pet", + "from": "system", + "filament_id": "OFdyfQvU", + "instantiation": "false", + "description": "To get better transparent or translucent results with the corresponding filament, please refer to this wiki: Printing tips for transparent PETG.", + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "10" + ], + "filament_cost": [ + "13.99" + ], + "filament_density": [ + "1.25" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_flow_ratio": [ + "0.95", + "0.97", + "0.97", + "0.95", + "0.97", + "0.97" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "10%" + ], + "slow_down_layer_time": [ + "12" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @System.json index 990343ec8e..58b7b615fa 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @System.json @@ -6,12 +6,27 @@ "setting_id": "qUW9pYQ6aYUpMb2I", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "filament_retraction_length": [ + "0.3", + "0.3", + "0.3", + "0.3", + "0.3", "0.3" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @base.json index 09efd2d8b5..555b2417a5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG Translucent @base.json @@ -28,15 +28,33 @@ "10" ], "filament_cost": [ - "24.99" + "15.99" ], "filament_density": [ "1.25" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_multitool_ramming_flow": [ @@ -52,9 +70,19 @@ "70" ], "nozzle_temperature": [ + "245", + "245", + "245", + "245", + "245", "245" ], "nozzle_temperature_initial_layer": [ + "250", + "250", + "250", + "250", + "250", "250" ], "nozzle_temperature_range_high": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @System.json index 2474c3c9da..f5590b772d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @System.json @@ -9,18 +9,43 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_max_volumetric_speed": [ + "11.5", + "11.5", + "11.5", + "11.5", + "11.5", "11.5" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "overhang_fan_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @base.json index 89fe7b3dde..ffbae062ae 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PETG-CF @base.json @@ -24,16 +24,26 @@ "0" ], "filament_cost": [ - "34.99" + "31.99" ], "filament_density": [ "1.25" ], - "filament_flow_ratio": [ - "0.95" + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" ], - "filament_max_volumetric_speed": [ - "12" + "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", + "0.95" ], "filament_type": [ "PETG-CF" @@ -65,9 +75,6 @@ "slow_down_layer_time": [ "6" ], - "temperature_vitrification": [ - "70" - ], "textured_plate_temp": [ "70" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @System.json index 511914839a..28ae999df2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @System.json @@ -6,6 +6,11 @@ "setting_id": "R499nyjJA5r7khOd", "instantiation": "true", "additional_cooling_fan_speed": [ + "0", + "0", + "0", + "0", + "0", "0" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @base.json index 1fb04ff6a9..5baa67a318 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Aero @base.json @@ -10,15 +10,33 @@ "30" ], "filament_cost": [ - "44.99" + "41.99" ], "filament_density": [ "1.21" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.6", + "0.6", + "0.6", + "0.6", + "0.6", "0.6" ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_multitool_ramming_flow": [ @@ -30,9 +48,6 @@ "filament_vendor": [ "Bambu Lab" ], - "filament_scarf_seam_type": [ - "none" - ], "nozzle_temperature_range_low": [ "210" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @System.json index 04ae179bcc..3e267d9444 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @System.json @@ -6,12 +6,27 @@ "setting_id": "zkc85XTKi4cb6cOw", "instantiation": "true", "filament_max_volumetric_speed": [ - "21" + "12", + "21", + "40", + "12", + "21", + "30" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @base.json index d5614af65f..96bf0e01d8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Basic @base.json @@ -6,30 +6,31 @@ "filament_id": "OFoiVqVM", "instantiation": "false", "filament_cost": [ - "24.99" + "15.99" ], "filament_density": [ "1.26" ], - "filament_flow_ratio": [ - "0.98" + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" ], - "filament_max_volumetric_speed": [ - "12" + "filament_flow_ratio": [ + "0.98", + "0.985", + "0.985", + "0.98", + "0.985", + "0.985" ], "filament_vendor": [ "Bambu Lab" ], - "filament_scarf_seam_type": [ - "none" - ], - "filament_scarf_height": [ - "10%" - ], "filament_scarf_gap": [ "0%" - ], - "filament_scarf_length": [ - "10" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @System.json index 15adc3e70f..51190b04ab 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @System.json @@ -6,9 +6,19 @@ "setting_id": "NZkeYlElza4KiVEo", "instantiation": "true", "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_max_volumetric_speed": [ + "12", + "21", + "21", + "12", + "21", "21" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @base.json index 7b1290817d..544235249e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Dynamic @base.json @@ -11,6 +11,14 @@ "filament_density": [ "1.26" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_vendor": [ "Bambu Lab" ] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @System.json index 69dc00e4e1..7b9c100352 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @System.json @@ -6,9 +6,19 @@ "setting_id": "O21mHwtRSSE6HEfS", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @base.json index 3ecc707ddf..09086beec7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Galaxy @base.json @@ -6,15 +6,33 @@ "filament_id": "OFQ3e56w", "instantiation": "false", "filament_cost": [ - "29.99" + "21.99" ], "filament_density": [ "1.19" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @System.json index 62b7248f32..6924441f5d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @System.json @@ -6,9 +6,19 @@ "setting_id": "BiwTTWJCMV2qcaF1", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @base.json index 8395082e6d..50ed9ba8fd 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Glow @base.json @@ -6,21 +6,39 @@ "filament_id": "OFEkPBwx", "instantiation": "false", "filament_cost": [ - "29.99" + "21.99" ], "filament_density": [ "1.26" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_vendor": [ "Bambu Lab" ], - "temperature_vitrification": [ - "45" + "required_nozzle_HRC": [ + "40" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @System.json index 342d7667f8..7a1c0c90b5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @System.json @@ -6,7 +6,12 @@ "setting_id": "1qdr65SvIErZzxN3", "instantiation": "true", "filament_max_volumetric_speed": [ - "23.2" + "12", + "21", + "21", + "12", + "21", + "21" ], "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @base.json index 1ff6cb84cc..33cfe9bbf6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Impact @base.json @@ -8,7 +8,20 @@ "filament_cost": [ "25.4" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Lite @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Lite @System.json new file mode 100644 index 0000000000..bd4b09654b --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Lite @System.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @System", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "MmKkT3hRnIEeSeXm", + "instantiation": "true", + "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", + "1" + ], + "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", + "18" + ], + "nozzle_temperature": [ + "220", + "220", + "220", + "220", + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220", + "220", + "220", + "220", + "220" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Lite @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Lite @base.json new file mode 100644 index 0000000000..81ccf320ed --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Lite @base.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFnfxTvi", + "instantiation": "false", + "filament_cost": [ + "18.99" + ], + "filament_density": [ + "1.40" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "12", + "21", + "40", + "12", + "16", + "16" + ], + "filament_vendor": [ + "Bambu Lab" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @System.json index 0573904f7f..67b3b9273c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @System.json @@ -6,9 +6,19 @@ "setting_id": "oNGmbbdba2aULYwQ", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @base.json index 0faa115520..74d40dde58 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Marble @base.json @@ -6,12 +6,25 @@ "filament_id": "OF9OlTWH", "instantiation": "false", "filament_cost": [ - "29.99" + "21.99" ], "filament_density": [ "1.22" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @System.json index bb359354b1..eb3d72adff 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @System.json @@ -6,12 +6,27 @@ "setting_id": "POQTCsM5qwSXswgr", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_max_volumetric_speed": [ - "22" + "11", + "19.5", + "40", + "11", + "19.5", + "25" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @base.json index ac7760f632..fa68a8c519 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Matte @base.json @@ -6,27 +6,34 @@ "filament_id": "OFXIbw5D", "instantiation": "false", "filament_cost": [ - "24.99" + "15.99" ], "filament_density": [ "1.32" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_vendor": [ "Bambu Lab" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_scarf_height": [ "5%" ], "filament_scarf_gap": [ "0%" - ], - "filament_scarf_length": [ - "10" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @System.json index 7a1a9661d8..c3616606cf 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @System.json @@ -6,6 +6,11 @@ "setting_id": "7w5T6uXXrwLzQb5D", "instantiation": "true", "filament_max_volumetric_speed": [ + "12", + "21", + "21", + "12", + "21", "21" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @base.json index 81a9c95c24..3a319c357c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Metal @base.json @@ -7,18 +7,28 @@ "instantiation": "false", "description": "To make the prints get higher gloss, please dry the filament before use, and set the outer wall speed to be 40 to 60 mm/s when slicing.", "filament_cost": [ - "29.99" + "21.99" ], "filament_density": [ "1.25" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_vendor": [ "Bambu Lab" - ], - "filament_scarf_seam_type": [ - "none" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Pure @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Pure @System.json new file mode 100644 index 0000000000..e18d718039 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Pure @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @System", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "MI6Z51sJkjOmlIl0", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Pure @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Pure @base.json new file mode 100644 index 0000000000..cc37c38cfa --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Pure @base.json @@ -0,0 +1,36 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFTHDCqA", + "instantiation": "false", + "filament_cost": [ + "16.99" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", + "0.98" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature_range_high": [ + "220" + ], + "slow_down_layer_time": [ + "8" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @System.json index 8114f02586..8a3c41a981 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @System.json @@ -5,5 +5,13 @@ "from": "system", "setting_id": "urdS8L3VweWtD0bW", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_max_volumetric_speed": [ + "7.5", + "7.5", + "7.5", + "7.5", + "7.5", + "7.5" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @base.json index f76daf5b77..3010ab3b71 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk @base.json @@ -7,12 +7,25 @@ "instantiation": "false", "description": "To make the prints get higher gloss, please dry the filament before use, and set the outer wall speed to be 40 to 60 mm/s when slicing.", "filament_cost": [ - "29.99" + "21.99" ], "filament_density": [ "1.32" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_vendor": [ @@ -25,9 +38,19 @@ "0%" ], "nozzle_temperature": [ + "230", + "230", + "230", + "230", + "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", "230" ], "supertack_plate_temp": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @System.json index c58e4dbc95..97db4b7d66 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @System.json @@ -11,5 +11,13 @@ "supertack_plate_temp_initial_layer": [ "35" ], - "compatible_printers": [] + "compatible_printers": [], + "filament_max_volumetric_speed": [ + "7.5", + "7.5", + "7.5", + "7.5", + "7.5", + "7.5" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @base.json index 93e6e81148..26fb14ac08 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Silk+ @base.json @@ -7,27 +7,47 @@ "instantiation": "false", "description": "To make the prints get higher gloss, please dry the filament before use, and set the outer wall speed to be 40 to 60 mm/s when slicing.", "filament_cost": [ - "29.99" + "15.99" ], "filament_density": [ "1.27" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ - "0.98" + "0.98", + "0.985", + "0.985", + "0.98", + "0.985", + "0.985" ], "filament_scarf_height": [ "5%" ], - "filament_scarf_seam_type": [ - "all" - ], "filament_vendor": [ "Bambu Lab" ], "nozzle_temperature": [ + "230", + "230", + "230", + "230", + "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", "230" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Sparkle @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Sparkle @base.json index 152b762069..e9ed1a15ca 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Sparkle @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Sparkle @base.json @@ -6,12 +6,25 @@ "filament_id": "OFDxfPgH", "instantiation": "false", "filament_cost": [ - "29.99" + "21.99" ], "filament_density": [ "1.26" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @System.json index 98ac23e383..206a921cea 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @System.json @@ -6,6 +6,11 @@ "setting_id": "ZxjDjF5XAaoeOobw", "instantiation": "true", "filament_max_volumetric_speed": [ + "12", + "21", + "21", + "12", + "21", "21" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @base.json index a5aa15e8c1..dfa1936ab9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough @base.json @@ -11,7 +11,20 @@ "filament_density": [ "1.26" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_vendor": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough+ @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough+ @System.json new file mode 100644 index 0000000000..191fc1baad --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough+ @System.json @@ -0,0 +1,33 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @System", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "5DfKHufhlLWJBqNG", + "instantiation": "true", + "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "18", + "18", + "12", + "18", + "18" + ], + "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", + "18" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough+ @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough+ @base.json new file mode 100644 index 0000000000..efe3f7aea1 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Tough+ @base.json @@ -0,0 +1,67 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OF342jVN", + "instantiation": "false", + "additional_cooling_fan_speed": [ + "80" + ], + "filament_change_length": [ + "5" + ], + "filament_cost": [ + "20.99" + ], + "filament_density": [ + "1.21" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", + "0.98" + ], + "filament_prime_volume": [ + "30" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature": [ + "245", + "245", + "245", + "245", + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245", + "245", + "245", + "245", + "245" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "slow_down_layer_time": [ + "8" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Translucent @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Translucent @System.json new file mode 100644 index 0000000000..1db5196607 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Translucent @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @System", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "M48unzzxHYxY9hUU", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Translucent @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Translucent @base.json new file mode 100644 index 0000000000..0cfa44ea55 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Translucent @base.json @@ -0,0 +1,36 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFFbSnCD", + "instantiation": "false", + "filament_cost": [ + "15.99" + ], + "filament_density": [ + "1.22" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", + "0.98" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "slow_down_layer_time": [ + "8" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Wood @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Wood @base.json index b9686af187..075d0f175d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Wood @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA Wood @base.json @@ -6,26 +6,51 @@ "filament_id": "OFMjtqTC", "instantiation": "false", "filament_cost": [ - "24.99" + "21.99" ], "filament_density": [ "1.21" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_vendor": [ "Bambu Lab" ] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @System.json index a677e25a26..e0a7db2a04 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @System.json @@ -6,18 +6,43 @@ "setting_id": "JKf6MqhbAM6NRWNY", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_max_volumetric_speed": [ + "12", + "15", + "15", + "12", + "15", "15" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "nozzle_temperature": [ + "230", + "230", + "230", + "230", + "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", "230" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @base.json index 7bd37d40a4..652b978391 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PLA-CF @base.json @@ -15,12 +15,25 @@ "45" ], "filament_cost": [ - "34.99" + "31.99" ], "filament_density": [ "1.22" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @System.json index 4200478407..958e721fe9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @System.json @@ -5,5 +5,13 @@ "from": "system", "setting_id": "NEjBweIYKppi6T0Q", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_max_volumetric_speed": [ + "6.5", + "6.5", + "6.5", + "6.5", + "6.5", + "6.5" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @base.json index 8519203173..e25994ff90 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPA-CF @base.json @@ -5,6 +5,14 @@ "from": "system", "filament_id": "OF54B0S0", "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_vendor": [ "Bambu Lab" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPS-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPS-CF @base.json index b48f3b9300..8f6b42d96d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPS-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PPS-CF @base.json @@ -10,7 +10,7 @@ "30" ], "filament_cost": [ - "175" + "169.32" ], "filament_density": [ "1.26" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @System.json index b0f82e6b71..ed4df6036f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @System.json @@ -6,9 +6,19 @@ "setting_id": "Eb9Y2xbVDpjuptrv", "instantiation": "true", "nozzle_temperature": [ + "240", + "240", + "240", + "240", + "240", "240" ], "nozzle_temperature_initial_layer": [ + "240", + "240", + "240", + "240", + "240", "240" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @base.json index 1c6e0f2201..7d8917cf86 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu PVA @base.json @@ -7,13 +7,26 @@ "instantiation": "false", "description": "This is a water-soluble support filament, and usually it is only for the support structure and not for the model body. Printing this filament is of many requirements, and to get better printing quality, please refer to this wiki: PVA Printing Guide.", "filament_cost": [ - "79.98" + "73.98" ], "filament_density": [ "1.27" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_max_volumetric_speed": [ - "6" + "4", + "4", + "4", + "4", + "4", + "4" ], "filament_vendor": [ "Bambu Lab" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PA PET @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PA PET @base.json index 7adbcb812d..6f15479b24 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PA PET @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PA PET @base.json @@ -15,6 +15,14 @@ "filament_density": [ "1.22" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_is_support": [ "1" ], @@ -22,9 +30,19 @@ "Bambu Lab" ], "nozzle_temperature": [ + "280", + "280", + "280", + "280", + "280", "280" ], "nozzle_temperature_initial_layer": [ + "280", + "280", + "280", + "280", + "280", "280" ], "required_nozzle_HRC": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA @base.json index 9511f5c0cd..8dc7f82786 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA @base.json @@ -13,11 +13,19 @@ "40" ], "filament_cost": [ - "69.98" + "39.98" ], "filament_density": [ "1.30" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_is_support": [ "1" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @System.json index 06af8de863..0e5d882c32 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @System.json @@ -12,9 +12,19 @@ "60" ], "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @base.json index 63802d3794..42b946de62 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support For PLA-PETG @base.json @@ -21,10 +21,23 @@ "filament_density": [ "1.19" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_is_support": [ "1" ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_multitool_ramming_flow": [ @@ -43,9 +56,19 @@ "60" ], "nozzle_temperature": [ + "210", + "210", + "210", + "210", + "210", "210" ], "nozzle_temperature_initial_layer": [ + "210", + "210", + "210", + "210", + "210", "210" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support G @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support G @base.json index 35cc03e9b8..148f1a6e1c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support G @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support G @base.json @@ -15,6 +15,14 @@ "filament_density": [ "1.22" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_is_support": [ "1" ], @@ -22,9 +30,19 @@ "Bambu Lab" ], "nozzle_temperature": [ + "280", + "280", + "280", + "280", + "280", "280" ], "nozzle_temperature_initial_layer": [ + "280", + "280", + "280", + "280", + "280", "280" ], "required_nozzle_HRC": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support W @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support W @base.json index a922afd83e..5f8135bfdc 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support W @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support W @base.json @@ -18,6 +18,14 @@ "filament_density": [ "1.30" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_is_support": [ "1" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @System.json index 3e998e0cc4..6e53555d93 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @System.json @@ -6,9 +6,19 @@ "setting_id": "5fy5QeiH5NyGq69r", "instantiation": "true", "filament_long_retractions_when_cut": [ + "1", + "1", + "1", + "1", + "1", "1" ], "filament_retraction_distances_when_cut": [ + "18", + "18", + "18", + "18", + "18", "18" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @base.json index b844ac16c7..8f6c3d6996 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu Support for ABS @base.json @@ -10,15 +10,33 @@ "30" ], "filament_cost": [ - "29.98" + "23.98" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_is_support": [ "1" ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_multitool_ramming_flow": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 85A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 85A @System.json new file mode 100644 index 0000000000..73ec0a348b --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 85A @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @System", + "inherits": "Bambu TPU 85A @base", + "from": "system", + "setting_id": "rmOR0b5LEO1Db9Db", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 85A @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 85A @base.json new file mode 100644 index 0000000000..e8acb25e51 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 85A @base.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @base", + "inherits": "fdm_filament_tpu", + "from": "system", + "filament_id": "OFlfuj2k", + "instantiation": "false", + "description": "This filament is too soft and not compatible with the AMS. Printing it is of many requirements, and to get better printing quality, please refer to this wiki: TPU printing guide.", + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.18" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "2.2", + "2.2", + "2.2", + "2.2", + "2.2", + "2.2" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature": [ + "225", + "225", + "225", + "225", + "225", + "225" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225", + "225", + "225", + "225", + "225" + ], + "nozzle_temperature_range_high": [ + "240" + ], + "slow_down_layer_time": [ + "20" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 90A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 90A @System.json new file mode 100644 index 0000000000..55631055a2 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 90A @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @System", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "YCcBMzzb9pqPsesL", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 90A @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 90A @base.json new file mode 100644 index 0000000000..ace53ae601 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 90A @base.json @@ -0,0 +1,53 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @base", + "inherits": "fdm_filament_tpu", + "from": "system", + "filament_id": "OFtkLO6q", + "instantiation": "false", + "description": "This filament is too soft and not compatible with the AMS. Printing it is of many requirements, and to get better printing quality, please refer to this wiki: TPU printing guide.", + "filament_cost": [ + "38.99" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8", + "2.8", + "2.8", + "2.8", + "2.8" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature": [ + "225", + "225", + "225", + "225", + "225", + "225" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225", + "225", + "225", + "225", + "225" + ], + "nozzle_temperature_range_high": [ + "240" + ], + "slow_down_layer_time": [ + "14" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @System.json index 5973e084b3..af343b5c5a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @System.json @@ -6,7 +6,12 @@ "setting_id": "LVi6dblW9n9rnSNJ", "instantiation": "true", "filament_max_volumetric_speed": [ - "3.6" + "3.2", + "3.2", + "3.2", + "3.2", + "3.2", + "3.2" ], "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @base.json index 5b71c52f81..4cf5910c79 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A @base.json @@ -12,13 +12,31 @@ "filament_density": [ "1.22" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_vendor": [ "Bambu Lab" ], "nozzle_temperature": [ + "230", + "230", + "230", + "230", + "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", "230" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A HF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A HF @base.json index 95263eb4ef..d89e277204 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A HF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU 95A HF @base.json @@ -7,24 +7,52 @@ "instantiation": "false", "description": "This filament is too soft and not compatible with the AMS. Printing it is of many requirements, and to get better printing quality, please refer to this wiki: TPU printing guide.", "filament_cost": [ - "41.99" + "38.99" ], "filament_density": [ "1.22" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_max_volumetric_speed": [ + "12", + "12", + "12", + "12", + "12", "12" ], "filament_retraction_length": [ + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", "0.8" ], "filament_vendor": [ "Bambu Lab" ], "nozzle_temperature": [ + "230", + "230", + "230", + "230", + "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", "230" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU for AMS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU for AMS @System.json new file mode 100644 index 0000000000..2a366e7da5 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU for AMS @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @System", + "inherits": "Bambu TPU for AMS @base", + "from": "system", + "setting_id": "kYivBf7yRPZlOH2U", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU for AMS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU for AMS @base.json new file mode 100644 index 0000000000..dd8aada9db --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Bambu/Bambu TPU for AMS @base.json @@ -0,0 +1,106 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @base", + "inherits": "fdm_filament_tpu", + "from": "system", + "filament_id": "OFIBbYO5", + "instantiation": "false", + "description": "If you are to print a kind of soft TPU, please don't slice with this profile, and it is only for TPU that has high enough hardness (not less than 55D) and is compatible with the AMS. To get better printing quality, please refer to this wiki: TPU printing guide.", + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "20" + ], + "filament_cost": [ + "34.99" + ], + "filament_density": [ + "1.26" + ], + "filament_deretraction_speed": [ + "10", + "10", + "10", + "10", + "10", + "10" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_flow_ratio": [ + "0.97", + "0.97", + "0.97", + "0.97", + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "18", + "18", + "18", + "18", + "18", + "18" + ], + "filament_retraction_length": [ + "2", + "0.4", + "0.4", + "2", + "0.4", + "0.4" + ], + "filament_retraction_speed": [ + "10", + "10", + "10", + "10", + "10", + "10" + ], + "filament_type": [ + "TPU-AMS" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature": [ + "230", + "230", + "230", + "230", + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230", + "230", + "230", + "230", + "230" + ], + "nozzle_temperature_range_high": [ + "240" + ], + "nozzle_temperature_range_low": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "10" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @System.json index 5fac752fcf..7b347e5f79 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC ABS @System", - "inherits": "DREMC ABS @base", - "from": "system", - "setting_id": "gNjISMxTLwQzDrV9", - "instantiation": "true", - "compatible_printers": [] -} \ No newline at end of file +{ + "type": "filament", + "name": "DREMC ABS @System", + "inherits": "DREMC ABS @base", + "from": "system", + "setting_id": "gNjISMxTLwQzDrV9", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @base.json index fbd2a32e8f..283ba5535c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS @base.json @@ -1,35 +1,35 @@ -{ - "type": "filament", - "name": "DREMC ABS @base", - "inherits": "fdm_filament_abs", - "from": "system", - "filament_id": "OFzrUUxc", - "instantiation": "false", - "filament_cost": [ - "24" - ], - "filament_density": [ - "1.06" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_shrink": [ - "99.7" - ], - "fan_max_speed": [ - "20" - ], - "overhang_fan_speed": [ - "50" - ], - "filament_max_volumetric_speed": [ - "20" - ], - "chamber_temperature": [ - "60" - ], - "filament_vendor": [ - "DREMC" - ] -} \ No newline at end of file +{ + "type": "filament", + "name": "DREMC ABS @base", + "inherits": "fdm_filament_abs", + "from": "system", + "filament_id": "OFzrUUxc", + "instantiation": "false", + "filament_cost": [ + "24" + ], + "filament_density": [ + "1.06" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_shrink": [ + "99.7" + ], + "fan_max_speed": [ + "20" + ], + "overhang_fan_speed": [ + "50" + ], + "filament_max_volumetric_speed": [ + "20" + ], + "chamber_temperature": [ + "60" + ], + "filament_vendor": [ + "DREMC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @System.json index 0d0345828e..6e367b2622 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC ABS+ @System", - "inherits": "DREMC ABS+ @base", - "from": "system", - "setting_id": "M73sIwcpWv6zpFrb", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC ABS+ @System", + "inherits": "DREMC ABS+ @base", + "from": "system", + "setting_id": "M73sIwcpWv6zpFrb", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @base.json index 6817351573..8f9fb0abad 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS+ @base.json @@ -1,26 +1,26 @@ -{ - "type": "filament", - "name": "DREMC ABS+ @base", - "inherits": "fdm_filament_abs", - "from": "system", - "filament_id": "OF99vXPs", - "instantiation": "false", - "filament_cost": [ - "24" - ], - "filament_density": [ - "1.06" - ], - "filament_flow_ratio": [ - "0.93" - ], - "filament_shrink": [ - "99.7" - ], - "filament_max_volumetric_speed": [ - "20" - ], - "filament_vendor": [ - "DREMC" - ] -} +{ + "type": "filament", + "name": "DREMC ABS+ @base", + "inherits": "fdm_filament_abs", + "from": "system", + "filament_id": "OF99vXPs", + "instantiation": "false", + "filament_cost": [ + "24" + ], + "filament_density": [ + "1.06" + ], + "filament_flow_ratio": [ + "0.93" + ], + "filament_shrink": [ + "99.7" + ], + "filament_max_volumetric_speed": [ + "20" + ], + "filament_vendor": [ + "DREMC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @System.json index f5cde22b77..ab136b1c02 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @System.json @@ -1,15 +1,15 @@ -{ - "type": "filament", - "name": "DREMC ABS-GF @System", - "inherits": "DREMC ABS-GF @base", - "from": "system", - "setting_id": "eWq555EPhD9cVAPL", - "instantiation": "true", - "filament_long_retractions_when_cut": [ - "1" - ], - "filament_retraction_distances_when_cut": [ - "18" - ], - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC ABS-GF @System", + "inherits": "DREMC ABS-GF @base", + "from": "system", + "setting_id": "eWq555EPhD9cVAPL", + "instantiation": "true", + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @base.json index 046a015930..397ca63348 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ABS-GF @base.json @@ -1,44 +1,44 @@ -{ - "type": "filament", - "name": "DREMC ABS-GF @base", - "inherits": "fdm_filament_abs", - "from": "system", - "filament_id": "OFCidU7j", - "instantiation": "false", - "fan_cooling_layer_time": [ - "12" - ], - "fan_max_speed": [ - "30" - ], - "filament_cost": [ - "40" - ], - "filament_density": [ - "1.12" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_shrink": [ - "99.7" - ], - "filament_max_volumetric_speed": [ - "18" - ], - "filament_type": [ - "ABS-GF" - ], - "filament_vendor": [ - "DREMC" - ], - "overhang_fan_speed": [ - "30" - ], - "overhang_fan_threshold": [ - "10%" - ], - "slow_down_layer_time": [ - "4" - ] -} +{ + "type": "filament", + "name": "DREMC ABS-GF @base", + "inherits": "fdm_filament_abs", + "from": "system", + "filament_id": "OFCidU7j", + "instantiation": "false", + "fan_cooling_layer_time": [ + "12" + ], + "fan_max_speed": [ + "30" + ], + "filament_cost": [ + "40" + ], + "filament_density": [ + "1.12" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_shrink": [ + "99.7" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_type": [ + "ABS-GF" + ], + "filament_vendor": [ + "DREMC" + ], + "overhang_fan_speed": [ + "30" + ], + "overhang_fan_threshold": [ + "10%" + ], + "slow_down_layer_time": [ + "4" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @System.json index 10d6626540..d5481e90f6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC ASA @System", - "inherits": "DREMC ASA @base", - "from": "system", - "setting_id": "PMulSQ0tYbNyvOYw", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC ASA @System", + "inherits": "DREMC ASA @base", + "from": "system", + "setting_id": "PMulSQ0tYbNyvOYw", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @base.json index 5e5e96b148..9b12602c7b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA @base.json @@ -1,44 +1,44 @@ -{ - "type": "filament", - "name": "DREMC ASA @base", - "inherits": "fdm_filament_asa", - "from": "system", - "filament_id": "OFLNgV3C", - "instantiation": "false", - "eng_plate_temp": [ - "110" - ], - "eng_plate_temp_initial_layer": [ - "110" - ], - "filament_cost": [ - "36" - ], - "filament_density": [ - "1.09" - ], - "filament_flow_ratio": [ - "0.94" - ], - "filament_shrink": [ - "99.7" - ], - "filament_max_volumetric_speed": [ - "15" - ], - "filament_vendor": [ - "DREMC" - ], - "hot_plate_temp": [ - "110" - ], - "hot_plate_temp_initial_layer": [ - "110" - ], - "textured_plate_temp": [ - "110" - ], - "textured_plate_temp_initial_layer": [ - "110" - ] -} +{ + "type": "filament", + "name": "DREMC ASA @base", + "inherits": "fdm_filament_asa", + "from": "system", + "filament_id": "OFLNgV3C", + "instantiation": "false", + "eng_plate_temp": [ + "110" + ], + "eng_plate_temp_initial_layer": [ + "110" + ], + "filament_cost": [ + "36" + ], + "filament_density": [ + "1.09" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_shrink": [ + "99.7" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_vendor": [ + "DREMC" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "textured_plate_temp": [ + "110" + ], + "textured_plate_temp_initial_layer": [ + "110" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @System.json index 0e10750d78..72d6abf2ca 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC ASA CF @System", - "inherits": "DREMC ASA CF @base", - "from": "system", - "setting_id": "ZcipEKAqtBcAm6vR", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC ASA CF @System", + "inherits": "DREMC ASA CF @base", + "from": "system", + "setting_id": "ZcipEKAqtBcAm6vR", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @base.json index ef6c3bc7b5..01065766e5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA CF @base.json @@ -1,50 +1,50 @@ -{ - "type": "filament", - "name": "DREMC ASA CF @base", - "inherits": "fdm_filament_asa", - "from": "system", - "filament_id": "OFdI4zMo", - "instantiation": "false", - "eng_plate_temp": [ - "110" - ], - "eng_plate_temp_initial_layer": [ - "110" - ], - "filament_cost": [ - "48" - ], - "filament_density": [ - "1.09" - ], - "filament_flow_ratio": [ - "0.92" - ], - "filament_shrink": [ - "99.7" - ], - "filament_max_volumetric_speed": [ - "15" - ], - "filament_vendor": [ - "DREMC" - ], - "hot_plate_temp": [ - "110" - ], - "hot_plate_temp_initial_layer": [ - "110" - ], - "textured_plate_temp": [ - "110" - ], - "textured_plate_temp_initial_layer": [ - "110" - ], - "nozzle_temperature": [ - "265" - ], - "nozzle_temperature_initial_layer": [ - "265" - ] -} +{ + "type": "filament", + "name": "DREMC ASA CF @base", + "inherits": "fdm_filament_asa", + "from": "system", + "filament_id": "OFdI4zMo", + "instantiation": "false", + "eng_plate_temp": [ + "110" + ], + "eng_plate_temp_initial_layer": [ + "110" + ], + "filament_cost": [ + "48" + ], + "filament_density": [ + "1.09" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_shrink": [ + "99.7" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_vendor": [ + "DREMC" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "textured_plate_temp": [ + "110" + ], + "textured_plate_temp_initial_layer": [ + "110" + ], + "nozzle_temperature": [ + "265" + ], + "nozzle_temperature_initial_layer": [ + "265" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @System.json index 2d0f99fa1e..18072f734c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC ASA GF @System", - "inherits": "DREMC ASA GF @base", - "from": "system", - "setting_id": "8J3lt7KlQWcx0VUS", - "instantiation": "true", - "compatible_printers": [] -} \ No newline at end of file +{ + "type": "filament", + "name": "DREMC ASA GF @System", + "inherits": "DREMC ASA GF @base", + "from": "system", + "setting_id": "8J3lt7KlQWcx0VUS", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @base.json index b916335f2f..985063e406 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC ASA GF @base.json @@ -1,50 +1,50 @@ -{ - "type": "filament", - "name": "DREMC ASA GF @base", - "inherits": "fdm_filament_asa", - "from": "system", - "filament_id": "OF2xccEe", - "instantiation": "false", - "eng_plate_temp": [ - "110" - ], - "eng_plate_temp_initial_layer": [ - "110" - ], - "filament_cost": [ - "36" - ], - "filament_density": [ - "1.12" - ], - "filament_flow_ratio": [ - "0.92" - ], - "filament_shrink": [ - "99.7" - ], - "filament_max_volumetric_speed": [ - "15" - ], - "filament_vendor": [ - "DREMC" - ], - "hot_plate_temp": [ - "110" - ], - "hot_plate_temp_initial_layer": [ - "110" - ], - "textured_plate_temp": [ - "110" - ], - "textured_plate_temp_initial_layer": [ - "110" - ], - "nozzle_temperature": [ - "270" - ], - "nozzle_temperature_initial_layer": [ - "270" - ] -} +{ + "type": "filament", + "name": "DREMC ASA GF @base", + "inherits": "fdm_filament_asa", + "from": "system", + "filament_id": "OF2xccEe", + "instantiation": "false", + "eng_plate_temp": [ + "110" + ], + "eng_plate_temp_initial_layer": [ + "110" + ], + "filament_cost": [ + "36" + ], + "filament_density": [ + "1.12" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_shrink": [ + "99.7" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_vendor": [ + "DREMC" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "textured_plate_temp": [ + "110" + ], + "textured_plate_temp_initial_layer": [ + "110" + ], + "nozzle_temperature": [ + "270" + ], + "nozzle_temperature_initial_layer": [ + "270" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @System.json index b126651441..46ee06deb1 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC PA12-CF @System", - "inherits": "DREMC PA12-CF @base", - "from": "system", - "setting_id": "jVlZ1KPsA5i8RIED", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC PA12-CF @System", + "inherits": "DREMC PA12-CF @base", + "from": "system", + "setting_id": "jVlZ1KPsA5i8RIED", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @base.json index 3482ecedf6..db21421565 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA12-CF @base.json @@ -1,59 +1,59 @@ -{ - "type": "filament", - "name": "DREMC PA12-CF @base", - "inherits": "fdm_filament_pa", - "from": "system", - "filament_id": "OFEhuUNq", - "instantiation": "false", - "fan_cooling_layer_time": [ - "15" - ], - "fan_max_speed": [ - "100" - ], - "filament_cost": [ - "105" - ], - "filament_density": [ - "1.06" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "14" - ], - "filament_type": [ - "PA-CF" - ], - "filament_vendor": [ - "DREMC" - ], - "full_fan_speed_layer": [ - "2" - ], - "nozzle_temperature": [ - "290" - ], - "nozzle_temperature_initial_layer": [ - "290" - ], - "nozzle_temperature_range_low": [ - "260" - ], - "overhang_fan_speed": [ - "100" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "temperature_vitrification": [ - "131" - ], - "textured_plate_temp": [ - "80" - ], - "textured_plate_temp_initial_layer": [ - "80" - ] -} +{ + "type": "filament", + "name": "DREMC PA12-CF @base", + "inherits": "fdm_filament_pa", + "from": "system", + "filament_id": "OFEhuUNq", + "instantiation": "false", + "fan_cooling_layer_time": [ + "15" + ], + "fan_max_speed": [ + "100" + ], + "filament_cost": [ + "105" + ], + "filament_density": [ + "1.06" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "14" + ], + "filament_type": [ + "PA-CF" + ], + "filament_vendor": [ + "DREMC" + ], + "full_fan_speed_layer": [ + "2" + ], + "nozzle_temperature": [ + "290" + ], + "nozzle_temperature_initial_layer": [ + "290" + ], + "nozzle_temperature_range_low": [ + "260" + ], + "overhang_fan_speed": [ + "100" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "temperature_vitrification": [ + "131" + ], + "textured_plate_temp": [ + "80" + ], + "textured_plate_temp_initial_layer": [ + "80" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @System.json index 61b28cdb4d..26825d9fb4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC PA6-CF @System", - "inherits": "DREMC PA6-CF @base", - "from": "system", - "setting_id": "GPnfqyRGptMQSsGP", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC PA6-CF @System", + "inherits": "DREMC PA6-CF @base", + "from": "system", + "setting_id": "GPnfqyRGptMQSsGP", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @base.json index fe5ef518a1..ebf4155d2f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PA6-CF @base.json @@ -1,53 +1,53 @@ -{ - "type": "filament", - "name": "DREMC PA6-CF @base", - "inherits": "fdm_filament_pa", - "from": "system", - "filament_id": "OFsoykbm", - "instantiation": "false", - "fan_cooling_layer_time": [ - "15" - ], - "filament_cost": [ - "68" - ], - "filament_density": [ - "1.25" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_type": [ - "PA6-CF" - ], - "filament_vendor": [ - "DREMC" - ], - "nozzle_temperature": [ - "270" - ], - "nozzle_temperature_initial_layer": [ - "270" - ], - "nozzle_temperature_range_low": [ - "260" - ], - "overhang_fan_speed": [ - "100" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "temperature_vitrification": [ - "215" - ], - "textured_plate_temp": [ - "90" - ], - "textured_plate_temp_initial_layer": [ - "90" - ] -} +{ + "type": "filament", + "name": "DREMC PA6-CF @base", + "inherits": "fdm_filament_pa", + "from": "system", + "filament_id": "OFsoykbm", + "instantiation": "false", + "fan_cooling_layer_time": [ + "15" + ], + "filament_cost": [ + "68" + ], + "filament_density": [ + "1.25" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_type": [ + "PA6-CF" + ], + "filament_vendor": [ + "DREMC" + ], + "nozzle_temperature": [ + "270" + ], + "nozzle_temperature_initial_layer": [ + "270" + ], + "nozzle_temperature_range_low": [ + "260" + ], + "overhang_fan_speed": [ + "100" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "temperature_vitrification": [ + "215" + ], + "textured_plate_temp": [ + "90" + ], + "textured_plate_temp_initial_layer": [ + "90" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @System.json index 85efd31920..05c758379b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC PET-CF @System", - "inherits": "DREMC PET-CF @base", - "from": "system", - "setting_id": "hal1nPyBF13UL9qB", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC PET-CF @System", + "inherits": "DREMC PET-CF @base", + "from": "system", + "setting_id": "hal1nPyBF13UL9qB", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @base.json index 9f7d27a1a0..a9c3db755d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PET-CF @base.json @@ -1,86 +1,86 @@ -{ - "type": "filament", - "name": "DREMC PET-CF @base", - "inherits": "fdm_filament_pet", - "from": "system", - "filament_id": "OFwJ0qu2", - "instantiation": "false", - "cool_plate_temp": [ - "0" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "242" - ], - "fan_min_speed": [ - "0" - ], - "filament_cost": [ - "70" - ], - "filament_density": [ - "1.3" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_type": [ - "PET-CF" - ], - "filament_vendor": [ - "DREMC" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature": [ - "300" - ], - "nozzle_temperature_initial_layer": [ - "300" - ], - "nozzle_temperature_range_high": [ - "300" - ], - "nozzle_temperature_range_low": [ - "270" - ], - "required_nozzle_HRC": [ - "40" - ], - "supertack_plate_temp": [ - "80" - ], - "supertack_plate_temp_initial_layer": [ - "80" - ], - "slow_down_layer_time": [ - "5" - ], - "slow_down_min_speed": [ - "10" - ], - "temperature_vitrification": [ - "147" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ] -} +{ + "type": "filament", + "name": "DREMC PET-CF @base", + "inherits": "fdm_filament_pet", + "from": "system", + "filament_id": "OFwJ0qu2", + "instantiation": "false", + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "242" + ], + "fan_min_speed": [ + "0" + ], + "filament_cost": [ + "70" + ], + "filament_density": [ + "1.3" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_type": [ + "PET-CF" + ], + "filament_vendor": [ + "DREMC" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature": [ + "300" + ], + "nozzle_temperature_initial_layer": [ + "300" + ], + "nozzle_temperature_range_high": [ + "300" + ], + "nozzle_temperature_range_low": [ + "270" + ], + "required_nozzle_HRC": [ + "40" + ], + "supertack_plate_temp": [ + "80" + ], + "supertack_plate_temp_initial_layer": [ + "80" + ], + "slow_down_layer_time": [ + "5" + ], + "slow_down_min_speed": [ + "10" + ], + "temperature_vitrification": [ + "147" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @System.json index 46f2cb9b20..733448583a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @System.json @@ -1,15 +1,15 @@ -{ - "type": "filament", - "name": "DREMC PETG @System", - "inherits": "DREMC PETG @base", - "from": "system", - "setting_id": "gTGiaBYfymmtlyfG", - "instantiation": "true", - "filament_max_volumetric_speed": [ - "20" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC PETG @System", + "inherits": "DREMC PETG @base", + "from": "system", + "setting_id": "gTGiaBYfymmtlyfG", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "20" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @base.json index c67e185527..9bc66b7ef4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PETG @base.json @@ -1,59 +1,59 @@ -{ - "type": "filament", - "name": "DREMC PETG @base", - "inherits": "fdm_filament_pet", - "from": "system", - "filament_id": "OFVBlUFH", - "instantiation": "false", - "cool_plate_temp": [ - "0" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "30" - ], - "fan_max_speed": [ - "90" - ], - "fan_min_speed": [ - "20" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_vendor": [ - "DREMC" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "overhang_fan_speed": [ - "50" - ], - "overhang_fan_threshold": [ - "10%" - ], - "slow_down_layer_time": [ - "12" - ], - "slow_down_min_speed": [ - "10" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ] -} \ No newline at end of file +{ + "type": "filament", + "name": "DREMC PETG @base", + "inherits": "fdm_filament_pet", + "from": "system", + "filament_id": "OFVBlUFH", + "instantiation": "false", + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "90" + ], + "fan_min_speed": [ + "20" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_vendor": [ + "DREMC" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "overhang_fan_speed": [ + "50" + ], + "overhang_fan_threshold": [ + "10%" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "10" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @System.json index 8e98be30b8..801772818c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @System.json @@ -1,12 +1,12 @@ -{ - "type": "filament", - "name": "DREMC PLA+ HS @System", - "inherits": "DREMC PLA+ HS @base", - "from": "system", - "setting_id": "I0HWhYAZ3ppq91Gx", - "instantiation": "true", - "filament_max_volumetric_speed": [ - "22" - ], - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC PLA+ HS @System", + "inherits": "DREMC PLA+ HS @base", + "from": "system", + "setting_id": "I0HWhYAZ3ppq91Gx", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "22" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @base.json index 1d7f1b47af..8aff665468 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA HS @base.json @@ -1,20 +1,20 @@ -{ - "type": "filament", - "name": "DREMC PLA+ HS @base", - "inherits": "fdm_filament_pla", - "from": "system", - "filament_id": "OFJHBEGD", - "instantiation": "false", - "filament_cost": [ - "26" - ], - "filament_density": [ - "1.25" - ], - "filament_flow_ratio": [ - "0.98" - ], - "filament_vendor": [ - "DREMC" - ] -} +{ + "type": "filament", + "name": "DREMC PLA+ HS @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFJHBEGD", + "instantiation": "false", + "filament_cost": [ + "26" + ], + "filament_density": [ + "1.25" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_vendor": [ + "DREMC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @System.json index 869633969a..37c782593e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @System.json @@ -1,12 +1,12 @@ -{ - "type": "filament", - "name": "DREMC PLA+ @System", - "inherits": "DREMC PLA+ @base", - "from": "system", - "setting_id": "fIjHIsFmdDWIM1bf", - "instantiation": "true", - "filament_max_volumetric_speed": [ - "18" - ], - "compatible_printers": [] -} \ No newline at end of file +{ + "type": "filament", + "name": "DREMC PLA+ @System", + "inherits": "DREMC PLA+ @base", + "from": "system", + "setting_id": "fIjHIsFmdDWIM1bf", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "18" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @base.json index b989f6d59d..56402a1a71 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PLA+ @base.json @@ -1,20 +1,20 @@ -{ - "type": "filament", - "name": "DREMC PLA+ @base", - "inherits": "fdm_filament_pla", - "from": "system", - "filament_id": "OFSwbBWS", - "instantiation": "false", - "filament_cost": [ - "26" - ], - "filament_density": [ - "1.25" - ], - "filament_flow_ratio": [ - "0.98" - ], - "filament_vendor": [ - "DREMC" - ] -} +{ + "type": "filament", + "name": "DREMC PLA+ @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFSwbBWS", + "instantiation": "false", + "filament_cost": [ + "26" + ], + "filament_density": [ + "1.25" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_vendor": [ + "DREMC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @System.json index 32edda19c3..48b62c9ca3 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @System.json @@ -1,9 +1,9 @@ -{ - "type": "filament", - "name": "DREMC PPA-CF @System", - "inherits": "DREMC PPA-CF @base", - "from": "system", - "setting_id": "flUD84NuiAfCit8z", - "instantiation": "true", - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC PPA-CF @System", + "inherits": "DREMC PPA-CF @base", + "from": "system", + "setting_id": "flUD84NuiAfCit8z", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @base.json index 6a696177e7..8fd11800be 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC PPA-CF @base.json @@ -1,11 +1,11 @@ -{ - "type": "filament", - "name": "DREMC PPA-CF @base", - "inherits": "fdm_filament_ppa", - "from": "system", - "filament_id": "OFiWaoqD", - "instantiation": "false", - "filament_vendor": [ - "DREMC" - ] -} \ No newline at end of file +{ + "type": "filament", + "name": "DREMC PPA-CF @base", + "inherits": "fdm_filament_ppa", + "from": "system", + "filament_id": "OFiWaoqD", + "instantiation": "false", + "filament_vendor": [ + "DREMC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @System.json index 86d5d02151..8278548d38 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @System.json @@ -1,12 +1,12 @@ -{ - "type": "filament", - "name": "DREMC TPU 95A @System", - "inherits": "DREMC TPU 95A @base", - "from": "system", - "setting_id": "AfnFh14wKZsNEaZ1", - "instantiation": "true", - "filament_max_volumetric_speed": [ - "6" - ], - "compatible_printers": [] -} +{ + "type": "filament", + "name": "DREMC TPU 95A @System", + "inherits": "DREMC TPU 95A @base", + "from": "system", + "setting_id": "AfnFh14wKZsNEaZ1", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "6" + ], + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @base.json b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @base.json index 63d4669b47..a0fe66dc47 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/DREMC/DREMC TPU 95A @base.json @@ -1,23 +1,23 @@ -{ - "type": "filament", - "name": "DREMC TPU 95A @base", - "inherits": "fdm_filament_tpu", - "from": "system", - "filament_id": "OFYd5uS3", - "instantiation": "false", - "filament_cost": [ - "40" - ], - "filament_density": [ - "1.25" - ], - "filament_vendor": [ - "DREMC" - ], - "nozzle_temperature": [ - "230" - ], - "nozzle_temperature_initial_layer": [ - "230" - ] -} +{ + "type": "filament", + "name": "DREMC TPU 95A @base", + "inherits": "fdm_filament_tpu", + "from": "system", + "filament_id": "OFYd5uS3", + "instantiation": "false", + "filament_cost": [ + "40" + ], + "filament_density": [ + "1.25" + ], + "filament_vendor": [ + "DREMC" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ABS @System.json index 51121cf6fc..0360bbbb63 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ABS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ABS @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo ABS @System", + "renamed_from": "Elegoo ABS", "inherits": "Elegoo ABS @base", "from": "system", "setting_id": "UKRDINWkDngjN16F", "instantiation": "true", - "renamed_from": "Elegoo ABS", "fan_max_speed": [ "40" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA @System.json index 6bd0ca95fd..97cc8563df 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo ASA @System", + "renamed_from": "Elegoo ASA", "inherits": "Elegoo ASA @base", "from": "system", "setting_id": "mpSVVs77BAdKmtP6", @@ -17,6 +18,5 @@ "nozzle_temperature_initial_layer": [ "270" ], - "compatible_printers": [], - "renamed_from": "Elegoo ASA" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA-CF @System.json index 13ef86c2d9..c469fa9019 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo ASA-CF @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo ASA-CF @System", + "renamed_from": "Elegoo ASA-CF", "inherits": "Elegoo ASA-CF @base", "from": "system", "setting_id": "XT1aUl4pe9t0Ijwg", "instantiation": "true", - "renamed_from": "Elegoo ASA-CF", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PAHT-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PAHT-CF @System.json index d07ac1dd64..725896bbd5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PAHT-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PAHT-CF @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PAHT-CF @System", + "renamed_from": "Elegoo PAHT-CF", "inherits": "Elegoo PAHT-CF @base", "from": "system", "setting_id": "S073oXCeOlTEqh6L", "instantiation": "true", - "renamed_from": "Elegoo PAHT-CF", "close_fan_the_first_x_layers": [ "3" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC @System.json index 8d2dcf83b7..6cd55a5668 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PC @System", + "renamed_from": "Elegoo PC", "inherits": "Elegoo PC @base", "from": "system", "setting_id": "NlNHcKHlkiq8khIf", "instantiation": "true", - "renamed_from": "Elegoo PC", "pressure_advance": [ "0.052" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC-FR @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC-FR @System.json index 7d2ab85058..e116b9e69a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC-FR @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PC-FR @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PC-FR @System", + "renamed_from": "Elegoo PC-FR", "inherits": "Elegoo PC-FR @base", "from": "system", "setting_id": "JcopkaXZ7YyLjIcw", "instantiation": "true", - "renamed_from": "Elegoo PC-FR", "pressure_advance": [ "0.05" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PET-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PET-CF @System.json index b7191e482b..5609b5ba6b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PET-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PET-CF @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PET-CF @System", + "renamed_from": "Elegoo PET-CF", "inherits": "Elegoo PET-CF @base", "from": "system", "setting_id": "oloKoC4Bs8dXatMU", "instantiation": "true", - "renamed_from": "Elegoo PET-CF", "pressure_advance": [ "0.05" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG @System.json index 621945f027..948f0970b6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PETG @System", + "renamed_from": "Elegoo PETG", "inherits": "Elegoo PETG @base", "from": "system", "setting_id": "4PLHMrDEDw4HLTve", "instantiation": "true", - "renamed_from": "Elegoo PETG", "pressure_advance": [ "0.05" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG HF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG HF @System.json index d912550c88..f67f6bbb15 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG HF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG HF @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PETG HF @System", + "renamed_from": "Elegoo PETG HF", "inherits": "Elegoo PETG HF @base", "from": "system", "setting_id": "d6gNuzrG00SXvMth", "instantiation": "true", - "renamed_from": "Elegoo PETG HF", "pressure_advance": [ "0.052" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG PRO @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG PRO @System.json index aa30920b7c..988424367e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG PRO @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG PRO @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PETG PRO @System", + "renamed_from": "Elegoo PETG PRO;Elegoo PETG Pro @System", "inherits": "Elegoo PETG PRO @base", "from": "system", "setting_id": "fdfCAYQEoYa9DN6I", @@ -17,6 +18,5 @@ "filament_max_volumetric_speed": [ "5" ], - "compatible_printers": [], - "renamed_from": "Elegoo PETG PRO;Elegoo PETG Pro @System" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG Translucent @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG Translucent @System.json index edb04a6dce..b73dece8de 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG Translucent @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG Translucent @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PETG Translucent @System", + "renamed_from": "Elegoo PETG Translucent", "inherits": "Elegoo PETG Translucent @base", "from": "system", "setting_id": "80Auuv3K7l8IptF3", "instantiation": "true", - "renamed_from": "Elegoo PETG Translucent", "pressure_advance": [ "0.052" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-CF @System.json index 03de8dad0f..9777aec024 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-CF @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PETG-CF @System", + "renamed_from": "Elegoo PETG-CF", "inherits": "Elegoo PETG-CF @base", "from": "system", "setting_id": "bXRJMaXxB3V49x7R", "instantiation": "true", - "renamed_from": "Elegoo PETG-CF", "pressure_advance": [ "0.052" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-GF @System.json index f315756987..d8fcd5b90a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PETG-GF @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PETG-GF @System", + "renamed_from": "Elegoo PETG-GF", "inherits": "Elegoo PETG-GF @base", "from": "system", "setting_id": "9NXaejLGh1VFX8bg", "instantiation": "true", - "renamed_from": "Elegoo PETG-GF", "pressure_advance": [ "0.052" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @System.json index 6120c0ac97..6e913207ac 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA @System", + "renamed_from": "Elegoo PLA", "inherits": "Elegoo PLA @base", "from": "system", "setting_id": "jiwZ5eoW1vHoJv9K", @@ -26,6 +27,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo PLA" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @base.json index 624c4ed95b..b18140ace7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA @base.json @@ -6,7 +6,7 @@ "filament_id": "OFvgE0Zh", "instantiation": "false", "fan_cooling_layer_time": [ - "81" + "85" ], "fan_min_speed": [ "50" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Basic @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Basic @System.json index 15d6f46a3f..ef10b6b1b2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Basic @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Basic @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Basic @System", + "renamed_from": "Elegoo PLA Basic", "inherits": "Elegoo PLA Basic @base", "from": "system", "setting_id": "qHDFHECwAInvpuk2", "instantiation": "true", - "renamed_from": "Elegoo PLA Basic", "nozzle_temperature": [ "220" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Galaxy @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Galaxy @System.json index 6fd7f8f606..3b00a8b673 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Galaxy @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Galaxy @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Galaxy @System", + "renamed_from": "Elegoo PLA Galaxy", "inherits": "Elegoo PLA Galaxy @base", "from": "system", "setting_id": "WXEEksjWsTbRyCPh", "instantiation": "true", - "renamed_from": "Elegoo PLA Galaxy", "fan_min_speed": [ "80" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Glow @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Glow @System.json index 9c4c2075b8..9a0d4d137b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Glow @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Glow @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Glow @System", + "renamed_from": "Elegoo PLA Glow", "inherits": "Elegoo PLA Glow @base", "from": "system", "setting_id": "yFdF2YmEMeCHiPxl", "instantiation": "true", - "renamed_from": "Elegoo PLA Glow", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Marble @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Marble @System.json index 755e42e758..e6309aca95 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Marble @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Marble @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Marble @System", + "renamed_from": "Elegoo PLA Marble", "inherits": "Elegoo PLA Marble @base", "from": "system", "setting_id": "kq7NS8IhIV4cBI1C", "instantiation": "true", - "renamed_from": "Elegoo PLA Marble", "fan_min_speed": [ "80" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Matte @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Matte @System.json index a05c57216e..c97d63d201 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Matte @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Matte @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Matte @System", + "renamed_from": "Elegoo PLA Matte", "inherits": "Elegoo PLA Matte @base", "from": "system", "setting_id": "UykE255l5V0oS0Ca", @@ -47,6 +48,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo PLA Matte" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA PRO @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA PRO @System.json index fbc18fac42..8ec9dd9746 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA PRO @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA PRO @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA PRO @System", + "renamed_from": "Elegoo PLA PRO", "inherits": "Elegoo PLA PRO @base", "from": "system", "setting_id": "62GiUVVZd8kx21vw", @@ -23,6 +24,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo PLA PRO" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Silk @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Silk @System.json index 79ae01da5b..b6b8387375 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Silk @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Silk @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA Silk @System", + "renamed_from": "Elegoo PLA Silk", "inherits": "Elegoo PLA Silk @base", "from": "system", "setting_id": "VkXguNj79KADxuYn", @@ -47,6 +48,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo PLA Silk" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Sparkle @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Sparkle @System.json index c7c030ff5a..203f67162e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Sparkle @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Sparkle @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Sparkle @System", + "renamed_from": "Elegoo PLA Sparkle", "inherits": "Elegoo PLA Sparkle @base", "from": "system", "setting_id": "VwZIFCojZLQLPrI1", "instantiation": "true", - "renamed_from": "Elegoo PLA Sparkle", "fan_min_speed": [ "80" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Translucent2 @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Translucent2 @System.json index 28993f13b4..2fc32af720 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Translucent2 @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Translucent2 @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Translucent2 @System", + "renamed_from": "Elegoo PLA Translucent2", "inherits": "Elegoo PLA Translucent2 @base", "from": "system", "setting_id": "q0koYRlO9X8xLXPM", "instantiation": "true", - "renamed_from": "Elegoo PLA Translucent2", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Wood @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Wood @System.json index 1e86976608..9e54df5c0b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Wood @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA Wood @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo PLA Wood @System", + "renamed_from": "Elegoo PLA Wood", "inherits": "Elegoo PLA Wood @base", "from": "system", "setting_id": "pMgazYJG8tyTpAVE", "instantiation": "true", - "renamed_from": "Elegoo PLA Wood", "fan_min_speed": [ "80" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA+ @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA+ @System.json index 2315cd2ac4..c155f82d3d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA+ @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA+ @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA+ @System", + "renamed_from": "Elegoo PLA+", "inherits": "Elegoo PLA+ @base", "from": "system", "setting_id": "q7NpDtaD9dTq1HIZ", @@ -20,6 +21,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo PLA+" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA-CF @System.json index 9b79f54799..0bb0edb9b9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo PLA-CF @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo PLA-CF @System", + "renamed_from": "Elegoo PLA-CF", "inherits": "Elegoo PLA-CF @base", "from": "system", "setting_id": "cYxM93L2KZBnAuWu", @@ -56,6 +57,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo PLA-CF" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PETG @System.json index 7fd3f8d160..ee13e5c9c9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PETG @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo Rapid PETG @System", + "renamed_from": "Elegoo Rapid PETG;Elegoo Rapid PETG+;Elegoo RAPID PETG;Elegoo RAPID PETG+", "inherits": "Elegoo Rapid PETG @base", "from": "system", "setting_id": "uUQSVOvP8tAaDqvB", @@ -32,6 +33,5 @@ "nozzle_temperature_initial_layer": [ "250" ], - "compatible_printers": [], - "renamed_from": "Elegoo Rapid PETG;Elegoo Rapid PETG+;Elegoo RAPID PETG;Elegoo RAPID PETG+" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PLA+ @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PLA+ @System.json index 4f3ee82ced..a632544557 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PLA+ @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid PLA+ @System.json @@ -1,6 +1,7 @@ { "type": "filament", "name": "Elegoo Rapid PLA+ @System", + "renamed_from": "Elegoo Rapid PLA+;Elegoo RAPID PLA+", "inherits": "Elegoo Rapid PLA+ @base", "from": "system", "setting_id": "HZ4nP67iAG7a243e", @@ -44,6 +45,5 @@ "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ], - "compatible_printers": [], - "renamed_from": "Elegoo Rapid PLA+;Elegoo RAPID PLA+" + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid TPU 95A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid TPU 95A @System.json index 3d15ba541c..e64c237aa7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid TPU 95A @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo Rapid TPU 95A @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo Rapid TPU 95A @System", + "renamed_from": "Elegoo Rapid TPU 95A", "inherits": "Elegoo Rapid TPU 95A @base", "from": "system", "setting_id": "WXLuO112bsdM37MI", "instantiation": "true", - "renamed_from": "Elegoo Rapid TPU 95A", "pressure_advance": [ "0.1" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo TPU 95A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo TPU 95A @System.json index 020bb85945..fdc4a7546d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo TPU 95A @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Elegoo/Elegoo TPU 95A @System.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Elegoo TPU 95A @System", + "renamed_from": "Elegoo TPU 95A", "inherits": "Elegoo TPU 95A @base", "from": "system", "setting_id": "SLcn59fIZPDl2brJ", "instantiation": "true", - "renamed_from": "Elegoo TPU 95A", "filament_max_volumetric_speed": [ "3.2" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ABS @System.json index 09fe0e6298..b73866a0f2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ABS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ABS @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFXCBZTA", - "setting_id": "R1lkPc60BdFq6i2Z", "name": "Eolas Prints ABS @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "R1lkPc60BdFq6i2Z", + "filament_id": "OFXCBZTA", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ASA @System.json index 263752abf1..e5fd6a2412 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ASA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints ASA @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFlSNkhc", - "setting_id": "JFXFsEzqXxNqxnsL", "name": "Eolas Prints ASA @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_asa", + "from": "system", + "setting_id": "JFXFsEzqXxNqxnsL", + "filament_id": "OFlSNkhc", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG @System.json index 9f1c691c30..33a64f72e5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFhWhL1i", - "setting_id": "u9fzEmHRAACOHT6J", "name": "Eolas Prints PETG @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "u9fzEmHRAACOHT6J", + "filament_id": "OFhWhL1i", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG Transition @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG Transition @System.json index 47245f3f54..890d68f491 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG Transition @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG Transition @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFRiFnfQ", - "setting_id": "BY3z4yKW9PQZwgto", "name": "Eolas Prints PETG Transition @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "BY3z4yKW9PQZwgto", + "filament_id": "OFRiFnfQ", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG UV Resistant @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG UV Resistant @System.json index 749b37cb54..8c50f37064 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG UV Resistant @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PETG UV Resistant @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFx8Lmsd", - "setting_id": "eexjO9xiesNROPCK", "name": "Eolas Prints PETG UV Resistant @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "eexjO9xiesNROPCK", + "filament_id": "OFx8Lmsd", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Antibacterial @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Antibacterial @System.json index a9cbc62ed2..46ebc7ae49 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Antibacterial @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Antibacterial @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFkzr35f", - "setting_id": "LAihILsSxo3djWjq", "name": "Eolas Prints PLA Antibacterial @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "LAihILsSxo3djWjq", + "filament_id": "OFkzr35f", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA High Speed @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA High Speed @System.json index 7488530282..2d6555bd1d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA High Speed @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA High Speed @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFvzvwCu", - "setting_id": "5g69jS4PRY0PbXvI", "name": "Eolas Prints PLA High Speed @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "5g69jS4PRY0PbXvI", + "filament_id": "OFvzvwCu", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 850 @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 850 @System.json index c4c66400e4..35bf1435e7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 850 @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 850 @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFH2nN08", - "setting_id": "jdjLUTsIovrt3UAF", "name": "Eolas Prints PLA INGEO 850 @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "jdjLUTsIovrt3UAF", + "filament_id": "OFH2nN08", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 870 @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 870 @System.json index f8ae8e662c..8e84babe2f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 870 @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA INGEO 870 @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFPc4zVY", - "setting_id": "AafBj7XbFWaNhKHu", "name": "Eolas Prints PLA INGEO 870 @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "AafBj7XbFWaNhKHu", + "filament_id": "OFPc4zVY", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Matte @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Matte @System.json index 9489d9f0f7..3b3bef69a4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Matte @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Matte @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFf5awy4", - "setting_id": "7LiJHuwirgABvbUa", "name": "Eolas Prints PLA Matte @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "7LiJHuwirgABvbUa", + "filament_id": "OFf5awy4", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Neon @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Neon @System.json index d6619b629c..034fe0d72f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Neon @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Neon @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFrFBEfd", - "setting_id": "sKgUBhF3VvETDkwg", "name": "Eolas Prints PLA Neon @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "sKgUBhF3VvETDkwg", + "filament_id": "OFrFBEfd", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Premium @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Premium @System.json index 03c332daa0..1ed527c6ad 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Premium @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Premium @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFtudokz", - "setting_id": "O2Ur7FIG2YlVEyZp", "name": "Eolas Prints PLA Premium @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "O2Ur7FIG2YlVEyZp", + "filament_id": "OFtudokz", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Silk @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Silk @System.json index b59d6ebf3d..e913c6a9d9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Silk @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Silk @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFbP8zEO", - "setting_id": "WN0GdqBsjhvnyDmG", "name": "Eolas Prints PLA Silk @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "WN0GdqBsjhvnyDmG", + "filament_id": "OFbP8zEO", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Transition @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Transition @System.json index 22bb2af20a..575d66d2dc 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Transition @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints PLA Transition @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFHfzQXo", - "setting_id": "o3RoG3NGSBlyBkfZ", "name": "Eolas Prints PLA Transition @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "o3RoG3NGSBlyBkfZ", + "filament_id": "OFHfzQXo", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex 93A @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex 93A @System.json index c2252c5df8..49643b7cc8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex 93A @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex 93A @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFhfd722", - "setting_id": "bQPvp6BCMzcG8FOi", "name": "Eolas Prints TPU Flex 93A @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "bQPvp6BCMzcG8FOi", + "filament_id": "OFhfd722", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D53 @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D53 @System.json index f6b85ebd29..3223cc6bb5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D53 @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D53 @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFIegjmD", - "setting_id": "XIFP4KMuMtXF5bjQ", "name": "Eolas Prints TPU Flex D53 @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "XIFP4KMuMtXF5bjQ", + "filament_id": "OFIegjmD", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D60 UV Resistant @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D60 UV Resistant @System.json index 4fc33c0d64..c8bdffbd3a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D60 UV Resistant @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Flex D60 UV Resistant @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFvVy7yo", - "setting_id": "rJmsm0zjvsk9Dy0G", "name": "Eolas Prints TPU D60 UV Resistant @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "rJmsm0zjvsk9Dy0G", + "filament_id": "OFvVy7yo", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Transition @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Transition @System.json index 31dd33a87d..b1f7114d15 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Transition @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Eolas Prints/Eolas Prints TPU Transition @System.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFTOPcx0", - "setting_id": "CM24KGoHLt0yLH93", "name": "Eolas Prints TPU Transition @System", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "CM24KGoHLt0yLH93", + "filament_id": "OFTOPcx0", + "instantiation": "true", "filament_color": [ "#4d9398" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @System.json index bea08bf527..364a065362 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @System.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "FILL3D PA @System", + "inherits": "FILL3D PA @base", "from": "system", "setting_id": "IX32M9Hib9UlDHuW", "instantiation": "true", - "inherits": "FILL3D PA @base", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @base.json index bb8f8905e3..2c243c8779 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PA @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PA @base", + "inherits": "fdm_filament_pa", "from": "system", "filament_id": "OFJNeELv", "instantiation": "false", - "inherits": "fdm_filament_pa", "filament_vendor": [ "FILL3D" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @System.json index 6600d5fc36..0b072d4941 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @System.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "FILL3D PETG @System", + "inherits": "FILL3D PETG @base", "from": "system", "setting_id": "f8kKGdxNz45g3xtZ", "instantiation": "true", - "inherits": "FILL3D PETG @base", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @base.json index f0a0e32f26..a38dadedc4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PETG @base", + "inherits": "fdm_filament_pet", "from": "system", "filament_id": "OFQbjX3s", "instantiation": "false", - "inherits": "fdm_filament_pet", "filament_vendor": [ "FILL3D" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @System.json index 093e6d0ba8..9d942e6968 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @System.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "FILL3D PETG CF @System", + "inherits": "FILL3D PETG CF @base", "from": "system", "setting_id": "MqNSM5lYck0H1Uyd", "instantiation": "true", - "inherits": "FILL3D PETG CF @base", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @base.json index 0d1dc4a737..1dfedb9045 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PETG CF @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PETG CF @base", + "inherits": "fdm_filament_pet", "from": "system", "filament_id": "OFOiJfLM", "instantiation": "false", - "inherits": "fdm_filament_pet", "filament_vendor": [ "FILL3D" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @System.json index cbe0c934f2..ded0d4cc51 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @System.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "FILL3D PLA Basic @System", + "inherits": "FILL3D PLA Basic @base", "from": "system", "setting_id": "b8Gq0WEZwF3Ty1As", "instantiation": "true", - "inherits": "FILL3D PLA Basic @base", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @base.json index 13d29eaaa8..a053c5278b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Basic @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PLA Basic @base", + "inherits": "fdm_filament_pla", "from": "system", "filament_id": "OFDpW3J8", "instantiation": "false", - "inherits": "fdm_filament_pla", "filament_vendor": [ "FILL3D" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @System.json index 6fa7fe2738..6e27267a87 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @System.json @@ -1,9 +1,9 @@ { "type": "filament", - "setting_id": "eWB0sfzKjOAnz8iy", "name": "FILL3D PLA Turbo @System", - "from": "system", - "instantiation": "true", "inherits": "FILL3D PLA Turbo @base", + "from": "system", + "setting_id": "eWB0sfzKjOAnz8iy", + "instantiation": "true", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @base.json index 38be0d7078..f31476056d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PLA Turbo @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PLA Turbo @base", + "inherits": "fdm_filament_pla", "from": "system", "filament_id": "OFoSknDB", "instantiation": "false", - "inherits": "fdm_filament_pla", "adaptive_pressure_advance": [ "1" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @System.json index 8a4e89650e..ab9792c196 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @System.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "FILL3D PP @System", + "inherits": "FILL3D PP @base", "from": "system", "setting_id": "7FAQwU4JwTfuaGa1", "instantiation": "true", - "inherits": "FILL3D PP @base", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @base.json index 708e4c50ec..991253f510 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PP @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PP @base", + "inherits": "fdm_filament_pp", "from": "system", "filament_id": "OFPWPlSC", "instantiation": "false", - "inherits": "fdm_filament_pp", "filament_vendor": [ "FILL3D" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @System.json index 313b3ff01b..2dc6362e5f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @System.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "FILL3D PPCF @System", + "inherits": "FILL3D PPCF @base", "from": "system", "setting_id": "CuI1vfvq3rjnqXQq", "instantiation": "true", - "inherits": "FILL3D PPCF @base", "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @base.json index 6d6aaf9e34..639a6981dd 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FILL3D/FILL3D PPCF @base.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "FILL3D PPCF @base", + "inherits": "fdm_filament_pp", "from": "system", "filament_id": "OFg8hMzT", "instantiation": "false", - "inherits": "fdm_filament_pp", "filament_vendor": [ "FILL3D" ], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG @base.json index 340dc5da23..d85a652fca 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG @base.json @@ -1,53 +1,53 @@ { - "type": "filament", - "name": "FilAr PETG @base", - "inherits": "fdm_filament_pet", - "from": "system", - "filament_id": "OF5rnhjh", - "instantiation": "false", - "filament_type": [ - "PETG" - ], - "filament_vendor": [ - "FilAr" - ], - "filament_diameter": [ - "1.75" - ], - "filament_density": [ - "1.27" - ], - "filament_flow_ratio": [ - "0.95" - ], - "nozzle_temperature": [ - "240" - ], - "nozzle_temperature_initial_layer": [ - "245" - ], - "nozzle_temperature_range_low": [ - "230" - ], - "nozzle_temperature_range_high": [ - "250" - ], - "hot_plate_temp": [ - "78" - ], - "hot_plate_temp_initial_layer": [ - "78" - ], - "textured_plate_temp": [ - "78" - ], - "textured_plate_temp_initial_layer": [ - "78" - ], - "fan_min_speed": [ - "40" - ], - "fan_max_speed": [ - "60" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG @base", + "inherits": "fdm_filament_pet", + "from": "system", + "filament_id": "OF5rnhjh", + "instantiation": "false", + "filament_type": [ + "PETG" + ], + "filament_vendor": [ + "FilAr" + ], + "filament_diameter": [ + "1.75" + ], + "filament_density": [ + "1.27" + ], + "filament_flow_ratio": [ + "0.95" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "245" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "hot_plate_temp": [ + "78" + ], + "hot_plate_temp_initial_layer": [ + "78" + ], + "textured_plate_temp": [ + "78" + ], + "textured_plate_temp_initial_layer": [ + "78" + ], + "fan_min_speed": [ + "40" + ], + "fan_max_speed": [ + "60" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Lima.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Lima.json index b1284f1d3d..6dba9cad51 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Lima.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Lima.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Amarillo Lima", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "QuJY74Af8ssl9uuB", - "filament_id": "OFt6e0US", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#C7E03A" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Amarillo Lima", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "QuJY74Af8ssl9uuB", + "filament_id": "OFt6e0US", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#C7E03A" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Radiante.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Radiante.json index 00e5af59a1..f40144889a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Radiante.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Amarillo Radiante.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Amarillo Radiante", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "aFO2PDBIQqvNlH9p", - "filament_id": "OF0Vtzaw", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FFD400" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Amarillo Radiante", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "aFO2PDBIQqvNlH9p", + "filament_id": "OF0Vtzaw", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FFD400" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Boreal.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Boreal.json index cbed2c3aa7..bbf4e876b2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Boreal.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Boreal.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Azul Boreal", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "JQsOaH7Zcs0cLLPY", - "filament_id": "OFNU9YIW", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#1B4F9C" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Azul Boreal", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "JQsOaH7Zcs0cLLPY", + "filament_id": "OFNU9YIW", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#1B4F9C" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Francia.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Francia.json index f2d8c16a43..c9919e6833 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Francia.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Francia.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Azul Francia", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "O24dTvHOzlbikvmq", - "filament_id": "OF44VYzK", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#0033A0" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Azul Francia", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "O24dTvHOzlbikvmq", + "filament_id": "OF44VYzK", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#0033A0" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Imperial.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Imperial.json index 8c917d750a..e71e68ae3f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Imperial.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Azul Imperial.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Azul Imperial", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "JAUmcvfO2lnmxGj5", - "filament_id": "OF2Z1nT5", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#14306B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Azul Imperial", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "JAUmcvfO2lnmxGj5", + "filament_id": "OF2Z1nT5", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#14306B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Blanco Antartida.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Blanco Antartida.json index c2bd7f3368..34e470b384 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Blanco Antartida.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Blanco Antartida.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Blanco Antartida", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "dd4fL2ztjz4UiTaG", - "filament_id": "OFsXQXbs", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#F7FAFC" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Blanco Antartida", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "dd4fL2ztjz4UiTaG", + "filament_id": "OFsXQXbs", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#F7FAFC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cian.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cian.json index ac1d1be6fe..52c4c8765e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cian.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cian.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Cian", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "kQFbBS3nxU7M2yPa", - "filament_id": "OFnejEt4", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#00B7D4" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Cian", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "kQFbBS3nxU7M2yPa", + "filament_id": "OFnejEt4", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#00B7D4" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Coral.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Coral.json index 9b3e380b57..a3795310ab 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Coral.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Coral.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Coral", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "fspbgXmAOWjFBQqh", - "filament_id": "OFysxCep", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FF6F5E" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Coral", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "fspbgXmAOWjFBQqh", + "filament_id": "OFysxCep", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FF6F5E" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cristal.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cristal.json index 1e7c947bea..3aa6ef6fe0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cristal.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Cristal.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Cristal", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "MnA2FnHdIuViwo41", - "filament_id": "OFJQDUk3", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E8F0EC" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Cristal", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "MnA2FnHdIuViwo41", + "filament_id": "OFJQDUk3", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E8F0EC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Ceniza.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Ceniza.json index c20eb5fcad..28205f3b09 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Ceniza.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Ceniza.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Gris Ceniza", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "oYjDczRs4U1JdteC", - "filament_id": "OFybzvQN", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#B4B6B1" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Gris Ceniza", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "oYjDczRs4U1JdteC", + "filament_id": "OFybzvQN", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#B4B6B1" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Plata.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Plata.json index 93335c7951..b013b19150 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Plata.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Gris Plata.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Gris Plata", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "eCJ5aFcQ00m97U35", - "filament_id": "OFgpLTMR", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#8C8686" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Gris Plata", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "eCJ5aFcQ00m97U35", + "filament_id": "OFgpLTMR", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#8C8686" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Magenta.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Magenta.json index 5a8ac777f5..ddca59214d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Magenta.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Magenta.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Magenta", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "CEOhwBE63SWwuh6P", - "filament_id": "OFurdQxc", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#B5174B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Magenta", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "CEOhwBE63SWwuh6P", + "filament_id": "OFurdQxc", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#B5174B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Negro Azabache.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Negro Azabache.json index 5cba6c4a02..a3325d5214 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Negro Azabache.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Negro Azabache.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Negro Azabache", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "OPZin7y48ZEeiH8D", - "filament_id": "OFq8gfS4", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#000000" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Negro Azabache", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "OPZin7y48ZEeiH8D", + "filament_id": "OFq8gfS4", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#000000" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Rojo Carmesi.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Rojo Carmesi.json index 3ed33ea0f9..aa00dbce0f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Rojo Carmesi.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PETG Rojo Carmesi.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PETG Rojo Carmesi", - "inherits": "FilAr PETG @base", - "from": "system", - "setting_id": "ok1h38XzyQXPBIMM", - "filament_id": "OFPbyOSk", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#8C1020" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PETG Rojo Carmesi", + "inherits": "FilAr PETG @base", + "from": "system", + "setting_id": "ok1h38XzyQXPBIMM", + "filament_id": "OFPbyOSk", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#8C1020" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA @base.json index c5ed35c1f1..547e5ab043 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA @base.json @@ -1,47 +1,47 @@ { - "type": "filament", - "name": "FilAr PLA @base", - "inherits": "fdm_filament_pla", - "from": "system", - "filament_id": "OF4KsW72", - "instantiation": "false", - "filament_type": [ - "PLA" - ], - "filament_vendor": [ - "FilAr" - ], - "filament_diameter": [ - "1.75" - ], - "filament_density": [ - "1.24" - ], - "filament_flow_ratio": [ - "0.98" - ], - "nozzle_temperature": [ - "210" - ], - "nozzle_temperature_initial_layer": [ - "215" - ], - "nozzle_temperature_range_low": [ - "200" - ], - "nozzle_temperature_range_high": [ - "220" - ], - "hot_plate_temp": [ - "60" - ], - "hot_plate_temp_initial_layer": [ - "60" - ], - "textured_plate_temp": [ - "60" - ], - "textured_plate_temp_initial_layer": [ - "60" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OF4KsW72", + "instantiation": "false", + "filament_type": [ + "PLA" + ], + "filament_vendor": [ + "FilAr" + ], + "filament_diameter": [ + "1.75" + ], + "filament_density": [ + "1.24" + ], + "filament_flow_ratio": [ + "0.98" + ], + "nozzle_temperature": [ + "210" + ], + "nozzle_temperature_initial_layer": [ + "215" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "nozzle_temperature_range_high": [ + "220" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Amarillo Lirio.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Amarillo Lirio.json index 1d6c41003b..e42c565e63 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Amarillo Lirio.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Amarillo Lirio.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Amarillo Lirio", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "sZEY2QrlLsDkgZin", - "filament_id": "OF8aFWfQ", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FFD52B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Amarillo Lirio", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "sZEY2QrlLsDkgZin", + "filament_id": "OF8aFWfQ", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FFD52B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Azul Francia.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Azul Francia.json index a2f84470c4..d369ea77c2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Azul Francia.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Azul Francia.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Azul Francia", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "kOF3UfqKVqWKFwiH", - "filament_id": "OFnYVFk2", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#0000FF" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Azul Francia", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "kOF3UfqKVqWKFwiH", + "filament_id": "OFnYVFk2", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#0000FF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Antartida.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Antartida.json index e9d68452dc..45f399f37f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Antartida.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Antartida.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Blanco Antartida", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "9KxtnS1WoUAgH323", - "filament_id": "OFHAccHz", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#F7FAFC" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Blanco Antartida", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "9KxtnS1WoUAgH323", + "filament_id": "OFHAccHz", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#F7FAFC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Calido.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Calido.json index 1166928647..ad66e02521 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Calido.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Blanco Calido.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Blanco Calido", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "pAToQatK3PVTMHrW", - "filament_id": "OFKTSiYF", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FFF8E7" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Blanco Calido", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "pAToQatK3PVTMHrW", + "filament_id": "OFKTSiYF", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FFF8E7" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Bronce.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Bronce.json index 599c64038c..51e2a4bb66 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Bronce.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Bronce.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Bronce", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "bJuNDmVGIF0TXvkk", - "filament_id": "OFWTRJ1K", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#AD8428" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Bronce", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "bJuNDmVGIF0TXvkk", + "filament_id": "OFWTRJ1K", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#AD8428" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cafe con Leche.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cafe con Leche.json index b70feb22d4..ffd0d08354 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cafe con Leche.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cafe con Leche.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Cafe con Leche", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "vlPu3T66cQhIr5nl", - "filament_id": "OFWwF7K7", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E0B269" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Cafe con Leche", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "vlPu3T66cQhIr5nl", + "filament_id": "OFWwF7K7", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E0B269" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Carpincho.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Carpincho.json index bdb948112a..538c7b23a7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Carpincho.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Carpincho.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Carpincho", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "dNsCH2BVjuq3jrN7", - "filament_id": "OFKWWgyp", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E8DFC1" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Carpincho", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "dNsCH2BVjuq3jrN7", + "filament_id": "OFKWWgyp", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E8DFC1" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Celeste Cielo.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Celeste Cielo.json index f0ca1c323c..a836b2da5b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Celeste Cielo.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Celeste Cielo.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Celeste Cielo", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "baAQZuzRZD0nwmqH", - "filament_id": "OFaDOaNt", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#A1EBFF" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Celeste Cielo", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "baAQZuzRZD0nwmqH", + "filament_id": "OFaDOaNt", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#A1EBFF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cobre.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cobre.json index 44402e7b5a..387493e380 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cobre.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Cobre.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Cobre", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "BpYgVH5d3LOdib3U", - "filament_id": "OFNemJM6", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#87421E" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Cobre", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "BpYgVH5d3LOdib3U", + "filament_id": "OFNemJM6", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#87421E" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Dorado.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Dorado.json index fd25d70050..a1aefcad52 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Dorado.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Dorado.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Dorado", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "KHIdy0oNw9YYDNOD", - "filament_id": "OF5P4jgA", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#A67F00" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Dorado", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "KHIdy0oNw9YYDNOD", + "filament_id": "OF5P4jgA", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#A67F00" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Ceniza.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Ceniza.json index d09d053c53..ae41bd4072 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Ceniza.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Ceniza.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Gris Ceniza", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "LBpWNtHWPyZi96wr", - "filament_id": "OFIamQnD", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#B4B6B1" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Gris Ceniza", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "LBpWNtHWPyZi96wr", + "filament_id": "OFIamQnD", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#B4B6B1" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Pizarra.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Pizarra.json index c6809d1104..ea38dedda9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Pizarra.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Pizarra.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Gris Pizarra", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "SeePXOShT3cge6TS", - "filament_id": "OFTlRzpe", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#4B4B4B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Gris Pizarra", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "SeePXOShT3cge6TS", + "filament_id": "OFTlRzpe", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#4B4B4B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Plata.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Plata.json index 3748c83352..4091ccc39f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Plata.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Gris Plata.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Gris Plata", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "B6HABCdHSblZS7lQ", - "filament_id": "OFKKajh6", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#8C8686" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Gris Plata", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "B6HABCdHSblZS7lQ", + "filament_id": "OFKKajh6", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#8C8686" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Manteca.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Manteca.json index 81c6eb5928..792fb3a0c8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Manteca.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Manteca.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Manteca", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "tR4io22VQO0J8UsV", - "filament_id": "OFexaZU2", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FFF5AB" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Manteca", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "tR4io22VQO0J8UsV", + "filament_id": "OFexaZU2", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FFF5AB" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Marron Oxido.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Marron Oxido.json index 452b48010d..9c8f6f9b3f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Marron Oxido.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Marron Oxido.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Marron Oxido", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "r9eviTeCeTW4rLuz", - "filament_id": "OFAt6ec0", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#5E190E" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Marron Oxido", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "r9eviTeCeTW4rLuz", + "filament_id": "OFAt6ec0", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#5E190E" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Naranja Tigre.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Naranja Tigre.json index dd5475f0c6..d42a83f938 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Naranja Tigre.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Naranja Tigre.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Naranja Tigre", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "zLZxXa78e1oiYWSg", - "filament_id": "OFKZ9skj", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FC5017" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Naranja Tigre", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "zLZxXa78e1oiYWSg", + "filament_id": "OFKZ9skj", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FC5017" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Negro Azabache.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Negro Azabache.json index aaf06f8833..782e2bc624 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Negro Azabache.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Negro Azabache.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Negro Azabache", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "glc7ip75qjodcceS", - "filament_id": "OFgMWJ8T", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#000000" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Negro Azabache", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "glc7ip75qjodcceS", + "filament_id": "OFgMWJ8T", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#000000" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Oro.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Oro.json index 03e171b525..2102a321b8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Oro.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Oro.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Oro", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "hCv43F2tNJagwzC7", - "filament_id": "OF5nlfKY", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FFD700" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Oro", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "hCv43F2tNJagwzC7", + "filament_id": "OF5nlfKY", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FFD700" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Piel.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Piel.json index 4ae2924081..46556f00b8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Piel.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Piel.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Piel", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "6ZwTYvV27Oj3l33v", - "filament_id": "OFsDXRpS", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FADDAC" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Piel", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "6ZwTYvV27Oj3l33v", + "filament_id": "OFsDXRpS", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FADDAC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rojo de Carreras.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rojo de Carreras.json index 95c3c870bc..358ad6769e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rojo de Carreras.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rojo de Carreras.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Rojo de Carreras", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "5dINxIgy0kMYYNDT", - "filament_id": "OFaEesXQ", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FA0F0F" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Rojo de Carreras", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "5dINxIgy0kMYYNDT", + "filament_id": "OFaEesXQ", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FA0F0F" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Amaranto.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Amaranto.json index 62763f36a5..7bc5f981ba 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Amaranto.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Amaranto.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Rosa Amaranto", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "wgxgJfhOa2ZPikRH", - "filament_id": "OFPqX3x2", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FA4164" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Rosa Amaranto", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "wgxgJfhOa2ZPikRH", + "filament_id": "OFPqX3x2", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FA4164" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Flamenco.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Flamenco.json index 9fb203bb0c..2ca378da29 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Flamenco.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Rosa Flamenco.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Rosa Flamenco", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "FhROwdLMSz3cyRZo", - "filament_id": "OFZ4QbfK", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#FFC7C2" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Rosa Flamenco", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "FhROwdLMSz3cyRZo", + "filament_id": "OFZ4QbfK", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#FFC7C2" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Tabaco.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Tabaco.json index 6925843d95..3cb6d377b5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Tabaco.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Tabaco.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Tabaco", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "6ax7ka7LBHqhBigT", - "filament_id": "OFjT9PkZ", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#7D5429" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Tabaco", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "6ax7ka7LBHqhBigT", + "filament_id": "OFjT9PkZ", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#7D5429" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Titanio.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Titanio.json index f7b823fe5b..b687dd6726 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Titanio.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Titanio.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Titanio", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "ZRedeSWJhUayeJLw", - "filament_id": "OFQWIKbV", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#878681" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Titanio", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "ZRedeSWJhUayeJLw", + "filament_id": "OFQWIKbV", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#878681" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde FilAr.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde FilAr.json index e3355ffa43..d4f853d0a7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde FilAr.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde FilAr.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Verde FilAr", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "SYWoimklLqx5O2Xh", - "filament_id": "OFvPPMxL", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#036D6B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Verde FilAr", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "SYWoimklLqx5O2Xh", + "filament_id": "OFvPPMxL", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#036D6B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Manzana.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Manzana.json index 46772cf083..0d2c420f7d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Manzana.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Manzana.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Verde Manzana", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "FlPRrQEcKnVKwJDM", - "filament_id": "OFdb8YNz", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#D4FF38" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Verde Manzana", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "FlPRrQEcKnVKwJDM", + "filament_id": "OFdb8YNz", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#D4FF38" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Oliva.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Oliva.json index 6fe74aa2f3..c1cf89131d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Oliva.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Oliva.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Verde Oliva", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "eWAcT15sDLZeV2uS", - "filament_id": "OFkoLUtR", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#595900" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Verde Oliva", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "eWAcT15sDLZeV2uS", + "filament_id": "OFkoLUtR", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#595900" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Pixel.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Pixel.json index 9068b293f2..1ae9dbcac8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Pixel.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Verde Pixel.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Verde Pixel", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "Z7toK1R2GuzHVgfo", - "filament_id": "OFkGvN4d", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#02E32F" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Verde Pixel", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "Z7toK1R2GuzHVgfo", + "filament_id": "OFkGvN4d", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#02E32F" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Violeta Jacaranda.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Violeta Jacaranda.json index fa12bcc077..d79155046b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Violeta Jacaranda.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA Violeta Jacaranda.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA Violeta Jacaranda", - "inherits": "FilAr PLA @base", - "from": "system", - "setting_id": "4VO2Qb2cTXQ1TJv2", - "filament_id": "OFP26zNb", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#9342C9" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA Violeta Jacaranda", + "inherits": "FilAr PLA @base", + "from": "system", + "setting_id": "4VO2Qb2cTXQ1TJv2", + "filament_id": "OFP26zNb", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#9342C9" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate @base.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate @base.json index 972f5a4220..669e40909b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate @base.json @@ -1,47 +1,47 @@ { - "type": "filament", - "name": "FilAr PLA-mate @base", - "inherits": "fdm_filament_pla", - "from": "system", - "filament_id": "OFtOoWIj", - "instantiation": "false", - "filament_type": [ - "PLA" - ], - "filament_vendor": [ - "FilAr" - ], - "filament_diameter": [ - "1.75" - ], - "filament_density": [ - "1.24" - ], - "filament_flow_ratio": [ - "0.98" - ], - "nozzle_temperature": [ - "200" - ], - "nozzle_temperature_initial_layer": [ - "205" - ], - "nozzle_temperature_range_low": [ - "195" - ], - "nozzle_temperature_range_high": [ - "210" - ], - "hot_plate_temp": [ - "50" - ], - "hot_plate_temp_initial_layer": [ - "50" - ], - "textured_plate_temp": [ - "50" - ], - "textured_plate_temp_initial_layer": [ - "50" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFtOoWIj", + "instantiation": "false", + "filament_type": [ + "PLA" + ], + "filament_vendor": [ + "FilAr" + ], + "filament_diameter": [ + "1.75" + ], + "filament_density": [ + "1.24" + ], + "filament_flow_ratio": [ + "0.98" + ], + "nozzle_temperature": [ + "200" + ], + "nozzle_temperature_initial_layer": [ + "205" + ], + "nozzle_temperature_range_low": [ + "195" + ], + "nozzle_temperature_range_high": [ + "210" + ], + "hot_plate_temp": [ + "50" + ], + "hot_plate_temp_initial_layer": [ + "50" + ], + "textured_plate_temp": [ + "50" + ], + "textured_plate_temp_initial_layer": [ + "50" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Amarillo.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Amarillo.json index 98a2349ac1..d9efefd3f7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Amarillo.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Amarillo.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Amarillo", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "f8DPrkYuTUPJ3cru", - "filament_id": "OFj3bTjw", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E8C547" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Amarillo", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "f8DPrkYuTUPJ3cru", + "filament_id": "OFj3bTjw", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E8C547" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Azul.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Azul.json index 7688708656..2b384f61c5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Azul.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Azul.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Azul", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "QMBocqysEed86R9y", - "filament_id": "OF5vgi2G", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#2D5DA8" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Azul", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "QMBocqysEed86R9y", + "filament_id": "OF5vgi2G", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#2D5DA8" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Beige.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Beige.json index 2324dadcc5..0a95d908ae 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Beige.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Beige.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Beige", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "XoilIv3HqpDTVRwv", - "filament_id": "OFGcLA5R", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#D8C4A0" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Beige", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "XoilIv3HqpDTVRwv", + "filament_id": "OFGcLA5R", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#D8C4A0" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Blanco.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Blanco.json index 92f10acf51..26d6aa37d5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Blanco.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Blanco.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Blanco", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "xkotTQheAIUUhPd7", - "filament_id": "OFtefokm", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#F2F2EC" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Blanco", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "xkotTQheAIUUhPd7", + "filament_id": "OFtefokm", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#F2F2EC" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Bordo.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Bordo.json index 4018c1d710..9ab337468d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Bordo.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Bordo.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Bordo", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "zV2dKrknk0ThDv36", - "filament_id": "OFiDpM1B", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#6E1A2B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Bordo", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "zV2dKrknk0ThDv36", + "filament_id": "OFiDpM1B", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#6E1A2B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Celeste Cielo.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Celeste Cielo.json index ff47203106..38e041c79e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Celeste Cielo.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Celeste Cielo.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Celeste Cielo", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "UZW4F0aVz1TqstYi", - "filament_id": "OFqtx549", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#9DC8E8" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Celeste Cielo", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "UZW4F0aVz1TqstYi", + "filament_id": "OFqtx549", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#9DC8E8" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Chocolate.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Chocolate.json index b67e57db85..071bcf600e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Chocolate.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Chocolate.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Chocolate", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "DdW1XKqqRuLM1cAd", - "filament_id": "OFdzlrhi", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#4A2E22" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Chocolate", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "DdW1XKqqRuLM1cAd", + "filament_id": "OFdzlrhi", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#4A2E22" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Gris.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Gris.json index 445a44b1e4..d1615e94f2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Gris.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Gris.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Gris", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "6OtKg1UxWuNCqsZy", - "filament_id": "OFGVwfK0", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#7E7E7E" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Gris", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "6OtKg1UxWuNCqsZy", + "filament_id": "OFGVwfK0", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#7E7E7E" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Marron.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Marron.json index aa411c3d77..289b15449a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Marron.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Marron.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Marron", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "lKOXMY37q8WpMdBA", - "filament_id": "OF8jh0Lk", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#6B4226" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Marron", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "lKOXMY37q8WpMdBA", + "filament_id": "OF8jh0Lk", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#6B4226" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Naranja.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Naranja.json index 2c382c085d..e817ce8b25 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Naranja.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Naranja.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Naranja", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "MabNpNP8G9RqEruP", - "filament_id": "OFmaeU4a", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E0662A" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Naranja", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "MabNpNP8G9RqEruP", + "filament_id": "OFmaeU4a", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E0662A" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Negro.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Negro.json index 7ec4105a25..2827d288d7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Negro.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Negro.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Negro", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "Jwrm1uuCo7UjvgWn", - "filament_id": "OFufTAK9", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#1A1A1A" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Negro", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "Jwrm1uuCo7UjvgWn", + "filament_id": "OFufTAK9", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#1A1A1A" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Piel.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Piel.json index 6635fe8b78..641e338dea 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Piel.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Piel.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Piel", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "ifbCS3WypTUa1JHr", - "filament_id": "OFfZcoKr", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E8C9A8" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Piel", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "ifbCS3WypTUa1JHr", + "filament_id": "OFfZcoKr", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E8C9A8" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rojo.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rojo.json index bed097ad9a..780517616f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rojo.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rojo.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Rojo", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "ak2QX0IS74Nmtyex", - "filament_id": "OFIBXa0k", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#B5302E" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Rojo", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "ak2QX0IS74Nmtyex", + "filament_id": "OFIBXa0k", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#B5302E" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rosa.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rosa.json index 1767674916..1f5848e668 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rosa.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Rosa.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Rosa", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "GrEXuL6TYue238MK", - "filament_id": "OFausr3F", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#E07A9B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Rosa", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "GrEXuL6TYue238MK", + "filament_id": "OFausr3F", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#E07A9B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Uva.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Uva.json index 0e5bb137e1..bd12219417 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Uva.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Uva.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Uva", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "PK1CsK7AS1p1IJaR", - "filament_id": "OFEZ449N", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#5B2A6B" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Uva", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "PK1CsK7AS1p1IJaR", + "filament_id": "OFEZ449N", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#5B2A6B" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Verde.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Verde.json index 67fe0ebfee..6b9d58ddac 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Verde.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Verde.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Verde", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "rsLi8jr62hHPgERG", - "filament_id": "OFCjG251", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#3A7D44" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Verde", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "rsLi8jr62hHPgERG", + "filament_id": "OFCjG251", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#3A7D44" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Violeta.json b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Violeta.json index e842875905..1b3f32860f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Violeta.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/FilAr/FilAr PLA-mate Violeta.json @@ -1,15 +1,15 @@ { - "type": "filament", - "name": "FilAr PLA-mate Violeta", - "inherits": "FilAr PLA-mate @base", - "from": "system", - "setting_id": "z2Pk06JzY9Tr1WjQ", - "filament_id": "OF2EK9F1", - "instantiation": "true", - "filament_vendor": [ - "FilAr" - ], - "default_filament_colour": [ - "#6B3FA0" - ] -} \ No newline at end of file + "type": "filament", + "name": "FilAr PLA-mate Violeta", + "inherits": "FilAr PLA-mate @base", + "from": "system", + "setting_id": "z2Pk06JzY9Tr1WjQ", + "filament_id": "OF2EK9F1", + "instantiation": "true", + "filament_vendor": [ + "FilAr" + ], + "default_filament_colour": [ + "#6B3FA0" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic ABS @System.json index e499fa3a73..bdffbd3398 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic ABS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic ABS @System.json @@ -7,5 +7,21 @@ "setting_id": "W0LP8Ah5MHMzogvV", "filament_id": "OFY9muEs", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "12", + "20", + "25", + "12", + "18", + "18" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic ASA @System.json index f55ee5e239..4262791b9d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic ASA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic ASA @System.json @@ -7,5 +7,21 @@ "setting_id": "bcsNcj4DzLb4K5zN", "filament_id": "OFLPAxz3", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "12", + "20", + "25", + "12", + "20", + "20" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic BVOH @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic BVOH @System.json index 7b34746bb2..20445bfecb 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic BVOH @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic BVOH @System.json @@ -6,5 +6,13 @@ "setting_id": "oUpbqz3uzQqND5DG", "filament_id": "OFo2UF2C", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic CoPE @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic CoPE @System.json index 60c330fc39..19d55ea479 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic CoPE @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic CoPE @System.json @@ -6,5 +6,13 @@ "setting_id": "KlHtaJU2GM0uaRGM", "filament_id": "OFjt9en1", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic EVA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic EVA @System.json index 646bef3f28..f0c9e0e16f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic EVA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic EVA @System.json @@ -7,5 +7,13 @@ "filament_id": "OFCD8qiU", "instantiation": "true", "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic HIPS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic HIPS @System.json index c4acb079be..ff885839f9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic HIPS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic HIPS @System.json @@ -6,5 +6,21 @@ "setting_id": "A7gedcxip65DXKuf", "filament_id": "OFsFon5l", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "8", + "13", + "13", + "8", + "13", + "13" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PA @System.json index 4bea15a407..3e9b42ad65 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PA @System.json @@ -7,5 +7,21 @@ "setting_id": "9DoeedUBMRPSCyu2", "filament_id": "OFg8ndtj", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "8", + "12", + "12", + "8", + "12", + "12" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PA-CF @System.json index 0e653e5529..74036889c0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PA-CF @System.json @@ -7,10 +7,23 @@ "setting_id": "rchW8WI6gcXuAE0V", "filament_id": "OFQLcbps", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_type": [ "PA-CF" ], "filament_multitool_ramming_flow": [ + "8", + "8", + "8", + "8", + "8", "8" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PC @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PC @System.json index f84c7fe7b6..bd4d19e935 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PC @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PC @System.json @@ -7,5 +7,21 @@ "setting_id": "LNjv9LwZnbu7ZASC", "filament_id": "OFLakOUI", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "12", + "20", + "30", + "12", + "20", + "20" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PCTG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PCTG @System.json index 41ff08bd5c..717f111802 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PCTG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PCTG @System.json @@ -6,5 +6,21 @@ "setting_id": "21dhMVBuVwR2lzIX", "filament_id": "OFu1evlr", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "12", + "18", + "18", + "12", + "15", + "15" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PE @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PE @System.json index 210c48b77a..c8297957b4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PE @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PE @System.json @@ -7,5 +7,13 @@ "filament_id": "OFPklMI1", "instantiation": "true", "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PE-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PE-CF @base.json index 53ca2e0f9d..a67219ac82 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PE-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PE-CF @base.json @@ -5,6 +5,14 @@ "from": "system", "filament_id": "OFd0Fv0k", "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_type": [ "PE-CF" ] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG @System.json index f6fb133324..8b34215571 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG @System.json @@ -7,5 +7,21 @@ "setting_id": "YiQZfhL6hH0giSHL", "filament_id": "OFYPdQJh", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "10", + "18", + "21", + "10", + "15", + "15" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @System.json index 63472f65a0..3c787ca1d8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @System.json @@ -6,9 +6,19 @@ "setting_id": "wNH8CohYIh9y6ayx", "instantiation": "true", "filament_max_volumetric_speed": [ - "20" + "20", + "26", + "30", + "20", + "21", + "21" ], "filament_multitool_ramming_flow": [ + "20", + "20", + "20", + "20", + "20", "20" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @base.json index 173f397a49..d5557c9176 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG HF @base.json @@ -4,5 +4,13 @@ "inherits": "fdm_filament_pet", "from": "system", "filament_id": "OF7lOgYF", - "instantiation": "false" + "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @System.json index aea01d2740..f7536223af 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @System.json @@ -9,15 +9,35 @@ "30" ], "fan_max_speed": [ + "40", + "40", + "40", + "40", + "40", "40" ], "fan_min_speed": [ + "5", + "5", + "5", + "5", + "5", "5" ], "filament_max_volumetric_speed": [ + "11.5", + "11.5", + "11.5", + "11.5", + "11.5", "11.5" ], "filament_multitool_ramming_flow": [ + "13", + "13", + "13", + "13", + "13", "13" ], "overhang_fan_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @base.json index 8bf644a26d..13c3ab8234 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PETG-CF @base.json @@ -5,6 +5,14 @@ "from": "system", "filament_id": "OFoYSJKi", "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_type": [ "PETG-CF" ] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PHA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PHA @System.json index c50840c55a..d8d8b19d88 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PHA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PHA @System.json @@ -7,5 +7,13 @@ "filament_id": "OF74KeQR", "instantiation": "true", "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA @System.json index 7bf0a0e72b..c5274780f3 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA @System.json @@ -7,5 +7,21 @@ "setting_id": "RcBNzytWgwRrwXXz", "filament_id": "OFDSrzZ8", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "12", + "21", + "40", + "12", + "21", + "30" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA High Speed @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA High Speed @System.json index ccd8205595..90aee0b556 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA High Speed @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA High Speed @System.json @@ -6,13 +6,36 @@ "setting_id": "L9wOwDxavVR7vrL7", "filament_id": "OFmpMwxS", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.98", + "0.98", + "0.98", + "0.98", + "0.98", "0.98" ], "filament_max_volumetric_speed": [ - "18" + "18", + "25", + "40", + "18", + "25", + "30" ], "filament_multitool_ramming_flow": [ + "25", + "25", + "25", + "25", + "25", "25" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @System.json index 2bb0e98e58..800f9f4e0a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @System.json @@ -6,12 +6,27 @@ "setting_id": "RFs9eCKYOMUSmvZf", "instantiation": "true", "filament_max_volumetric_speed": [ - "11" + "11", + "19.5", + "40", + "11", + "19.5", + "25" ], "filament_multitool_ramming_flow": [ + "11", + "11", + "11", + "11", + "11", "11" ], "filament_retraction_length": [ + "0.8", + "0.8", + "0.8", + "0.8", + "0.8", "0.8" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @base.json index 7fed10e48e..debc41c3ff 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Matte @base.json @@ -4,5 +4,13 @@ "inherits": "fdm_filament_pla", "from": "system", "filament_id": "OFmY0l6t", - "instantiation": "false" + "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Silk @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Silk @System.json index 3bee7ccde6..32fbeccf4c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Silk @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA Silk @System.json @@ -7,10 +7,28 @@ "setting_id": "oPkXDCBrTQB3SRm4", "filament_id": "OFesA6rF", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_max_volumetric_speed": [ + "7.5", + "7.5", + "7.5", + "7.5", + "7.5", "7.5" ], "filament_retraction_length": [ + "0.5", + "0.5", + "0.5", + "0.5", + "0.5", "0.5" ], "compatible_printers": [] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA-CF @System.json index 972ef33800..5d7df3c446 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PLA-CF @System.json @@ -7,11 +7,32 @@ "setting_id": "l2LkEql1SVH0iRqY", "filament_id": "OFWbdGsC", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_flow_ratio": [ + "0.95", + "0.95", + "0.95", + "0.95", + "0.95", "0.95" ], "filament_type": [ "PLA-CF" ], - "compatible_printers": [] + "compatible_printers": [], + "filament_max_volumetric_speed": [ + "12", + "18", + "18", + "12", + "18", + "18" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP @System.json index 14e38bc340..869b02e807 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP @System.json @@ -7,5 +7,13 @@ "filament_id": "OF1UNk9P", "instantiation": "true", "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @System.json index 3f2ee9f3f0..4c035469ed 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @System.json @@ -13,9 +13,19 @@ "1.01" ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_multitool_ramming_flow": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @base.json index 1852185476..92f65b3da2 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-CF @base.json @@ -5,6 +5,14 @@ "from": "system", "filament_id": "OFXkm8q1", "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_type": [ "PP-CF" ] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @System.json index d9bedf9316..c24caddef0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @System.json @@ -13,9 +13,19 @@ "1.05" ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_multitool_ramming_flow": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @base.json index 958fbc75a6..0c3873595d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PP-GF @base.json @@ -5,6 +5,14 @@ "from": "system", "filament_id": "OFsijjtH", "instantiation": "false", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_type": [ "PP-GF" ] diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-CF @System.json index 99ee7acda7..a909c0bc38 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-CF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-CF @System.json @@ -7,9 +7,27 @@ "filament_id": "OF8tPByX", "instantiation": "true", "fan_max_speed": [ + "35", + "35", + "35", + "35", + "35", "35" ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_max_volumetric_speed": [ + "6.5", + "6.5", + "6.5", + "6.5", + "6.5", "6.5" ], "overhang_fan_threshold": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-GF @System.json index 3b5e1b7583..1a93e1db6b 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-GF @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PPA-GF @System.json @@ -6,7 +6,20 @@ "setting_id": "yJCAFLt5wstMgMAY", "filament_id": "OF8Tlg47", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], "filament_max_volumetric_speed": [ + "6", + "6", + "6", + "6", + "6", "6" ], "filament_type": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic PVA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic PVA @System.json index c6300423ba..bd34a8405e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic PVA @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic PVA @System.json @@ -7,5 +7,21 @@ "setting_id": "1dlLnJKh1HzQCZVJ", "filament_id": "OFDvXujf", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ], + "filament_max_volumetric_speed": [ + "4", + "4", + "4", + "4", + "4", + "4" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic SBS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic SBS @System.json index cf5aa1a8f6..8d754ab3c7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic SBS @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic SBS @System.json @@ -6,5 +6,13 @@ "setting_id": "fjVWcIfxaOAZHNU1", "filament_id": "OFhQfUQY", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Generic TPU @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Generic TPU @System.json index c8ae9f2562..2a22351156 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Generic TPU @System.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Generic TPU @System.json @@ -7,5 +7,13 @@ "setting_id": "D6O8IcmSe8WGqOvb", "filament_id": "OFgbpcy9", "instantiation": "true", - "compatible_printers": [] + "compatible_printers": [], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Extra High Flow", + "Bowden Standard", + "Bowden High Flow", + "Bowden Extra High Flow" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @BBL P2S.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @BBL P2S.json index b183295021..cbd4beb609 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @BBL P2S.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @BBL P2S.json @@ -1,275 +1,295 @@ { - "type": "filament", - "name": "INSLOGIC PA6-66 @BBL P2S", - "inherits": "INSLOGIC PA6-66 @base", - "from": "system", - "setting_id": "UHHdgZgE7e8KR2GV", - "instantiation": "true", - "activate_air_filtration": [ - "1" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "close_fan_the_first_x_layers": [ - "1" - ], - "close_additional_fan_first_x_layers": [ - "3" - ], - "complete_print_exhaust_fan_speed": [ - "70" - ], - "cool_plate_temp": [ - "0" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "during_print_exhaust_fan_speed": [ - "70" - ], - "eng_plate_temp": [ - "50" - ], - "eng_plate_temp_initial_layer": [ - "50" - ], - "fan_cooling_layer_time": [ - "20" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "filament_adaptive_volumetric_speed": [ - "0" - ], - "filament_extruder_compatibility": [ - "0" - ], - "filament_cooling_before_tower": [ - "10", - "10" - ], - "filament_preheat_temperature_delta": [ - "0" - ], - "filament_tower_interface_pre_extrusion_dist": [ - "10" - ], - "filament_tower_interface_pre_extrusion_length": [ - "0" - ], - "filament_tower_ironing_area": [ - "4" - ], - "filament_tower_interface_purge_volume": [ - "20" - ], - "filament_tower_interface_print_temp": [ - "-1" - ], - "filament_density": [ - "1.10" - ], - "filament_dev_ams_drying_ams_limitations": [ - "1" - ], - "filament_dev_ams_drying_heat_distortion_temperature": [ - "90" - ], - "filament_dev_ams_drying_temperature": [ - "65", - "80", - "65", - "80" - ], - "filament_dev_ams_drying_time": [ - "12", - "12", - "12", - "12" - ], - "filament_dev_chamber_drying_bed_temperature": [ - "90.0" - ], - "filament_dev_chamber_drying_time": [ - "18" - ], - "filament_dev_drying_cooling_temperature": [ - "65" - ], - "filament_dev_drying_softening_temperature": [ - "85" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "filament_flush_temp": [ - "0" - ], - "filament_flush_temp_fast": [ - "0" - ], - "filament_flush_volumetric_speed": [ - "0" - ], - "filament_is_support": [ - "0" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_pre_cooling_temperature": [ - "0" - ], - "filament_pre_cooling_temperature_nc": [ - "0" - ], - "filament_prime_volume": [ - "45" - ], - "filament_prime_volume_nc": [ - "60" - ], - "filament_printable": [ - "3" - ], - "filament_ramming_travel_time_nc": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1" - ], - "filament_ramming_volumetric_speed_nc": [ - "-1" - ], - "filament_scarf_seam_type": [ - "none" - ], - "filament_shrink": [ - "100%" - ], - "filament_soluble": [ - "0" - ], - "full_fan_speed_layer": [ - "0" - ], - "additional_fan_full_speed_layer": [ - "0" - ], - "filament_scarf_height": [ - "10%" - ], - "filament_scarf_gap": [ - "0%" - ], - "filament_scarf_length": [ - "10" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_retract_length_nc": [ - "14" - ], - "filament_change_length": [ - "10" - ], - "hot_plate_temp": [ - "50" - ], - "hot_plate_temp_initial_layer": [ - "50" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "nozzle_temperature": [ - "255", - "255" - ], - "nozzle_temperature_initial_layer": [ - "255", - "255" - ], - "nozzle_temperature_range_high": [ - "280" - ], - "nozzle_temperature_range_low": [ - "250" - ], - "overhang_fan_speed": [ - "95" - ], - "overhang_fan_threshold": [ - "10%" - ], - "reduce_fan_stop_start_freq": [ - "0" - ], - "required_nozzle_HRC": [ - "3" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "slow_down_layer_time": [ - "6" - ], - "slow_down_min_speed": [ - "10" - ], - "supertack_plate_temp": [ - "0" - ], - "supertack_plate_temp_initial_layer": [ - "0" - ], - "temperature_vitrification": [ - "74.2" - ], - "textured_plate_temp": [ - "50" - ], - "textured_plate_temp_initial_layer": [ - "50" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0" - ], - "filament_start_gcode": [ - "; Filament gcode\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n" - ], - "filament_end_gcode": [ - "; filament end gcode \n\n" - ], - "filament_adhesiveness_category": [ - "400" - ], - "idle_temperature": [ - "0" - ], - "compatible_printers": [ - "Bambu Lab P2S 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PA6-66 @BBL P2S", + "inherits": "INSLOGIC PA6-66 @base", + "from": "system", + "setting_id": "UHHdgZgE7e8KR2GV", + "instantiation": "true", + "activate_air_filtration": [ + "1", + "1" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "close_additional_fan_first_x_layers": [ + "3" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70" + ], + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70" + ], + "eng_plate_temp": [ + "50" + ], + "eng_plate_temp_initial_layer": [ + "50" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_compatibility": [ + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_preheat_temperature_delta": [ + "0", + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_density": [ + "1.10" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_chamber_drying_bed_temperature": [ + "90.0" + ], + "filament_dev_chamber_drying_time": [ + "18" + ], + "filament_dev_drying_cooling_temperature": [ + "65" + ], + "filament_dev_drying_softening_temperature": [ + "85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_temp_fast": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_is_support": [ + "0" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_prime_volume": [ + "45" + ], + "filament_prime_volume_nc": [ + "60" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_scarf_seam_type": [ + "none" + ], + "filament_shrink": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "full_fan_speed_layer": [ + "0" + ], + "additional_fan_full_speed_layer": [ + "0" + ], + "filament_scarf_height": [ + "10%" + ], + "filament_scarf_gap": [ + "0%" + ], + "filament_scarf_length": [ + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_change_length": [ + "10" + ], + "hot_plate_temp": [ + "50" + ], + "hot_plate_temp_initial_layer": [ + "50" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "nozzle_temperature_range_high": [ + "280", + "280" + ], + "nozzle_temperature_range_low": [ + "250", + "250" + ], + "overhang_fan_speed": [ + "95" + ], + "overhang_fan_threshold": [ + "10%" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "10" + ], + "supertack_plate_temp": [ + "0" + ], + "supertack_plate_temp_initial_layer": [ + "0" + ], + "temperature_vitrification": [ + "74.2" + ], + "textured_plate_temp": [ + "50" + ], + "textured_plate_temp_initial_layer": [ + "50" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "filament_start_gcode": [ + "; Filament gcode\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n\n" + ], + "filament_adhesiveness_category": [ + "400" + ], + "idle_temperature": [ + "0" + ], + "compatible_printers": [ + "Bambu Lab P2S 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @P1-X1.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @P1-X1.json index fa71bcc4b7..96a607e349 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @P1-X1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-66 @P1-X1.json @@ -1,210 +1,215 @@ { - "type": "filament", - "name": "INSLOGIC PA6-66 @P1-X1", - "inherits": "INSLOGIC PA6-66 @base", - "from": "system", - "setting_id": "X6EcSgHdfuxoY1lL", - "instantiation": "true", - "cool_plate_temp": [ - "0" - ], - "eng_plate_temp": [ - "40" - ], - "hot_plate_temp": [ - "50" - ], - "textured_plate_temp": [ - "50" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp_initial_layer": [ - "40" - ], - "hot_plate_temp_initial_layer": [ - "50" - ], - "textured_plate_temp_initial_layer": [ - "50" - ], - "overhang_fan_threshold": [ - "95%" - ], - "overhang_fan_speed": [ - "100" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "3" - ], - "filament_end_gcode": [ - "; filament end gcode \n" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "fan_cooling_layer_time": [ - "15" - ], - "filament_density": [ - "1.2" - ], - "filament_deretraction_speed": [ - "nil", - "nil" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_retraction_minimum_travel": [ - "nil", - "nil" - ], - "filament_retract_before_wipe": [ - "nil", - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil", - "nil" - ], - "filament_retraction_length": [ - "1", - "1" - ], - "filament_z_hop": [ - "nil", - "nil" - ], - "filament_z_hop_types": [ - "nil", - "nil" - ], - "filament_retract_restart_extra": [ - "nil", - "nil" - ], - "filament_retraction_speed": [ - "nil", - "nil" - ], - "filament_soluble": [ - "0" - ], - "filament_wipe": [ - "nil", - "nil" - ], - "filament_wipe_distance": [ - "nil", - "nil" - ], - "nozzle_temperature_initial_layer": [ - "255", - "255" - ], - "full_fan_speed_layer": [ - "2" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "slow_down_min_speed": [ - "10" - ], - "slow_down_layer_time": [ - "2" - ], - "filament_start_gcode": [ - "; Filament gcode\n" - ], - "nozzle_temperature": [ - "255", - "255" - ], - "temperature_vitrification": [ - "70.4" - ], - "nozzle_temperature_range_low": [ - "250", - "250" - ], - "nozzle_temperature_range_high": [ - "280", - "280" - ], - "filament_flush_temp": [ - "0", - "0" - ], - "filament_flush_volumetric_speed": [ - "0", - "0" - ], - "filament_long_retractions_when_cut": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1", - "-1" - ], - "filament_retraction_distances_when_cut": [ - "nil", - "nil" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "filament_pre_cooling_temperature": [ - "0", - "0" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0", - "0 0 0 0 0 0" - ], - "idle_temperature": [ - "0" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle", - "Bambu Lab X1 Carbon 0.4 nozzle", - "Bambu Lab P1S 0.4 nozzle", - "Bambu Lab X1E 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PA6-66 @P1-X1", + "inherits": "INSLOGIC PA6-66 @base", + "from": "system", + "setting_id": "X6EcSgHdfuxoY1lL", + "instantiation": "true", + "cool_plate_temp": [ + "0" + ], + "eng_plate_temp": [ + "40" + ], + "hot_plate_temp": [ + "50" + ], + "textured_plate_temp": [ + "50" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "50" + ], + "textured_plate_temp_initial_layer": [ + "50" + ], + "overhang_fan_threshold": [ + "95%" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_cooling_layer_time": [ + "15" + ], + "filament_density": [ + "1.2" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_soluble": [ + "0" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "full_fan_speed_layer": [ + "2" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "2" + ], + "filament_start_gcode": [ + "; Filament gcode\n" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "temperature_vitrification": [ + "70.4" + ], + "nozzle_temperature_range_low": [ + "250", + "250" + ], + "nozzle_temperature_range_high": [ + "280", + "280" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "idle_temperature": [ + "0" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "compatible_printers": [ + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab X1E 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @BBL P2S.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @BBL P2S.json index 91c7c2bdbd..3a8fad133d 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @BBL P2S.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @BBL P2S.json @@ -1,275 +1,295 @@ { - "type": "filament", - "name": "INSLOGIC PA6-CF @BBL P2S", - "inherits": "INSLOGIC PA6-CF @base", - "from": "system", - "setting_id": "Km9iCy4A8kukE0AA", - "instantiation": "true", - "activate_air_filtration": [ - "1" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "close_fan_the_first_x_layers": [ - "1" - ], - "close_additional_fan_first_x_layers": [ - "3" - ], - "complete_print_exhaust_fan_speed": [ - "70" - ], - "cool_plate_temp": [ - "0" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "during_print_exhaust_fan_speed": [ - "70" - ], - "eng_plate_temp": [ - "65" - ], - "eng_plate_temp_initial_layer": [ - "65" - ], - "fan_cooling_layer_time": [ - "20" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "filament_adaptive_volumetric_speed": [ - "0" - ], - "filament_extruder_compatibility": [ - "0" - ], - "filament_cooling_before_tower": [ - "10", - "10" - ], - "filament_preheat_temperature_delta": [ - "0" - ], - "filament_tower_interface_pre_extrusion_dist": [ - "10" - ], - "filament_tower_interface_pre_extrusion_length": [ - "0" - ], - "filament_tower_ironing_area": [ - "4" - ], - "filament_tower_interface_purge_volume": [ - "20" - ], - "filament_tower_interface_print_temp": [ - "-1" - ], - "filament_density": [ - "1.12" - ], - "filament_dev_ams_drying_ams_limitations": [ - "1" - ], - "filament_dev_ams_drying_heat_distortion_temperature": [ - "90" - ], - "filament_dev_ams_drying_temperature": [ - "65", - "80", - "65", - "80" - ], - "filament_dev_ams_drying_time": [ - "12", - "12", - "12", - "12" - ], - "filament_dev_chamber_drying_bed_temperature": [ - "90.0" - ], - "filament_dev_chamber_drying_time": [ - "18" - ], - "filament_dev_drying_cooling_temperature": [ - "65" - ], - "filament_dev_drying_softening_temperature": [ - "85" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "filament_flush_temp": [ - "0" - ], - "filament_flush_temp_fast": [ - "0" - ], - "filament_flush_volumetric_speed": [ - "0" - ], - "filament_is_support": [ - "0" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_pre_cooling_temperature": [ - "0" - ], - "filament_pre_cooling_temperature_nc": [ - "0" - ], - "filament_prime_volume": [ - "45" - ], - "filament_prime_volume_nc": [ - "60" - ], - "filament_printable": [ - "3" - ], - "filament_ramming_travel_time_nc": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1" - ], - "filament_ramming_volumetric_speed_nc": [ - "-1" - ], - "filament_scarf_seam_type": [ - "none" - ], - "filament_shrink": [ - "100%" - ], - "filament_soluble": [ - "0" - ], - "full_fan_speed_layer": [ - "0" - ], - "additional_fan_full_speed_layer": [ - "0" - ], - "filament_scarf_height": [ - "10%" - ], - "filament_scarf_gap": [ - "0%" - ], - "filament_scarf_length": [ - "10" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_retract_length_nc": [ - "14" - ], - "filament_change_length": [ - "10" - ], - "hot_plate_temp": [ - "65" - ], - "hot_plate_temp_initial_layer": [ - "65" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "nozzle_temperature": [ - "275", - "275" - ], - "nozzle_temperature_initial_layer": [ - "280", - "280" - ], - "nozzle_temperature_range_high": [ - "290" - ], - "nozzle_temperature_range_low": [ - "270" - ], - "overhang_fan_speed": [ - "95" - ], - "overhang_fan_threshold": [ - "10%" - ], - "reduce_fan_stop_start_freq": [ - "0" - ], - "required_nozzle_HRC": [ - "3" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "slow_down_layer_time": [ - "6" - ], - "slow_down_min_speed": [ - "10" - ], - "supertack_plate_temp": [ - "0" - ], - "supertack_plate_temp_initial_layer": [ - "0" - ], - "temperature_vitrification": [ - "74.2" - ], - "textured_plate_temp": [ - "65" - ], - "textured_plate_temp_initial_layer": [ - "65" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0" - ], - "filament_start_gcode": [ - "; Filament gcode\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n" - ], - "filament_end_gcode": [ - "; filament end gcode \n\n" - ], - "filament_adhesiveness_category": [ - "400" - ], - "idle_temperature": [ - "0" - ], - "compatible_printers": [ - "Bambu Lab P2S 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PA6-CF @BBL P2S", + "inherits": "INSLOGIC PA6-CF @base", + "from": "system", + "setting_id": "Km9iCy4A8kukE0AA", + "instantiation": "true", + "activate_air_filtration": [ + "1", + "1" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "close_additional_fan_first_x_layers": [ + "3" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70" + ], + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70" + ], + "eng_plate_temp": [ + "65" + ], + "eng_plate_temp_initial_layer": [ + "65" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_compatibility": [ + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_preheat_temperature_delta": [ + "0", + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_density": [ + "1.12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_chamber_drying_bed_temperature": [ + "90.0" + ], + "filament_dev_chamber_drying_time": [ + "18" + ], + "filament_dev_drying_cooling_temperature": [ + "65" + ], + "filament_dev_drying_softening_temperature": [ + "85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_temp_fast": [ + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_is_support": [ + "0" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_prime_volume": [ + "45" + ], + "filament_prime_volume_nc": [ + "60" + ], + "filament_printable": [ + "3" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_scarf_seam_type": [ + "none" + ], + "filament_shrink": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "full_fan_speed_layer": [ + "0" + ], + "additional_fan_full_speed_layer": [ + "0" + ], + "filament_scarf_height": [ + "10%" + ], + "filament_scarf_gap": [ + "0%" + ], + "filament_scarf_length": [ + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_change_length": [ + "10" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "nozzle_temperature": [ + "275", + "275" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280" + ], + "nozzle_temperature_range_high": [ + "290", + "290" + ], + "nozzle_temperature_range_low": [ + "270", + "270" + ], + "overhang_fan_speed": [ + "95" + ], + "overhang_fan_threshold": [ + "10%" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "required_nozzle_HRC": [ + "3" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "10" + ], + "supertack_plate_temp": [ + "0" + ], + "supertack_plate_temp_initial_layer": [ + "0" + ], + "temperature_vitrification": [ + "74.2" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "filament_start_gcode": [ + "; Filament gcode\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n\n" + ], + "filament_adhesiveness_category": [ + "400" + ], + "idle_temperature": [ + "0" + ], + "compatible_printers": [ + "Bambu Lab P2S 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @P1-X1.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @P1-X1.json index c95e5d3f97..87c0461e53 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @P1-X1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PA6-CF @P1-X1.json @@ -1,210 +1,215 @@ { - "type": "filament", - "name": "INSLOGIC PA6-CF @P1-X1", - "inherits": "INSLOGIC PA6-CF @base", - "from": "system", - "setting_id": "ky3k6Q9Fyi3QwCHL", - "instantiation": "true", - "cool_plate_temp": [ - "0" - ], - "eng_plate_temp": [ - "40" - ], - "hot_plate_temp": [ - "65" - ], - "textured_plate_temp": [ - "65" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp_initial_layer": [ - "40" - ], - "hot_plate_temp_initial_layer": [ - "65" - ], - "textured_plate_temp_initial_layer": [ - "65" - ], - "overhang_fan_threshold": [ - "95%" - ], - "overhang_fan_speed": [ - "100" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "3" - ], - "filament_end_gcode": [ - "; filament end gcode \n" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "fan_cooling_layer_time": [ - "15" - ], - "filament_density": [ - "1.2" - ], - "filament_deretraction_speed": [ - "nil", - "nil" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_retraction_minimum_travel": [ - "nil", - "nil" - ], - "filament_retract_before_wipe": [ - "nil", - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil", - "nil" - ], - "filament_retraction_length": [ - "1", - "1" - ], - "filament_z_hop": [ - "nil", - "nil" - ], - "filament_z_hop_types": [ - "nil", - "nil" - ], - "filament_retract_restart_extra": [ - "nil", - "nil" - ], - "filament_retraction_speed": [ - "nil", - "nil" - ], - "filament_soluble": [ - "0" - ], - "filament_wipe": [ - "nil", - "nil" - ], - "filament_wipe_distance": [ - "nil", - "nil" - ], - "nozzle_temperature_initial_layer": [ - "280", - "280" - ], - "full_fan_speed_layer": [ - "2" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "slow_down_min_speed": [ - "10" - ], - "slow_down_layer_time": [ - "2" - ], - "filament_start_gcode": [ - "; Filament gcode\n" - ], - "nozzle_temperature": [ - "275", - "275" - ], - "temperature_vitrification": [ - "70.4" - ], - "nozzle_temperature_range_low": [ - "270", - "270" - ], - "nozzle_temperature_range_high": [ - "290", - "290" - ], - "filament_flush_temp": [ - "0", - "0" - ], - "filament_flush_volumetric_speed": [ - "0", - "0" - ], - "filament_long_retractions_when_cut": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1", - "-1" - ], - "filament_retraction_distances_when_cut": [ - "nil", - "nil" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "filament_pre_cooling_temperature": [ - "0", - "0" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0", - "0 0 0 0 0 0" - ], - "idle_temperature": [ - "0" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle", - "Bambu Lab X1 Carbon 0.4 nozzle", - "Bambu Lab P1S 0.4 nozzle", - "Bambu Lab X1E 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PA6-CF @P1-X1", + "inherits": "INSLOGIC PA6-CF @base", + "from": "system", + "setting_id": "ky3k6Q9Fyi3QwCHL", + "instantiation": "true", + "cool_plate_temp": [ + "0" + ], + "eng_plate_temp": [ + "40" + ], + "hot_plate_temp": [ + "65" + ], + "textured_plate_temp": [ + "65" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "overhang_fan_threshold": [ + "95%" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_cooling_layer_time": [ + "15" + ], + "filament_density": [ + "1.2" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_soluble": [ + "0" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280" + ], + "full_fan_speed_layer": [ + "2" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "2" + ], + "filament_start_gcode": [ + "; Filament gcode\n" + ], + "nozzle_temperature": [ + "275", + "275" + ], + "temperature_vitrification": [ + "70.4" + ], + "nozzle_temperature_range_low": [ + "270", + "270" + ], + "nozzle_temperature_range_high": [ + "290", + "290" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "idle_temperature": [ + "0" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "compatible_printers": [ + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab X1E 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @BBL P2S.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @BBL P2S.json index f654aa67f8..5cfadde8ee 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @BBL P2S.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @BBL P2S.json @@ -1,328 +1,349 @@ { - "type": "filament", - "name": "INSLOGIC PETG Pro @BBL P2S", - "inherits": "INSLOGIC PETG Pro @base", - "from": "system", - "setting_id": "6iAMtvQjja2ZKenA", - "instantiation": "true", - "cool_plate_temp": [ - "0" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp": [ - "70" - ], - "eng_plate_temp_initial_layer": [ - "70" - ], - "fan_cooling_layer_time": [ - "25" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "hot_plate_temp": [ - "70" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "nozzle_temperature_range_high": [ - "260" - ], - "overhang_fan_speed": [ - "100" - ], - "overhang_fan_threshold": [ - "95%" - ], - "slow_down_layer_time": [ - "8" - ], - "slow_down_min_speed": [ - "20", - "20" - ], - "textured_plate_temp": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "filament_deretraction_speed": [ - "nil", - "nil" - ], - "filament_flush_temp": [ - "0" - ], - "filament_flush_volumetric_speed": [ - "0" - ], - "filament_long_retractions_when_cut": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1" - ], - "filament_ramming_volumetric_speed_nc": [ - "-1" - ], - "filament_retract_before_wipe": [ - "nil", - "nil" - ], - "filament_retract_restart_extra": [ - "nil", - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil", - "nil" - ], - "filament_retraction_distances_when_cut": [ - "nil", - "nil" - ], - "filament_retraction_length": [ - "nil", - "nil" - ], - "filament_retraction_minimum_travel": [ - "nil", - "nil" - ], - "filament_retraction_speed": [ - "nil", - "nil" - ], - "filament_wipe": [ - "nil", - "nil" - ], - "filament_wipe_distance": [ - "nil", - "nil" - ], - "filament_z_hop": [ - "nil", - "nil" - ], - "filament_z_hop_types": [ - "nil", - "nil" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "first_x_layer_fan_speed": [ - "0" - ], - "filament_pre_cooling_temperature": [ - "0" - ], - "filament_pre_cooling_temperature_nc": [ - "0" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_ramming_travel_time_nc": [ - "0" - ], - "filament_adaptive_volumetric_speed": [ - "0" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "nozzle_temperature": [ - "245", - "245" - ], - "nozzle_temperature_initial_layer": [ - "245", - "245" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0" - ], - "activate_air_filtration": [ - "0" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "close_fan_the_first_x_layers": [ - "1" - ], - "close_additional_fan_first_x_layers": [ - "3" - ], - "complete_print_exhaust_fan_speed": [ - "70" - ], - "during_print_exhaust_fan_speed": [ - "70" - ], - "filament_extruder_compatibility": [ - "0" - ], - "filament_cooling_before_tower": [ - "10", - "10" - ], - "filament_preheat_temperature_delta": [ - "0" - ], - "filament_tower_interface_pre_extrusion_dist": [ - "10" - ], - "filament_tower_interface_pre_extrusion_length": [ - "0" - ], - "filament_tower_ironing_area": [ - "4" - ], - "filament_tower_interface_purge_volume": [ - "20" - ], - "filament_tower_interface_print_temp": [ - "-1" - ], - "filament_density": [ - "1.28" - ], - "filament_dev_ams_drying_ams_limitations": [ - "1", - "0" - ], - "filament_dev_ams_drying_heat_distortion_temperature": [ - "75" - ], - "filament_dev_ams_drying_temperature": [ - "65", - "65", - "55", - "55" - ], - "filament_dev_ams_drying_time": [ - "12", - "12", - "12", - "12" - ], - "filament_dev_chamber_drying_bed_temperature": [ - "80" - ], - "filament_dev_chamber_drying_time": [ - "12.0" - ], - "filament_dev_drying_cooling_temperature": [ - "55" - ], - "filament_dev_drying_softening_temperature": [ - "60" - ], - "filament_is_support": [ - "0" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_prime_volume": [ - "45" - ], - "filament_prime_volume_nc": [ - "60" - ], - "filament_printable": [ - "3" - ], - "filament_scarf_seam_type": [ - "none" - ], - "filament_shrink": [ - "100%" - ], - "filament_soluble": [ - "0" - ], - "full_fan_speed_layer": [ - "0" - ], - "additional_fan_full_speed_layer": [ - "0" - ], - "filament_scarf_height": [ - "10%" - ], - "filament_scarf_gap": [ - "0%" - ], - "filament_scarf_length": [ - "10" - ], - "filament_retract_length_nc": [ - "14" - ], - "filament_change_length": [ - "10" - ], - "nozzle_temperature_range_low": [ - "240" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "required_nozzle_HRC": [ - "3" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "supertack_plate_temp": [ - "70" - ], - "supertack_plate_temp_initial_layer": [ - "70" - ], - "temperature_vitrification": [ - "81" - ], - "filament_start_gcode": [ - "; Filament gcode\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n" - ], - "filament_end_gcode": [ - "; filament end gcode \n\n" - ], - "filament_adhesiveness_category": [ - "300" - ], - "idle_temperature": [ - "0" - ], - "compatible_printers": [ - "Bambu Lab P2S 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PETG Pro @BBL P2S", + "inherits": "INSLOGIC PETG Pro @base", + "from": "system", + "setting_id": "6iAMtvQjja2ZKenA", + "instantiation": "true", + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "25" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "nozzle_temperature_range_high": [ + "260", + "260" + ], + "overhang_fan_speed": [ + "100" + ], + "overhang_fan_threshold": [ + "95%" + ], + "slow_down_layer_time": [ + "8" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "activate_air_filtration": [ + "0", + "0" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "close_additional_fan_first_x_layers": [ + "3" + ], + "complete_print_exhaust_fan_speed": [ + "70", + "70" + ], + "during_print_exhaust_fan_speed": [ + "70", + "70" + ], + "filament_extruder_compatibility": [ + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_preheat_temperature_delta": [ + "0", + "0" + ], + "filament_tower_interface_pre_extrusion_dist": [ + "10" + ], + "filament_tower_interface_pre_extrusion_length": [ + "0" + ], + "filament_tower_ironing_area": [ + "4" + ], + "filament_tower_interface_purge_volume": [ + "20" + ], + "filament_tower_interface_print_temp": [ + "-1" + ], + "filament_density": [ + "1.28" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "75" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "65", + "55", + "55" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_chamber_drying_bed_temperature": [ + "80" + ], + "filament_dev_chamber_drying_time": [ + "12.0" + ], + "filament_dev_drying_cooling_temperature": [ + "55" + ], + "filament_dev_drying_softening_temperature": [ + "60" + ], + "filament_is_support": [ + "0" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_prime_volume": [ + "45" + ], + "filament_prime_volume_nc": [ + "60" + ], + "filament_printable": [ + "3" + ], + "filament_scarf_seam_type": [ + "none" + ], + "filament_shrink": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "full_fan_speed_layer": [ + "0" + ], + "additional_fan_full_speed_layer": [ + "0" + ], + "filament_scarf_height": [ + "10%" + ], + "filament_scarf_gap": [ + "0%" + ], + "filament_scarf_length": [ + "10" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_change_length": [ + "10" + ], + "nozzle_temperature_range_low": [ + "240", + "240" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "3" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "supertack_plate_temp": [ + "70" + ], + "supertack_plate_temp_initial_layer": [ + "70" + ], + "temperature_vitrification": [ + "81" + ], + "filament_start_gcode": [ + "; Filament gcode\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on chamber cooling fan\nM106 P10 S0 ; turn off left aux fan\nM142 P6 R30 S40 U0.3 V0.8 ; set PETG exhaust chamber autocooling\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n\n" + ], + "filament_adhesiveness_category": [ + "300" + ], + "idle_temperature": [ + "0" + ], + "compatible_printers": [ + "Bambu Lab P2S 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @P1-X1.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @P1-X1.json index 01411d237f..1e441cfcb9 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @P1-X1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PETG Pro @P1-X1.json @@ -1,210 +1,215 @@ { - "type": "filament", - "name": "INSLOGIC PETG Pro @P1-X1", - "inherits": "INSLOGIC PETG Pro @base", - "from": "system", - "setting_id": "miOBX0bGzziXI6SE", - "instantiation": "true", - "cool_plate_temp": [ - "0" - ], - "eng_plate_temp": [ - "40" - ], - "hot_plate_temp": [ - "70" - ], - "textured_plate_temp": [ - "70" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp_initial_layer": [ - "40" - ], - "hot_plate_temp_initial_layer": [ - "70" - ], - "textured_plate_temp_initial_layer": [ - "70" - ], - "overhang_fan_threshold": [ - "95%" - ], - "overhang_fan_speed": [ - "100" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "3" - ], - "filament_end_gcode": [ - "; filament end gcode \n" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "fan_cooling_layer_time": [ - "15" - ], - "filament_density": [ - "1.2" - ], - "filament_deretraction_speed": [ - "nil", - "nil" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_retraction_minimum_travel": [ - "nil", - "nil" - ], - "filament_retract_before_wipe": [ - "nil", - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil", - "nil" - ], - "filament_retraction_length": [ - "1", - "1" - ], - "filament_z_hop": [ - "nil", - "nil" - ], - "filament_z_hop_types": [ - "nil", - "nil" - ], - "filament_retract_restart_extra": [ - "nil", - "nil" - ], - "filament_retraction_speed": [ - "nil", - "nil" - ], - "filament_soluble": [ - "0" - ], - "filament_wipe": [ - "nil", - "nil" - ], - "filament_wipe_distance": [ - "nil", - "nil" - ], - "nozzle_temperature_initial_layer": [ - "245", - "245" - ], - "full_fan_speed_layer": [ - "2" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "slow_down_min_speed": [ - "10" - ], - "slow_down_layer_time": [ - "2" - ], - "filament_start_gcode": [ - "; Filament gcode\n" - ], - "nozzle_temperature": [ - "245", - "245" - ], - "temperature_vitrification": [ - "70.4" - ], - "nozzle_temperature_range_low": [ - "240", - "240" - ], - "nozzle_temperature_range_high": [ - "260", - "260" - ], - "filament_flush_temp": [ - "0", - "0" - ], - "filament_flush_volumetric_speed": [ - "0", - "0" - ], - "filament_long_retractions_when_cut": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1", - "-1" - ], - "filament_retraction_distances_when_cut": [ - "nil", - "nil" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "filament_pre_cooling_temperature": [ - "0", - "0" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0", - "0 0 0 0 0 0" - ], - "idle_temperature": [ - "0" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle", - "Bambu Lab X1 Carbon 0.4 nozzle", - "Bambu Lab P1S 0.4 nozzle", - "Bambu Lab X1E 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PETG Pro @P1-X1", + "inherits": "INSLOGIC PETG Pro @base", + "from": "system", + "setting_id": "miOBX0bGzziXI6SE", + "instantiation": "true", + "cool_plate_temp": [ + "0" + ], + "eng_plate_temp": [ + "40" + ], + "hot_plate_temp": [ + "70" + ], + "textured_plate_temp": [ + "70" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "overhang_fan_threshold": [ + "95%" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_cooling_layer_time": [ + "15" + ], + "filament_density": [ + "1.2" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_soluble": [ + "0" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "full_fan_speed_layer": [ + "2" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "2" + ], + "filament_start_gcode": [ + "; Filament gcode\n" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "temperature_vitrification": [ + "70.4" + ], + "nozzle_temperature_range_low": [ + "240", + "240" + ], + "nozzle_temperature_range_high": [ + "260", + "260" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "idle_temperature": [ + "0" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "compatible_printers": [ + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab X1E 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @BBL P2S.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @BBL P2S.json index 88c69393b9..443fd76caa 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @BBL P2S.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @BBL P2S.json @@ -1,190 +1,193 @@ { - "type": "filament", - "name": "INSLOGIC PLA Pro @BBL P2S", - "inherits": "INSLOGIC PLA Pro @base", - "from": "system", - "setting_id": "UAd1QXW7vm9gwoEc", - "instantiation": "true", - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_scarf_seam_type": [ - "all" - ], - "filament_scarf_height": [ - "10%" - ], - "filament_scarf_gap": [ - "0%" - ], - "filament_scarf_length": [ - "10" - ], - "filament_change_length": [ - "5" - ], - "filament_prime_volume": [ - "30" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" - ], - "eng_plate_temp": [ - "55" - ], - "eng_plate_temp_initial_layer": [ - "55" - ], - "filament_deretraction_speed": [ - "nil", - "nil" - ], - "filament_flush_temp": [ - "0", - "0" - ], - "filament_flush_volumetric_speed": [ - "0", - "0" - ], - "filament_long_retractions_when_cut": [ - "nil", - "nil" - ], - "filament_ramming_volumetric_speed": [ - "-1", - "-1" - ], - "filament_ramming_volumetric_speed_nc": [ - "-1", - "-1" - ], - "filament_retract_before_wipe": [ - "nil", - "nil" - ], - "filament_retract_restart_extra": [ - "nil", - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil", - "nil" - ], - "filament_retraction_distances_when_cut": [ - "10", - "10" - ], - "filament_retraction_length": [ - "1", - "1" - ], - "filament_retraction_minimum_travel": [ - "nil", - "nil" - ], - "filament_retraction_speed": [ - "nil", - "nil" - ], - "filament_wipe": [ - "nil", - "nil" - ], - "filament_wipe_distance": [ - "nil", - "nil" - ], - "filament_z_hop": [ - "nil", - "nil" - ], - "filament_z_hop_types": [ - "nil", - "nil" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "first_x_layer_fan_speed": [ - "40" - ], - "filament_pre_cooling_temperature": [ - "0", - "0" - ], - "filament_pre_cooling_temperature_nc": [ - "0", - "0" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_ramming_travel_time_nc": [ - "0", - "0" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "nozzle_temperature": [ - "215", - "215" - ], - "nozzle_temperature_initial_layer": [ - "215", - "215" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0", - "0 0 0 0 0 0" - ], - "nozzle_temperature_range_low": [ - "205", - "205" - ], - "nozzle_temperature_range_high": [ - "245", - "245" - ], - "hot_plate_temp": [ - "55" - ], - "hot_plate_temp_initial_layer": [ - "55" - ], - "textured_plate_temp": [ - "55" - ], - "textured_plate_temp_initial_layer": [ - "55" - ], - "fan_min_speed": [ - "60" - ], - "fan_max_speed": [ - "100" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "compatible_printers": [ - "Bambu Lab P2S 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PLA Pro @BBL P2S", + "inherits": "INSLOGIC PLA Pro @base", + "from": "system", + "setting_id": "UAd1QXW7vm9gwoEc", + "instantiation": "true", + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_scarf_seam_type": [ + "all" + ], + "filament_scarf_height": [ + "10%" + ], + "filament_scarf_gap": [ + "0%" + ], + "filament_scarf_length": [ + "10" + ], + "filament_change_length": [ + "5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "10", + "10" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "first_x_layer_fan_speed": [ + "40" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "nozzle_temperature": [ + "215", + "215" + ], + "nozzle_temperature_initial_layer": [ + "215", + "215" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature_range_low": [ + "205", + "205" + ], + "nozzle_temperature_range_high": [ + "245", + "245" + ], + "hot_plate_temp": [ + "55" + ], + "hot_plate_temp_initial_layer": [ + "55" + ], + "textured_plate_temp": [ + "55" + ], + "textured_plate_temp_initial_layer": [ + "55" + ], + "fan_min_speed": [ + "60", + "60" + ], + "fan_max_speed": [ + "100", + "100" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "compatible_printers": [ + "Bambu Lab P2S 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @P1-X1.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @P1-X1.json index db92a68125..90ce6f5192 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @P1-X1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/BBL/INSLOGIC PLA Pro @P1-X1.json @@ -1,210 +1,215 @@ { - "type": "filament", - "name": "INSLOGIC PLA Pro @P1-X1", - "inherits": "INSLOGIC PLA Pro @base", - "from": "system", - "setting_id": "InmXr3LoNKKDfnQu", - "instantiation": "true", - "cool_plate_temp": [ - "0" - ], - "eng_plate_temp": [ - "40" - ], - "hot_plate_temp": [ - "55" - ], - "textured_plate_temp": [ - "55" - ], - "cool_plate_temp_initial_layer": [ - "0" - ], - "eng_plate_temp_initial_layer": [ - "40" - ], - "hot_plate_temp_initial_layer": [ - "55" - ], - "textured_plate_temp_initial_layer": [ - "55" - ], - "overhang_fan_threshold": [ - "95%" - ], - "overhang_fan_speed": [ - "100" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "3" - ], - "filament_end_gcode": [ - "; filament end gcode \n" - ], - "filament_flow_ratio": [ - "0.98", - "0.98" - ], - "reduce_fan_stop_start_freq": [ - "1" - ], - "fan_cooling_layer_time": [ - "15" - ], - "filament_density": [ - "1.2" - ], - "filament_deretraction_speed": [ - "nil", - "nil" - ], - "filament_max_volumetric_speed": [ - "12", - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_retraction_minimum_travel": [ - "nil", - "nil" - ], - "filament_retract_before_wipe": [ - "nil", - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil", - "nil" - ], - "filament_retraction_length": [ - "1", - "1" - ], - "filament_z_hop": [ - "nil", - "nil" - ], - "filament_z_hop_types": [ - "nil", - "nil" - ], - "filament_retract_restart_extra": [ - "nil", - "nil" - ], - "filament_retraction_speed": [ - "nil", - "nil" - ], - "filament_soluble": [ - "0" - ], - "filament_wipe": [ - "nil", - "nil" - ], - "filament_wipe_distance": [ - "nil", - "nil" - ], - "nozzle_temperature_initial_layer": [ - "215", - "215" - ], - "full_fan_speed_layer": [ - "2" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "60" - ], - "slow_down_min_speed": [ - "10" - ], - "slow_down_layer_time": [ - "2" - ], - "filament_start_gcode": [ - "; Filament gcode\n" - ], - "nozzle_temperature": [ - "215", - "215" - ], - "temperature_vitrification": [ - "70.4" - ], - "nozzle_temperature_range_low": [ - "205", - "205" - ], - "nozzle_temperature_range_high": [ - "245", - "245" - ], - "filament_flush_temp": [ - "0", - "0" - ], - "filament_flush_volumetric_speed": [ - "0", - "0" - ], - "filament_long_retractions_when_cut": [ - "0" - ], - "filament_ramming_volumetric_speed": [ - "-1", - "-1" - ], - "filament_retraction_distances_when_cut": [ - "nil", - "nil" - ], - "filament_extruder_variant": [ - "Direct Drive Standard", - "Direct Drive High Flow" - ], - "filament_pre_cooling_temperature": [ - "0", - "0" - ], - "filament_ramming_travel_time": [ - "0", - "0" - ], - "filament_adaptive_volumetric_speed": [ - "0", - "0" - ], - "long_retractions_when_ec": [ - "0", - "0" - ], - "retraction_distances_when_ec": [ - "0", - "0" - ], - "volumetric_speed_coefficients": [ - "0 0 0 0 0 0", - "0 0 0 0 0 0" - ], - "idle_temperature": [ - "0" - ], - "additional_cooling_fan_speed": [ - "70" - ], - "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle", - "Bambu Lab X1 Carbon 0.4 nozzle", - "Bambu Lab P1S 0.4 nozzle", - "Bambu Lab X1E 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PLA Pro @P1-X1", + "inherits": "INSLOGIC PLA Pro @base", + "from": "system", + "setting_id": "InmXr3LoNKKDfnQu", + "instantiation": "true", + "cool_plate_temp": [ + "0" + ], + "eng_plate_temp": [ + "40" + ], + "hot_plate_temp": [ + "55" + ], + "textured_plate_temp": [ + "55" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp_initial_layer": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "55" + ], + "textured_plate_temp_initial_layer": [ + "55" + ], + "overhang_fan_threshold": [ + "95%" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "fan_cooling_layer_time": [ + "15" + ], + "filament_density": [ + "1.2" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15", + "15" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_soluble": [ + "0" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "nozzle_temperature_initial_layer": [ + "215", + "215" + ], + "full_fan_speed_layer": [ + "2" + ], + "fan_max_speed": [ + "100", + "100" + ], + "fan_min_speed": [ + "60", + "60" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "2" + ], + "filament_start_gcode": [ + "; Filament gcode\n" + ], + "nozzle_temperature": [ + "215", + "215" + ], + "temperature_vitrification": [ + "70.4" + ], + "nozzle_temperature_range_low": [ + "205", + "205" + ], + "nozzle_temperature_range_high": [ + "245", + "245" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "idle_temperature": [ + "0" + ], + "additional_cooling_fan_speed": [ + "70", + "70" + ], + "compatible_printers": [ + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab X1E 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-66 @base.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-66 @base.json index 952f927479..f5eedf33d8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-66 @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-66 @base.json @@ -1,36 +1,36 @@ { - "type": "filament", - "name": "INSLOGIC PA6-66 @base", - "inherits": "fdm_filament_pa", - "from": "system", - "filament_id": "OF02mnRc", - "instantiation": "false", - "filament_vendor": [ - "INSLOGIC" - ], - "filament_type": [ - "PA" - ], - "filament_density": [ - "1.08" - ], - "filament_diameter": [ - "1.75" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_soluble": [ - "0" - ], - "nozzle_temperature_range_low": [ - "250" - ], - "nozzle_temperature_range_high": [ - "280" - ], - "filament_notes": [ - "Inslogic Nylon PA6/66 TDS (20.01.2025). Nozzle sizes 0.2/0.4/0.6mm. Nozzle 250-280C. Bed 30-50C. Printing speed 50-150mm/s. Cooling fan 100%. Textured PEI Sheet. Drying 80C for 48h or 110C for 3h. TDS linear speed is not converted to filament_max_volumetric_speed." - ], - "compatible_printers": [] + "type": "filament", + "name": "INSLOGIC PA6-66 @base", + "inherits": "fdm_filament_pa", + "from": "system", + "filament_id": "OF02mnRc", + "instantiation": "false", + "filament_vendor": [ + "INSLOGIC" + ], + "filament_type": [ + "PA" + ], + "filament_density": [ + "1.08" + ], + "filament_diameter": [ + "1.75" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_soluble": [ + "0" + ], + "nozzle_temperature_range_low": [ + "250" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "filament_notes": [ + "Inslogic Nylon PA6/66 TDS (20.01.2025). Nozzle sizes 0.2/0.4/0.6mm. Nozzle 250-280C. Bed 30-50C. Printing speed 50-150mm/s. Cooling fan 100%. Textured PEI Sheet. Drying 80C for 48h or 110C for 3h. TDS linear speed is not converted to filament_max_volumetric_speed." + ], + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-CF @base.json index cf73d10c59..07b2ca037c 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-CF @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PA6-CF @base.json @@ -1,39 +1,39 @@ { - "type": "filament", - "name": "INSLOGIC PA6-CF @base", - "inherits": "fdm_filament_pa", - "from": "system", - "filament_id": "OFDkHRsW", - "instantiation": "false", - "filament_vendor": [ - "INSLOGIC" - ], - "filament_type": [ - "PA-CF" - ], - "filament_density": [ - "1.20" - ], - "filament_diameter": [ - "1.75" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_soluble": [ - "0" - ], - "nozzle_temperature_range_low": [ - "270" - ], - "nozzle_temperature_range_high": [ - "290" - ], - "filament_notes": [ - "Inslogic PA6-CF TDS (20.01.2025). Nozzle sizes 0.4/0.6mm. Nozzle 270-290C at 50-100mm/s. Bed 50-70C. Cooling fan 30%. Textured PEI Sheet. Drying 90C for 12h or 110C for 4h. Carbon-fiber reinforced; abrasive filament. TDS linear speed is not converted to filament_max_volumetric_speed." - ], - "compatible_printers": [], - "required_nozzle_HRC": [ - "3" - ] + "type": "filament", + "name": "INSLOGIC PA6-CF @base", + "inherits": "fdm_filament_pa", + "from": "system", + "filament_id": "OFDkHRsW", + "instantiation": "false", + "filament_vendor": [ + "INSLOGIC" + ], + "filament_type": [ + "PA-CF" + ], + "filament_density": [ + "1.20" + ], + "filament_diameter": [ + "1.75" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_soluble": [ + "0" + ], + "nozzle_temperature_range_low": [ + "270" + ], + "nozzle_temperature_range_high": [ + "290" + ], + "filament_notes": [ + "Inslogic PA6-CF TDS (20.01.2025). Nozzle sizes 0.4/0.6mm. Nozzle 270-290C at 50-100mm/s. Bed 50-70C. Cooling fan 30%. Textured PEI Sheet. Drying 90C for 12h or 110C for 4h. Carbon-fiber reinforced; abrasive filament. TDS linear speed is not converted to filament_max_volumetric_speed." + ], + "compatible_printers": [], + "required_nozzle_HRC": [ + "3" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PETG Pro @base.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PETG Pro @base.json index ef0e797c2a..c5ac71e563 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PETG Pro @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PETG Pro @base.json @@ -1,36 +1,36 @@ { - "type": "filament", - "name": "INSLOGIC PETG Pro @base", - "inherits": "fdm_filament_pet", - "from": "system", - "filament_id": "OFBdBfg1", - "instantiation": "false", - "filament_vendor": [ - "INSLOGIC" - ], - "filament_type": [ - "PETG" - ], - "filament_density": [ - "1.26" - ], - "filament_diameter": [ - "1.75" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_soluble": [ - "0" - ], - "nozzle_temperature_range_low": [ - "230" - ], - "nozzle_temperature_range_high": [ - "270" - ], - "filament_notes": [ - "Inslogic PETG Pro TDS (12.02.2024). Nozzle sizes 0.2/0.4/0.6mm. 230-240C at 50-100mm/s; 240-255C at 100-300mm/s; 255-270C at 300-600mm/s. Bed 60-70C. Cooling fan 100%. Bed: Smooth PEI Sheet / High Temperature Plate. Drying 50C for 4h. TDS linear speed is not converted to filament_max_volumetric_speed." - ], - "compatible_printers": [] + "type": "filament", + "name": "INSLOGIC PETG Pro @base", + "inherits": "fdm_filament_pet", + "from": "system", + "filament_id": "OFBdBfg1", + "instantiation": "false", + "filament_vendor": [ + "INSLOGIC" + ], + "filament_type": [ + "PETG" + ], + "filament_density": [ + "1.26" + ], + "filament_diameter": [ + "1.75" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_soluble": [ + "0" + ], + "nozzle_temperature_range_low": [ + "230" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "filament_notes": [ + "Inslogic PETG Pro TDS (12.02.2024). Nozzle sizes 0.2/0.4/0.6mm. 230-240C at 50-100mm/s; 240-255C at 100-300mm/s; 255-270C at 300-600mm/s. Bed 60-70C. Cooling fan 100%. Bed: Smooth PEI Sheet / High Temperature Plate. Drying 50C for 4h. TDS linear speed is not converted to filament_max_volumetric_speed." + ], + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PLA Pro @base.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PLA Pro @base.json index b33a37c62c..7d199cb46e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PLA Pro @base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/INSLOGIC PLA Pro @base.json @@ -1,36 +1,36 @@ { - "type": "filament", - "name": "INSLOGIC PLA Pro @base", - "inherits": "fdm_filament_pla", - "from": "system", - "filament_id": "OFvPeNbA", - "instantiation": "false", - "filament_vendor": [ - "INSLOGIC" - ], - "filament_type": [ - "PLA" - ], - "filament_density": [ - "1.20" - ], - "filament_diameter": [ - "1.75" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_soluble": [ - "0" - ], - "nozzle_temperature_range_low": [ - "195" - ], - "nozzle_temperature_range_high": [ - "220" - ], - "filament_notes": [ - "Inslogic PLA Pro TDS (12.02.2024). Nozzle sizes 0.2/0.4/0.6mm. 195-205C at 50-100mm/s; 205-220C at 100-300mm/s. Bed 50-60C. Cooling fan 100%. Bed: Textured PEI Sheet / Cool Plate. Drying 50C for 4h. TDS linear speed is not converted to filament_max_volumetric_speed." - ], - "compatible_printers": [] + "type": "filament", + "name": "INSLOGIC PLA Pro @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "OFvPeNbA", + "instantiation": "false", + "filament_vendor": [ + "INSLOGIC" + ], + "filament_type": [ + "PLA" + ], + "filament_density": [ + "1.20" + ], + "filament_diameter": [ + "1.75" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_soluble": [ + "0" + ], + "nozzle_temperature_range_low": [ + "195" + ], + "nozzle_temperature_range_high": [ + "220" + ], + "filament_notes": [ + "Inslogic PLA Pro TDS (12.02.2024). Nozzle sizes 0.2/0.4/0.6mm. 195-205C at 50-100mm/s; 205-220C at 100-300mm/s. Bed 50-60C. Cooling fan 100%. Bed: Textured PEI Sheet / Cool Plate. Drying 50C for 4h. TDS linear speed is not converted to filament_max_volumetric_speed." + ], + "compatible_printers": [] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-66 @Prusa CORE One.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-66 @Prusa CORE One.json index 040e1f0ff0..7fa82c8699 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-66 @Prusa CORE One.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-66 @Prusa CORE One.json @@ -1,165 +1,165 @@ { - "type": "filament", - "name": "INSLOGIC PA6-66 @Prusa CORE One", - "inherits": "INSLOGIC PA6-66 @base", - "from": "system", - "setting_id": "Kuv4zCw8jhxYOzhB", - "instantiation": "true", - "hot_plate_temp": [ - "40" - ], - "hot_plate_temp_initial_layer": [ - "40" - ], - "textured_plate_temp": [ - "40" - ], - "textured_plate_temp_initial_layer": [ - "40" - ], - "enable_overhang_bridge_fan": [ - "1" - ], - "overhang_fan_speed": [ - "100" - ], - "chamber_minimal_temperature": [ - "0" - ], - "chamber_temperature": [ - "0" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "0" - ], - "filament_end_gcode": [ - "; Filament-specific end gcode" - ], - "filament_flow_ratio": [ - "0.99" - ], - "fan_cooling_layer_time": [ - "100" - ], - "filament_cooling_final_speed": [ - "3.5" - ], - "filament_cooling_initial_speed": [ - "10" - ], - "filament_cooling_moves": [ - "2" - ], - "filament_deretraction_speed": [ - "nil" - ], - "filament_loading_speed": [ - "10" - ], - "filament_loading_speed_start": [ - "50" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_multitool_ramming": [ - "0" - ], - "filament_multitool_ramming_flow": [ - "10" - ], - "filament_multitool_ramming_volume": [ - "10" - ], - "filament_ramming_parameters": [ - "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" - ], - "filament_retraction_minimum_travel": [ - "nil" - ], - "filament_retract_before_wipe": [ - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil" - ], - "filament_retraction_length": [ - "nil" - ], - "filament_retract_length_toolchange": [ - "nil" - ], - "filament_z_hop": [ - "nil" - ], - "filament_retract_lift_above": [ - "nil" - ], - "filament_retract_lift_below": [ - "nil" - ], - "filament_retract_restart_extra": [ - "nil" - ], - "filament_retract_restart_extra_toolchange": [ - "nil" - ], - "filament_retraction_speed": [ - "nil" - ], - "filament_stamping_distance": [ - "45" - ], - "filament_stamping_loading_speed": [ - "29" - ], - "filament_toolchange_delay": [ - "0" - ], - "filament_unloading_speed": [ - "100" - ], - "filament_unloading_speed_start": [ - "100" - ], - "filament_wipe": [ - "nil" - ], - "nozzle_temperature_initial_layer": [ - "265" - ], - "full_fan_speed_layer": [ - "0" - ], - "idle_temperature": [ - "170" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "100" - ], - "slow_down_min_speed": [ - "20" - ], - "slow_down_layer_time": [ - "15" - ], - "filament_start_gcode": [ - "" - ], - "nozzle_temperature": [ - "265" - ], - "compatible_printers": [ - "Prusa CORE One 0.4 nozzle", - "Prusa CORE One L 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PA6-66 @Prusa CORE One", + "inherits": "INSLOGIC PA6-66 @base", + "from": "system", + "setting_id": "Kuv4zCw8jhxYOzhB", + "instantiation": "true", + "hot_plate_temp": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "40" + ], + "textured_plate_temp": [ + "40" + ], + "textured_plate_temp_initial_layer": [ + "40" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "overhang_fan_speed": [ + "100" + ], + "chamber_minimal_temperature": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "0" + ], + "filament_end_gcode": [ + "; Filament-specific end gcode" + ], + "filament_flow_ratio": [ + "0.99" + ], + "fan_cooling_layer_time": [ + "100" + ], + "filament_cooling_final_speed": [ + "3.5" + ], + "filament_cooling_initial_speed": [ + "10" + ], + "filament_cooling_moves": [ + "2" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_loading_speed": [ + "10" + ], + "filament_loading_speed_start": [ + "50" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "10" + ], + "filament_multitool_ramming_volume": [ + "10" + ], + "filament_ramming_parameters": [ + "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retract_length_toolchange": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_restart_extra_toolchange": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_stamping_distance": [ + "45" + ], + "filament_stamping_loading_speed": [ + "29" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_unloading_speed": [ + "100" + ], + "filament_unloading_speed_start": [ + "100" + ], + "filament_wipe": [ + "nil" + ], + "nozzle_temperature_initial_layer": [ + "265" + ], + "full_fan_speed_layer": [ + "0" + ], + "idle_temperature": [ + "170" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "slow_down_min_speed": [ + "20" + ], + "slow_down_layer_time": [ + "15" + ], + "filament_start_gcode": [ + "" + ], + "nozzle_temperature": [ + "265" + ], + "compatible_printers": [ + "Prusa CORE One 0.4 nozzle", + "Prusa CORE One L 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-CF @Prusa CORE One.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-CF @Prusa CORE One.json index 790650ee23..5063ee001a 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-CF @Prusa CORE One.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PA6-CF @Prusa CORE One.json @@ -1,165 +1,165 @@ { - "type": "filament", - "name": "INSLOGIC PA6-CF @Prusa CORE One", - "inherits": "INSLOGIC PA6-CF @base", - "from": "system", - "setting_id": "ZCYSMR6VCj0IrYAF", - "instantiation": "true", - "hot_plate_temp": [ - "60" - ], - "hot_plate_temp_initial_layer": [ - "60" - ], - "textured_plate_temp": [ - "60" - ], - "textured_plate_temp_initial_layer": [ - "60" - ], - "enable_overhang_bridge_fan": [ - "1" - ], - "overhang_fan_speed": [ - "30" - ], - "chamber_minimal_temperature": [ - "0" - ], - "chamber_temperature": [ - "0" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "0" - ], - "filament_end_gcode": [ - "; Filament-specific end gcode" - ], - "filament_flow_ratio": [ - "0.99" - ], - "fan_cooling_layer_time": [ - "100" - ], - "filament_cooling_final_speed": [ - "3.5" - ], - "filament_cooling_initial_speed": [ - "10" - ], - "filament_cooling_moves": [ - "2" - ], - "filament_deretraction_speed": [ - "nil" - ], - "filament_loading_speed": [ - "10" - ], - "filament_loading_speed_start": [ - "50" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_multitool_ramming": [ - "0" - ], - "filament_multitool_ramming_flow": [ - "10" - ], - "filament_multitool_ramming_volume": [ - "10" - ], - "filament_ramming_parameters": [ - "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" - ], - "filament_retraction_minimum_travel": [ - "nil" - ], - "filament_retract_before_wipe": [ - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil" - ], - "filament_retraction_length": [ - "nil" - ], - "filament_retract_length_toolchange": [ - "nil" - ], - "filament_z_hop": [ - "nil" - ], - "filament_retract_lift_above": [ - "nil" - ], - "filament_retract_lift_below": [ - "nil" - ], - "filament_retract_restart_extra": [ - "nil" - ], - "filament_retract_restart_extra_toolchange": [ - "nil" - ], - "filament_retraction_speed": [ - "nil" - ], - "filament_stamping_distance": [ - "45" - ], - "filament_stamping_loading_speed": [ - "29" - ], - "filament_toolchange_delay": [ - "0" - ], - "filament_unloading_speed": [ - "100" - ], - "filament_unloading_speed_start": [ - "100" - ], - "filament_wipe": [ - "nil" - ], - "nozzle_temperature_initial_layer": [ - "280" - ], - "full_fan_speed_layer": [ - "0" - ], - "idle_temperature": [ - "170" - ], - "fan_max_speed": [ - "30" - ], - "fan_min_speed": [ - "30" - ], - "slow_down_min_speed": [ - "20" - ], - "slow_down_layer_time": [ - "15" - ], - "filament_start_gcode": [ - "" - ], - "nozzle_temperature": [ - "280" - ], - "compatible_printers": [ - "Prusa CORE One 0.4 nozzle", - "Prusa CORE One L 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PA6-CF @Prusa CORE One", + "inherits": "INSLOGIC PA6-CF @base", + "from": "system", + "setting_id": "ZCYSMR6VCj0IrYAF", + "instantiation": "true", + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "overhang_fan_speed": [ + "30" + ], + "chamber_minimal_temperature": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "0" + ], + "filament_end_gcode": [ + "; Filament-specific end gcode" + ], + "filament_flow_ratio": [ + "0.99" + ], + "fan_cooling_layer_time": [ + "100" + ], + "filament_cooling_final_speed": [ + "3.5" + ], + "filament_cooling_initial_speed": [ + "10" + ], + "filament_cooling_moves": [ + "2" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_loading_speed": [ + "10" + ], + "filament_loading_speed_start": [ + "50" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "10" + ], + "filament_multitool_ramming_volume": [ + "10" + ], + "filament_ramming_parameters": [ + "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retract_length_toolchange": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_restart_extra_toolchange": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_stamping_distance": [ + "45" + ], + "filament_stamping_loading_speed": [ + "29" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_unloading_speed": [ + "100" + ], + "filament_unloading_speed_start": [ + "100" + ], + "filament_wipe": [ + "nil" + ], + "nozzle_temperature_initial_layer": [ + "280" + ], + "full_fan_speed_layer": [ + "0" + ], + "idle_temperature": [ + "170" + ], + "fan_max_speed": [ + "30" + ], + "fan_min_speed": [ + "30" + ], + "slow_down_min_speed": [ + "20" + ], + "slow_down_layer_time": [ + "15" + ], + "filament_start_gcode": [ + "" + ], + "nozzle_temperature": [ + "280" + ], + "compatible_printers": [ + "Prusa CORE One 0.4 nozzle", + "Prusa CORE One L 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PETG Pro @Prusa CORE One.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PETG Pro @Prusa CORE One.json index 6eb05df53d..70465325c1 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PETG Pro @Prusa CORE One.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PETG Pro @Prusa CORE One.json @@ -1,165 +1,165 @@ { - "type": "filament", - "name": "INSLOGIC PETG Pro @Prusa CORE One", - "inherits": "INSLOGIC PETG Pro @base", - "from": "system", - "setting_id": "yHUGQJhN0HUa7A5V", - "instantiation": "true", - "hot_plate_temp": [ - "65" - ], - "hot_plate_temp_initial_layer": [ - "65" - ], - "textured_plate_temp": [ - "65" - ], - "textured_plate_temp_initial_layer": [ - "65" - ], - "enable_overhang_bridge_fan": [ - "1" - ], - "overhang_fan_speed": [ - "100" - ], - "chamber_minimal_temperature": [ - "0" - ], - "chamber_temperature": [ - "0" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "0" - ], - "filament_end_gcode": [ - "; Filament-specific end gcode" - ], - "filament_flow_ratio": [ - "0.99" - ], - "fan_cooling_layer_time": [ - "100" - ], - "filament_cooling_final_speed": [ - "3.5" - ], - "filament_cooling_initial_speed": [ - "10" - ], - "filament_cooling_moves": [ - "2" - ], - "filament_deretraction_speed": [ - "nil" - ], - "filament_loading_speed": [ - "10" - ], - "filament_loading_speed_start": [ - "50" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_multitool_ramming": [ - "0" - ], - "filament_multitool_ramming_flow": [ - "10" - ], - "filament_multitool_ramming_volume": [ - "10" - ], - "filament_ramming_parameters": [ - "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" - ], - "filament_retraction_minimum_travel": [ - "nil" - ], - "filament_retract_before_wipe": [ - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil" - ], - "filament_retraction_length": [ - "nil" - ], - "filament_retract_length_toolchange": [ - "nil" - ], - "filament_z_hop": [ - "nil" - ], - "filament_retract_lift_above": [ - "nil" - ], - "filament_retract_lift_below": [ - "nil" - ], - "filament_retract_restart_extra": [ - "nil" - ], - "filament_retract_restart_extra_toolchange": [ - "nil" - ], - "filament_retraction_speed": [ - "nil" - ], - "filament_stamping_distance": [ - "45" - ], - "filament_stamping_loading_speed": [ - "29" - ], - "filament_toolchange_delay": [ - "0" - ], - "filament_unloading_speed": [ - "100" - ], - "filament_unloading_speed_start": [ - "100" - ], - "filament_wipe": [ - "nil" - ], - "nozzle_temperature_initial_layer": [ - "250" - ], - "full_fan_speed_layer": [ - "0" - ], - "idle_temperature": [ - "170" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "100" - ], - "slow_down_min_speed": [ - "20" - ], - "slow_down_layer_time": [ - "15" - ], - "filament_start_gcode": [ - "" - ], - "nozzle_temperature": [ - "250" - ], - "compatible_printers": [ - "Prusa CORE One 0.4 nozzle", - "Prusa CORE One L 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PETG Pro @Prusa CORE One", + "inherits": "INSLOGIC PETG Pro @base", + "from": "system", + "setting_id": "yHUGQJhN0HUa7A5V", + "instantiation": "true", + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "overhang_fan_speed": [ + "100" + ], + "chamber_minimal_temperature": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "0" + ], + "filament_end_gcode": [ + "; Filament-specific end gcode" + ], + "filament_flow_ratio": [ + "0.99" + ], + "fan_cooling_layer_time": [ + "100" + ], + "filament_cooling_final_speed": [ + "3.5" + ], + "filament_cooling_initial_speed": [ + "10" + ], + "filament_cooling_moves": [ + "2" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_loading_speed": [ + "10" + ], + "filament_loading_speed_start": [ + "50" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "10" + ], + "filament_multitool_ramming_volume": [ + "10" + ], + "filament_ramming_parameters": [ + "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retract_length_toolchange": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_restart_extra_toolchange": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_stamping_distance": [ + "45" + ], + "filament_stamping_loading_speed": [ + "29" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_unloading_speed": [ + "100" + ], + "filament_unloading_speed_start": [ + "100" + ], + "filament_wipe": [ + "nil" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "full_fan_speed_layer": [ + "0" + ], + "idle_temperature": [ + "170" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "slow_down_min_speed": [ + "20" + ], + "slow_down_layer_time": [ + "15" + ], + "filament_start_gcode": [ + "" + ], + "nozzle_temperature": [ + "250" + ], + "compatible_printers": [ + "Prusa CORE One 0.4 nozzle", + "Prusa CORE One L 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PLA Pro @Prusa CORE One.json b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PLA Pro @Prusa CORE One.json index f670bd71b0..6330d188c8 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PLA Pro @Prusa CORE One.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/INSLOGIC/Prusa/INSLOGIC PLA Pro @Prusa CORE One.json @@ -1,165 +1,165 @@ { - "type": "filament", - "name": "INSLOGIC PLA Pro @Prusa CORE One", - "inherits": "INSLOGIC PLA Pro @base", - "from": "system", - "setting_id": "Qkscha5uuuFXbvbB", - "instantiation": "true", - "hot_plate_temp": [ - "55" - ], - "hot_plate_temp_initial_layer": [ - "55" - ], - "textured_plate_temp": [ - "55" - ], - "textured_plate_temp_initial_layer": [ - "55" - ], - "enable_overhang_bridge_fan": [ - "1" - ], - "overhang_fan_speed": [ - "100" - ], - "chamber_minimal_temperature": [ - "0" - ], - "chamber_temperature": [ - "0" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "close_fan_the_first_x_layers": [ - "0" - ], - "filament_end_gcode": [ - "; Filament-specific end gcode" - ], - "filament_flow_ratio": [ - "0.99" - ], - "fan_cooling_layer_time": [ - "100" - ], - "filament_cooling_final_speed": [ - "3.5" - ], - "filament_cooling_initial_speed": [ - "10" - ], - "filament_cooling_moves": [ - "2" - ], - "filament_deretraction_speed": [ - "nil" - ], - "filament_loading_speed": [ - "10" - ], - "filament_loading_speed_start": [ - "50" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "filament_minimal_purge_on_wipe_tower": [ - "15" - ], - "filament_multitool_ramming": [ - "0" - ], - "filament_multitool_ramming_flow": [ - "10" - ], - "filament_multitool_ramming_volume": [ - "10" - ], - "filament_ramming_parameters": [ - "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" - ], - "filament_retraction_minimum_travel": [ - "nil" - ], - "filament_retract_before_wipe": [ - "nil" - ], - "filament_retract_when_changing_layer": [ - "nil" - ], - "filament_retraction_length": [ - "nil" - ], - "filament_retract_length_toolchange": [ - "nil" - ], - "filament_z_hop": [ - "nil" - ], - "filament_retract_lift_above": [ - "nil" - ], - "filament_retract_lift_below": [ - "nil" - ], - "filament_retract_restart_extra": [ - "nil" - ], - "filament_retract_restart_extra_toolchange": [ - "nil" - ], - "filament_retraction_speed": [ - "nil" - ], - "filament_stamping_distance": [ - "45" - ], - "filament_stamping_loading_speed": [ - "29" - ], - "filament_toolchange_delay": [ - "0" - ], - "filament_unloading_speed": [ - "100" - ], - "filament_unloading_speed_start": [ - "100" - ], - "filament_wipe": [ - "nil" - ], - "nozzle_temperature_initial_layer": [ - "210" - ], - "full_fan_speed_layer": [ - "0" - ], - "idle_temperature": [ - "170" - ], - "fan_max_speed": [ - "100" - ], - "fan_min_speed": [ - "100" - ], - "slow_down_min_speed": [ - "20" - ], - "slow_down_layer_time": [ - "15" - ], - "filament_start_gcode": [ - "" - ], - "nozzle_temperature": [ - "210" - ], - "compatible_printers": [ - "Prusa CORE One 0.4 nozzle", - "Prusa CORE One L 0.4 nozzle" - ] + "type": "filament", + "name": "INSLOGIC PLA Pro @Prusa CORE One", + "inherits": "INSLOGIC PLA Pro @base", + "from": "system", + "setting_id": "Qkscha5uuuFXbvbB", + "instantiation": "true", + "hot_plate_temp": [ + "55" + ], + "hot_plate_temp_initial_layer": [ + "55" + ], + "textured_plate_temp": [ + "55" + ], + "textured_plate_temp_initial_layer": [ + "55" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "overhang_fan_speed": [ + "100" + ], + "chamber_minimal_temperature": [ + "0" + ], + "chamber_temperature": [ + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "0" + ], + "filament_end_gcode": [ + "; Filament-specific end gcode" + ], + "filament_flow_ratio": [ + "0.99" + ], + "fan_cooling_layer_time": [ + "100" + ], + "filament_cooling_final_speed": [ + "3.5" + ], + "filament_cooling_initial_speed": [ + "10" + ], + "filament_cooling_moves": [ + "2" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_loading_speed": [ + "10" + ], + "filament_loading_speed_start": [ + "50" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "10" + ], + "filament_multitool_ramming_volume": [ + "10" + ], + "filament_ramming_parameters": [ + "250 100 40.1613 40.3548 40.4516 40.3548 40.2581| 0.05 40.1483 0.45 40.3419 0.95 40.3419 1.45 40.3419 1.95 40.3419 2.45 40.3419 2.95 40.3419 3.45 40.3419 3.95 40.3419 4.45 40.3419 4.95 40.3419" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retract_length_toolchange": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_restart_extra_toolchange": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_stamping_distance": [ + "45" + ], + "filament_stamping_loading_speed": [ + "29" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_unloading_speed": [ + "100" + ], + "filament_unloading_speed_start": [ + "100" + ], + "filament_wipe": [ + "nil" + ], + "nozzle_temperature_initial_layer": [ + "210" + ], + "full_fan_speed_layer": [ + "0" + ], + "idle_temperature": [ + "170" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "slow_down_min_speed": [ + "20" + ], + "slow_down_layer_time": [ + "15" + ], + "filament_start_gcode": [ + "" + ], + "nozzle_temperature": [ + "210" + ], + "compatible_printers": [ + "Prusa CORE One 0.4 nozzle", + "Prusa CORE One L 0.4 nozzle" + ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/JAYO/BBL/JAYO PETG @BBL P2S 0.4 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/JAYO/BBL/JAYO PETG @BBL P2S 0.4 nozzle.json index fc70479c7b..afced56591 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/JAYO/BBL/JAYO PETG @BBL P2S 0.4 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/JAYO/BBL/JAYO PETG @BBL P2S 0.4 nozzle.json @@ -48,6 +48,7 @@ "25" ], "additional_cooling_fan_speed": [ + "70", "70" ], "slow_down_layer_time": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P 0.2 nozzle.json b/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P 0.2 nozzle.json index f2c1c78883..e6242c5aa0 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P 0.2 nozzle.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P 0.2 nozzle.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_max_volumetric_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P.json b/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P.json index a9e5da69b6..988868d757 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Numakers/BBL/Numakers PLA+ @BBL P1P.json @@ -9,6 +9,7 @@ "80" ], "fan_min_speed": [ + "50", "50" ], "filament_deretraction_speed": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-ESD @BBL X1.json b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-ESD @BBL X1.json index 99fcec0536..943ad93ee4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-ESD @BBL X1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-ESD @BBL X1.json @@ -19,6 +19,7 @@ "Cool Plate" ], "fan_max_speed": [ + "80", "80" ], "temperature_vitrification": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-rCF08 @BBL X1.json b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-rCF08 @BBL X1.json index 12fc28a3b3..00c9cbc3d3 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-rCF08 @BBL X1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/Polymaker/BBL/Fiberon PETG-rCF08 @BBL X1.json @@ -11,39 +11,51 @@ "Bambu Lab X1 0.8 nozzle" ], "filament_deretraction_speed": [ + "nil", "nil" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_retraction_minimum_travel": [ + "nil", "nil" ], "filament_retract_before_wipe": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil" ], "filament_retraction_length": [ + "nil", "nil" ], "filament_z_hop": [ + "nil", "nil" ], "filament_z_hop_types": [ + "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retraction_speed": [ + "nil", "nil" ], "filament_wipe": [ + "nil", "nil" ], "filament_wipe_distance": [ + "nil", "nil" ], "filament_start_gcode": [ @@ -53,18 +65,23 @@ "40" ], "filament_flush_temp": [ + "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil" ], "filament_ramming_volumetric_speed": [ + "-1", "-1" ], "filament_retraction_distances_when_cut": [ + "nil", "nil" ], "filament_extruder_variant": [ @@ -72,21 +89,27 @@ "Direct Drive High Flow" ], "filament_pre_cooling_temperature": [ + "0", "0" ], "filament_ramming_travel_time": [ + "0", "0" ], "filament_adaptive_volumetric_speed": [ + "0", "0" ], "long_retractions_when_ec": [ + "0", "0" ], "retraction_distances_when_ec": [ + "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0" ] } diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth ABS rABS.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth ABS rABS.json index c5e97344e6..9c41c99100 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth ABS rABS.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth ABS rABS.json @@ -7,9 +7,11 @@ "filament_id": "OFzk5oAo", "instantiation": "true", "activate_air_filtration": [ + "1", "1" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "25", "25" ], "fan_min_speed": [ + "0", "0" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "12" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "250" ], "nozzle_temperature_range_high": [ + "260", "260" ], "nozzle_temperature_range_low": [ + "230", "230" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura FDA.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura FDA.json index a6cec42f4a..b9cfdd4fa7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura FDA.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura FDA.json @@ -7,9 +7,11 @@ "filament_id": "OFSw6Mor", "instantiation": "true", "activate_air_filtration": [ + "1", "1" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.99", @@ -166,6 +174,7 @@ "11" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "265" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature_range_low": [ + "245", "245" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura.json index 1c072f99b1..7b5f99ee60 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA Adura.json @@ -7,9 +7,11 @@ "filament_id": "OFWK0Y9A", "instantiation": "true", "activate_air_filtration": [ + "1", "1" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.99", @@ -166,6 +174,7 @@ "11" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "265" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature_range_low": [ + "245", "245" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA-CF Adura X.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA-CF Adura X.json index b07d89b749..bb38a38852 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA-CF Adura X.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA-CF Adura X.json @@ -7,9 +7,11 @@ "filament_id": "OFBsbMMF", "instantiation": "true", "activate_air_filtration": [ + "1", "1" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.99", @@ -166,6 +174,7 @@ "15" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "275" ], "nozzle_temperature_range_high": [ + "280", "280" ], "nozzle_temperature_range_low": [ + "260", "260" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA6 Addlantis.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA6 Addlantis.json index a0a967026e..f8da458e21 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA6 Addlantis.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PA6 Addlantis.json @@ -7,9 +7,11 @@ "filament_id": "OF1ID4N1", "instantiation": "true", "activate_air_filtration": [ + "1", "1" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "5" ], "fan_max_speed": [ + "30", "30" ], "fan_min_speed": [ + "10", "10" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.99", @@ -166,6 +174,7 @@ "11" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.62 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "275" ], "nozzle_temperature_range_high": [ + "285", "285" ], "nozzle_temperature_range_low": [ + "265", "265" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PC BLend HT LCF.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PC BLend HT LCF.json index 2a4219ef1d..a58028b69f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PC BLend HT LCF.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PC BLend HT LCF.json @@ -7,9 +7,11 @@ "filament_id": "OFhN09f0", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "40", "40" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "15" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "275" ], "nozzle_temperature_range_high": [ + "290", "290" ], "nozzle_temperature_range_low": [ + "265", "265" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Base.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Base.json index 2f4206faea..3fdf2fee27 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Base.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Base.json @@ -7,9 +7,11 @@ "filament_id": "OFHHwrd1", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "10" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "255" ], "nozzle_temperature_range_high": [ + "275", "275" ], "nozzle_temperature_range_low": [ + "240", "240" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG ESD.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG ESD.json index 1cafba7a4e..25e253f757 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG ESD.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG ESD.json @@ -7,9 +7,11 @@ "filament_id": "OFUtiVRn", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.97", @@ -166,6 +174,7 @@ "20" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 high reliability - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "290" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature_range_low": [ + "255", "255" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Economy.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Economy.json index 17f23ee8b3..bd7e0764f7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Economy.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Economy.json @@ -7,9 +7,11 @@ "filament_id": "OFZGrQTU", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "10" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "255" ], "nozzle_temperature_range_high": [ + "275", "275" ], "nozzle_temperature_range_low": [ + "240", "240" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Flame v0.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Flame v0.json index 3a83fffcdc..cb94413ef6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Flame v0.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG Flame v0.json @@ -7,9 +7,11 @@ "filament_id": "OF0EYBWQ", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.97", @@ -166,6 +174,7 @@ "20" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.4 high reliability - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "290" ], "nozzle_temperature_range_high": [ + "270", "270" ], "nozzle_temperature_range_low": [ + "255", "255" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG PRO Matte.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG PRO Matte.json index b894fad112..52da3757e3 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG PRO Matte.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG PRO Matte.json @@ -7,9 +7,11 @@ "filament_id": "OFU5JPDy", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "8" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "260" ], "nozzle_temperature_range_high": [ + "275", "275" ], "nozzle_temperature_range_low": [ + "235", "235" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "1" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG rPETG Matte.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG rPETG Matte.json index fc7470096e..159fcca4d7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG rPETG Matte.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG rPETG Matte.json @@ -7,9 +7,11 @@ "filament_id": "OFqTwtXM", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "40", "40" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "10" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "255" ], "nozzle_temperature_range_high": [ + "260", "260" ], "nozzle_temperature_range_low": [ + "225", "225" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG-CF Rigid X.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG-CF Rigid X.json index 70d3df17cf..b62613ae92 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG-CF Rigid X.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PETG-CF Rigid X.json @@ -7,9 +7,11 @@ "filament_id": "OFAcJkl1", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "100", "100" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "30" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "5", "5" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.95", @@ -166,6 +174,7 @@ "11" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026 – Special thanks to Mats.Z (3DP24, Jonkoping University / Campus Varnamo) for profile improvements during internship autumn 2025.", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "270" ], "nozzle_temperature_range_high": [ + "275", "275" ], "nozzle_temperature_range_low": [ + "245", "245" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "0" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA E-PLA.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA E-PLA.json index 783ee6ccd1..1cf251f555 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA E-PLA.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA E-PLA.json @@ -7,9 +7,11 @@ "filament_id": "OF71b7qO", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "12" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "240", "240" ], "nozzle_temperature_range_low": [ + "190", "190" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Economy.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Economy.json index 84a22a9a60..4271837beb 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Economy.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Economy.json @@ -7,9 +7,11 @@ "filament_id": "OFZJft47", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "12" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "240", "240" ], "nozzle_temperature_range_low": [ + "200", "200" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA HT-PLA PRO Matte.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA HT-PLA PRO Matte.json index f3236b5d5a..03f7f6ff13 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA HT-PLA PRO Matte.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA HT-PLA PRO Matte.json @@ -7,9 +7,11 @@ "filament_id": "OFVDWuxl", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "11" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "245", "245" ], "nozzle_temperature_range_low": [ + "210", "210" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Premium Silk.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Premium Silk.json index f1bf250692..73c52acce6 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Premium Silk.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Premium Silk.json @@ -7,9 +7,11 @@ "filament_id": "OFOQCfVa", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "50", "50" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "80" ], "fan_max_speed": [ + "90", "90" ], "fan_min_speed": [ + "70", "70" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "1", @@ -166,6 +174,7 @@ "10" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "245" ], "nozzle_temperature_range_high": [ + "255", "255" ], "nozzle_temperature_range_low": [ + "235", "235" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Textura.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Textura.json index 218bb0f6af..bfe7676c25 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Textura.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Textura.json @@ -7,9 +7,11 @@ "filament_id": "OFRFhdqy", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "80" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "14" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "240", "240" ], "nozzle_temperature_range_low": [ + "190", "190" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Wood.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Wood.json index d4c4c4c04f..1be018e431 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Wood.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA Wood.json @@ -7,9 +7,11 @@ "filament_id": "OFN8QBhu", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "8" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "230" ], "nozzle_temperature_range_high": [ + "230", "230" ], "nozzle_temperature_range_low": [ + "200", "200" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "0" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA High Speed.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA High Speed.json index 939a8301fb..cd8b897e5f 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA High Speed.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA High Speed.json @@ -7,9 +7,11 @@ "filament_id": "OFLjDYxH", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "12" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "240", "240" ], "nozzle_temperature_range_low": [ + "190", "190" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA.json index 075ab03f46..59aa588cd4 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA X-PLA.json @@ -7,9 +7,11 @@ "filament_id": "OFtdVZpV", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "14" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "230" ], "nozzle_temperature_range_high": [ + "240", "240" ], "nozzle_temperature_range_low": [ + "190", "190" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA rPLA RE-ADD.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA rPLA RE-ADD.json index 771869bc04..0aa4ca73b7 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA rPLA RE-ADD.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PLA rPLA RE-ADD.json @@ -7,9 +7,11 @@ "filament_id": "OFnBvPhb", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "0.98", @@ -166,6 +174,7 @@ "16" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "240", "240" ], "nozzle_temperature_range_low": [ + "190", "190" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PVDF Adamant S1.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PVDF Adamant S1.json index 584d049776..96ba6ace88 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PVDF Adamant S1.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth PVDF Adamant S1.json @@ -7,9 +7,11 @@ "filament_id": "OFQ5TxZ2", "instantiation": "true", "activate_air_filtration": [ + "1", "1" ], "additional_cooling_fan_speed": [ + "0", "0" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "5" ], "fan_max_speed": [ + "80", "80" ], "fan_min_speed": [ + "25", "25" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "1", @@ -166,6 +174,7 @@ "4" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.6 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "265" ], "nozzle_temperature_range_high": [ + "260", "260" ], "nozzle_temperature_range_low": [ + "240", "240" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU EasyFlex.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU EasyFlex.json index f75218b666..2b05356f4e 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU EasyFlex.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU EasyFlex.json @@ -7,9 +7,11 @@ "filament_id": "OFO6GMJ3", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "1", @@ -166,6 +174,7 @@ "5" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.7 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "250", "250" ], "nozzle_temperature_range_low": [ + "230", "230" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 85A.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 85A.json index 446377b7c4..b14dd41fba 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 85A.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 85A.json @@ -7,9 +7,11 @@ "filament_id": "OFvcIGee", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "1", @@ -166,6 +174,7 @@ "5" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.2 - V.Pack:18_05_2026", @@ -189,6 +198,7 @@ "nil" ], "filament_retract_restart_extra": [ + "nil", "nil" ], "filament_retract_when_changing_layer": [ @@ -293,9 +303,11 @@ "250" ], "nozzle_temperature_range_high": [ + "250", "250" ], "nozzle_temperature_range_low": [ + "230", "230" ], "overhang_fan_speed": [ @@ -311,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 95A.json b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 95A.json index b63da895a8..c35736f4b5 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 95A.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/addnorth/BBL/addnorth TPU Pro Matte 95A.json @@ -7,9 +7,11 @@ "filament_id": "OFyJjkek", "instantiation": "true", "activate_air_filtration": [ + "0", "0" ], "additional_cooling_fan_speed": [ + "70", "70" ], "chamber_temperatures": [ @@ -72,6 +74,7 @@ "compatible_prints": [], "compatible_prints_condition": "", "complete_print_exhaust_fan_speed": [ + "70", "70" ], "cool_plate_temp": [ @@ -102,12 +105,14 @@ "50" ], "during_print_exhaust_fan_speed": [ + "70", "70" ], "enable_overhang_bridge_fan": [ "1" ], "enable_pressure_advance": [ + "0", "0" ], "eng_plate_temp": [ @@ -120,9 +125,11 @@ "100" ], "fan_max_speed": [ + "100", "100" ], "fan_min_speed": [ + "100", "100" ], "filament_adhesiveness_category": [ @@ -148,7 +155,8 @@ "; filament end gcode \n" ], "filament_extruder_variant": [ - "Direct Drive Standard" + "Direct Drive Standard", + "Direct Drive High Flow" ], "filament_flow_ratio": [ "1", @@ -166,6 +174,7 @@ "5" ], "filament_minimal_purge_on_wipe_tower": [ + "15", "15" ], "filament_notes": "File Version:2.3 - V.Pack:18_05_2026", @@ -294,9 +303,11 @@ "235" ], "nozzle_temperature_range_high": [ + "250", "250" ], "nozzle_temperature_range_low": [ + "230", "230" ], "overhang_fan_speed": [ @@ -312,6 +323,7 @@ "2" ], "pressure_advance": [ + "0.02", "0.02" ], "reduce_fan_stop_start_freq": [ diff --git a/resources/profiles/Peopoly.json b/resources/profiles/Peopoly.json index 9b95c24bb3..21ae6bdb93 100644 --- a/resources/profiles/Peopoly.json +++ b/resources/profiles/Peopoly.json @@ -1,6 +1,6 @@ { "name": "Peopoly", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "Peopoly configurations", "machine_model_list": [ diff --git a/resources/profiles/Peopoly/filament/Generic ABS @Peopoly.json b/resources/profiles/Peopoly/filament/Generic ABS @Peopoly.json index d9e2ae777c..9342bcb63c 100644 --- a/resources/profiles/Peopoly/filament/Generic ABS @Peopoly.json +++ b/resources/profiles/Peopoly/filament/Generic ABS @Peopoly.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Peopoly", - "inherits": "fdm_filament_abs", "renamed_from": "Peopoly Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "HLq9urLhPLW0du6x", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Peopoly/filament/Generic PETG @Peopoly.json b/resources/profiles/Peopoly/filament/Generic PETG @Peopoly.json index fc4501866a..0d21a46002 100644 --- a/resources/profiles/Peopoly/filament/Generic PETG @Peopoly.json +++ b/resources/profiles/Peopoly/filament/Generic PETG @Peopoly.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Peopoly", - "inherits": "fdm_filament_petg", "renamed_from": "Peopoly Generic PETG", + "inherits": "fdm_filament_petg", "from": "system", "setting_id": "dgMXFTyLovrMR56j", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Phrozen.json b/resources/profiles/Phrozen.json index f07568bb29..ef10047de6 100644 --- a/resources/profiles/Phrozen.json +++ b/resources/profiles/Phrozen.json @@ -1,6 +1,6 @@ { "name": "Phrozen", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Phrozen configurations", "machine_model_list": [ diff --git a/resources/profiles/Phrozen/filament/Generic PLA @Phrozen Arco 0.4 nozzle.json b/resources/profiles/Phrozen/filament/Generic PLA @Phrozen Arco 0.4 nozzle.json index c53abee956..63c6d76ba0 100644 --- a/resources/profiles/Phrozen/filament/Generic PLA @Phrozen Arco 0.4 nozzle.json +++ b/resources/profiles/Phrozen/filament/Generic PLA @Phrozen Arco 0.4 nozzle.json @@ -6,6 +6,9 @@ "from": "system", "setting_id": "xTeHmDOY48Bik10J", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_settings_id": [ "Generic PLA @Phrozen Arco 0.4 nozzle" ], diff --git a/resources/profiles/Prusa.json b/resources/profiles/Prusa.json index e16e2d3be3..c0c6ce2f4e 100644 --- a/resources/profiles/Prusa.json +++ b/resources/profiles/Prusa.json @@ -1,6 +1,6 @@ { "name": "Prusa", - "version": "02.04.00.08", + "version": "02.04.00.09", "force_update": "0", "description": "Prusa configurations", "machine_model_list": [ diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.6.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.6.json index 8ba18e9dde..8493c75c81 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One 0.6", - "inherits": "Generic ABS @Prusa CORE One", "renamed_from": "Prusa Generic ABS @CORE One 0.6;Prusa Generic ABS CORE One 0.6", + "inherits": "Generic ABS @Prusa CORE One", "from": "system", "setting_id": "PYQhstNvKFJ7qsxe", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.8.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.8.json index 2981c2ef63..cc8322476d 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One 0.8", - "inherits": "Generic ABS @Prusa CORE One", "renamed_from": "Prusa Generic ABS @CORE One 0.8;Prusa Generic ABS CORE One 0.8", + "inherits": "Generic ABS @Prusa CORE One", "from": "system", "setting_id": "ExG49agessyLCVpW", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.4.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.4.json index f2e61055ab..caf36dc7d1 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.4.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One HF 0.4", - "inherits": "Generic ABS @Prusa CORE One", "renamed_from": "Prusa Generic ABS @CORE One HF 0.4;Prusa Generic ABS CORE One HF 0.4", + "inherits": "Generic ABS @Prusa CORE One", "from": "system", "setting_id": "ASYz8yASE82tQDII", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.5.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.5.json index 14782a747a..4d0ae20a33 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.5.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One HF 0.5", - "inherits": "Generic ABS @Prusa CORE One", "renamed_from": "Prusa Generic ABS @CORE One HF 0.5;Prusa Generic ABS CORE One HF 0.5", + "inherits": "Generic ABS @Prusa CORE One", "from": "system", "setting_id": "mzZCm8XDmAR23YR6", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.6.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.6.json index be46455a73..6419e2a9d4 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One HF 0.6", - "inherits": "Generic ABS @Prusa CORE One", "renamed_from": "Prusa Generic ABS @CORE One HF 0.6;Prusa Generic ABS CORE One HF 0.6", + "inherits": "Generic ABS @Prusa CORE One", "from": "system", "setting_id": "gJhX2KBpk4wfXIj0", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.8.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.8.json index f4d2954ad7..84913947af 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One HF 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One HF 0.8", - "inherits": "Generic ABS @Prusa CORE One", "renamed_from": "Prusa Generic ABS @CORE One HF 0.8;Prusa Generic ABS CORE One HF 0.8", + "inherits": "Generic ABS @Prusa CORE One", "from": "system", "setting_id": "JbGYSVdZTeFJXaVk", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One.json index 7339d20a7c..146903ac55 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa CORE One.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa CORE One", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS @CORE One;Prusa Generic ABS CORE One", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "0k31oXq1pLQsHvrj", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.25.json index 0fe673d854..23709aa9a8 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MINIIS 0.25", - "inherits": "Generic ABS @Prusa base", "renamed_from": "Prusa Generic ABS @MINIIS 0.25;Prusa Generic ABS MINIIS 0.25", + "inherits": "Generic ABS @Prusa base", "from": "system", "setting_id": "T7U23i3I3ALV2oEd", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.6.json index 3b9fa495e3..41dc794378 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MINIIS 0.6", - "inherits": "Generic ABS @Prusa base", "renamed_from": "Prusa Generic ABS @MINIIS 0.6;Prusa Generic ABS MINIIS 0.6", + "inherits": "Generic ABS @Prusa base", "from": "system", "setting_id": "iZdNxczgKBs0zIiI", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.8.json index e9d5d7554b..71a6e81ce3 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MINIIS 0.8", - "inherits": "Generic ABS @Prusa base", "renamed_from": "Prusa Generic ABS @MINIIS 0.8;Prusa Generic ABS MINIIS 0.8", + "inherits": "Generic ABS @Prusa base", "from": "system", "setting_id": "f6fZt6LNgXSHjInj", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS.json index 9f6569d6e9..f32d65f4b7 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MINIIS", - "inherits": "Generic ABS @Prusa base", "renamed_from": "Prusa Generic ABS @MINIIS;Prusa Generic ABS MINIIS", + "inherits": "Generic ABS @Prusa base", "from": "system", "setting_id": "ZqiVOVIYGAbB1SPk", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.25.json index 0a36c04f02..48f60ab2be 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK3.5 0.25", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS @MK3.5 0.25;Prusa Generic ABS MK3.5 0.25", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "IjZS8VJrGg6fRiI2", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.6.json index 04626e6ad8..853478b06e 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK3.5 0.6", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS @MK3.5 0.6;Prusa Generic ABS MK3.5 0.6", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "iJ2u6LgWCZd2zaPJ", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.8.json index 4e65b7e329..dde209cb04 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK3.5 0.8", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS @MK3.5 0.8;Prusa Generic ABS MK3.5 0.8", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "m8neIe1dfWt5Klbq", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5.json index 075e055e72..bdd0f313ea 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK3.5", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS @MK3.5;Prusa Generic ABS MK3.5", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "EEc6F9uzIkv6nFib", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4.json index 9ab147b678..a6fc0f89da 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4", - "inherits": "Generic ABS @Prusa base", "renamed_from": "Prusa Generic ABS @MK4;Prusa Generic ABS MK4", + "inherits": "Generic ABS @Prusa base", "from": "system", "setting_id": "MVcRPldYJo5fnXh8", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.6.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.6.json index 7371c1f2f9..9e27724462 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S 0.6", - "inherits": "Generic ABS @Prusa MK4S", "renamed_from": "Prusa Generic ABS @MK4S 0.6;Prusa Generic ABS MK4S 0.6", + "inherits": "Generic ABS @Prusa MK4S", "from": "system", "setting_id": "aNRfxkoYTEG3NPV1", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.8.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.8.json index bf0e8419cf..72718602a4 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S 0.8", - "inherits": "Generic ABS @Prusa MK4S", "renamed_from": "Prusa Generic ABS @MK4S 0.8;Prusa Generic ABS MK4S 0.8", + "inherits": "Generic ABS @Prusa MK4S", "from": "system", "setting_id": "sL7NL7GOf52fzxnj", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.4.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.4.json index 84aca85d1a..c0e2cd5932 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.4.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S HF0.4", - "inherits": "Generic ABS @Prusa MK4S", "renamed_from": "Prusa Generic ABS @MK4S HF0.4;Prusa Generic ABS MK4S HF0.4", + "inherits": "Generic ABS @Prusa MK4S", "from": "system", "setting_id": "usm5Dycg7z1b1o1v", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.5.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.5.json index cb9f3ccebc..6b5706180e 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.5.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S HF0.5", - "inherits": "Generic ABS @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic ABS @MK4S HF0.5;Prusa Generic ABS MK4S HF0.5", + "inherits": "Generic ABS @Prusa MK4S HF0.4", "from": "system", "setting_id": "EdrmoUsReFVn5EWW", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.6.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.6.json index 2327e2d1cc..2de8b74683 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S HF0.6", - "inherits": "Generic ABS @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic ABS @MK4S HF0.6;Prusa Generic ABS MK4S HF0.6", + "inherits": "Generic ABS @Prusa MK4S HF0.4", "from": "system", "setting_id": "lcxvk4AN6z8NGdKv", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.8.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.8.json index 81bf85e41c..104c612597 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S HF0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S HF0.8", - "inherits": "Generic ABS @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic ABS @MK4S HF0.8;Prusa Generic ABS MK4S HF0.8", + "inherits": "Generic ABS @Prusa MK4S HF0.4", "from": "system", "setting_id": "VTSZGauVB9yGzOJD", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S.json index c454e1d79b..2809ff16e9 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa MK4S.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa MK4S", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS @MK4S;Prusa Generic ABS MK4S", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "6xkFvOyWtTQNXYAm", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Prusa/filament/Generic ABS @Prusa.json b/resources/profiles/Prusa/filament/Generic ABS @Prusa.json index 0c10f8f297..6747d42b45 100644 --- a/resources/profiles/Prusa/filament/Generic ABS @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic ABS @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Prusa", - "inherits": "Generic ABS @Prusa base", "renamed_from": "Prusa Generic ABS", + "inherits": "Generic ABS @Prusa base", "from": "system", "setting_id": "RBSSZVt1NCAz4x3V", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.6.json index 071e689280..c6390f9d8d 100644 --- a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HF @Prusa MINIIS 0.6", - "inherits": "Generic ABS HF @Prusa base", "renamed_from": "Prusa Generic ABS HF @MINIIS 0.6;Prusa Generic ABS HF MINIIS 0.6", + "inherits": "Generic ABS HF @Prusa base", "from": "system", "setting_id": "L6copDR26trR0D8B", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.8.json index ca0b250240..a52f9f3f40 100644 --- a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HF @Prusa MINIIS 0.8", - "inherits": "Generic ABS HF @Prusa base", "renamed_from": "Prusa Generic ABS HF @MINIIS 0.8;Prusa Generic ABS HF MINIIS 0.8", + "inherits": "Generic ABS HF @Prusa base", "from": "system", "setting_id": "oxiwspATW960u3eZ", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS.json index 6acc1844e7..b845f03d4d 100644 --- a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HF @Prusa MINIIS", - "inherits": "Generic ABS HF @Prusa base", "renamed_from": "Prusa Generic ABS HF @MINIIS;Prusa Generic ABS HF MINIIS", + "inherits": "Generic ABS HF @Prusa base", "from": "system", "setting_id": "KcRRWqB7hrovzBng", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.6.json index 5e446b1507..2dbab6b643 100644 --- a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS HF @MK3.5 0.6;Prusa Generic ABS HF MK3.5 0.6", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "ELwxwCcaOKeCUqoB", "filament_id": "OF55jHAJ", diff --git a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.8.json index e5f48f3390..4a0a033087 100644 --- a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS HF @MK3.5 0.8;Prusa Generic ABS HF MK3.5 0.8", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "xWMzscdlR6llxFKQ", "filament_id": "OF55jHAJ", diff --git a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5.json index 9c1f224149..f814613ec2 100644 --- a/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic ABS HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HF @Prusa MK3.5", - "inherits": "fdm_filament_abs", "renamed_from": "Prusa Generic ABS HF @MK3.5;Prusa Generic ABS HF MK3.5", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "n9Xu8L69l5rs6VZF", "filament_id": "OF55jHAJ", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.6.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.6.json index 0fa54a9d21..15413c6ac0 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One 0.6", - "inherits": "Generic ASA @Prusa CORE One", "renamed_from": "Prusa Generic ASA @CORE One 0.6;Prusa Generic ASA CORE One 0.6", + "inherits": "Generic ASA @Prusa CORE One", "from": "system", "setting_id": "WJzGT568OrlSqxjt", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.8.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.8.json index db78ff7eeb..008cbbc758 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One 0.8", - "inherits": "Generic ASA @Prusa CORE One", "renamed_from": "Prusa Generic ASA @CORE One 0.8;Prusa Generic ASA CORE One 0.8", + "inherits": "Generic ASA @Prusa CORE One", "from": "system", "setting_id": "VtxVQIuWVkP6W3aN", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.4.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.4.json index 18a1b68fb3..825a3de691 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.4.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One HF 0.4", - "inherits": "Generic ASA @Prusa CORE One", "renamed_from": "Prusa Generic ASA @CORE One HF 0.4;Prusa Generic ASA CORE One HF 0.4", + "inherits": "Generic ASA @Prusa CORE One", "from": "system", "setting_id": "eKDfiVRE59itoppm", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.5.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.5.json index dd7c08b25f..86dec35130 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.5.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One HF 0.5", - "inherits": "Generic ASA @Prusa CORE One", "renamed_from": "Prusa Generic ASA @CORE One HF 0.5;Prusa Generic ASA CORE One HF 0.5", + "inherits": "Generic ASA @Prusa CORE One", "from": "system", "setting_id": "ZjHf5Vvtf4ESNnWb", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.6.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.6.json index 7ca03b1c37..e3de3e1d3d 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One HF 0.6", - "inherits": "Generic ASA @Prusa CORE One", "renamed_from": "Prusa Generic ASA @CORE One HF 0.6;Prusa Generic ASA CORE One HF 0.6", + "inherits": "Generic ASA @Prusa CORE One", "from": "system", "setting_id": "aRDgUgQJWdNDJx5c", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.8.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.8.json index 7fe2a7d8bf..c8d78a0e69 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One HF 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One HF 0.8", - "inherits": "Generic ASA @Prusa CORE One", "renamed_from": "Prusa Generic ASA @CORE One HF 0.8;Prusa Generic ASA CORE One HF 0.8", + "inherits": "Generic ASA @Prusa CORE One", "from": "system", "setting_id": "UQYl8pGvqg2D9zJX", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One.json index 84fe0fa3d9..853b1e0803 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa CORE One.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa CORE One", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @CORE One;Prusa Generic ASA CORE One", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "Q7fgojkHRZI0floy", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.25.json index 8aeaefd5c8..b4f7bbc063 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MINIIS 0.25", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MINIIS 0.25;Prusa Generic ASA MINIIS 0.25", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "3k53bfrhLAnuxHQo", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.6.json index 46cf4ee835..b52d104a19 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MINIIS 0.6", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MINIIS 0.6;Prusa Generic ASA MINIIS 0.6", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "NMILNvvq88zkz2Lf", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.8.json index 2e96b0d886..2f968e4792 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MINIIS 0.8", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MINIIS 0.8;Prusa Generic ASA MINIIS 0.8", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "lnjqcRttOW0XRGe2", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS.json index add2390249..01270df239 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MINIIS", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MINIIS;Prusa Generic ASA MINIIS", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "53FptNgFYqTPZfkV", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.25.json index ddf9c2d380..c97d7ae278 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK3.5 0.25", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MK3.5 0.25;Prusa Generic ASA MK3.5 0.25", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "zyUCfzPlsqRZiUvj", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.6.json index 0bcbf559e4..3e11e59a68 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK3.5 0.6", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MK3.5 0.6;Prusa Generic ASA MK3.5 0.6", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "AjpsLZCJaPLfpGdv", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.8.json index 2ca5decddd..e92daf0a82 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK3.5 0.8", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MK3.5 0.8;Prusa Generic ASA MK3.5 0.8", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "UwiRVbIWfsSjXcwV", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5.json index 61eed484a1..2bbcdd5b2a 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK3.5", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MK3.5;Prusa Generic ASA MK3.5", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "BA46zZsxlvH5bdbC", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4.json index bf6998903d..2afc566d7b 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MK4;Prusa Generic ASA MK4", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "3HdBZTnRTu6aKN1e", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.6.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.6.json index 15d5cb17a8..378d3eb14b 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S 0.6", - "inherits": "Generic ASA @Prusa MK4S", "renamed_from": "Prusa Generic ASA @MK4S 0.6;Prusa Generic ASA MK4S 0.6", + "inherits": "Generic ASA @Prusa MK4S", "from": "system", "setting_id": "gtPmGmeYUKi7hwVI", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.8.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.8.json index 5af8faecb8..54710e830a 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S 0.8", - "inherits": "Generic ASA @Prusa MK4S", "renamed_from": "Prusa Generic ASA @MK4S 0.8;Prusa Generic ASA MK4S 0.8", + "inherits": "Generic ASA @Prusa MK4S", "from": "system", "setting_id": "a0IXdYic1FVnKaJg", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.4.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.4.json index 033ca2b942..4ce726bbe0 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.4.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S HF0.4", - "inherits": "Generic ASA @Prusa MK4S", "renamed_from": "Prusa Generic ASA @MK4S HF0.4;Prusa Generic ASA MK4S HF0.4", + "inherits": "Generic ASA @Prusa MK4S", "from": "system", "setting_id": "INXVBsLNAkRQUlPU", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.5.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.5.json index fe96876ce6..64352c5df0 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.5.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S HF0.5", - "inherits": "Generic ASA @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic ASA @MK4S HF0.5;Prusa Generic ASA MK4S HF0.5", + "inherits": "Generic ASA @Prusa MK4S HF0.4", "from": "system", "setting_id": "g7VYJJrBS9mmbJOi", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.6.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.6.json index 56c2ff76e0..d167d8e54e 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S HF0.6", - "inherits": "Generic ASA @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic ASA @MK4S HF0.6;Prusa Generic ASA MK4S HF0.6", + "inherits": "Generic ASA @Prusa MK4S HF0.4", "from": "system", "setting_id": "yDj1rzyRIOYJM4Pp", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.8.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.8.json index be3eeb1fe4..ed1b0939dc 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S HF0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S HF0.8", - "inherits": "Generic ASA @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic ASA @MK4S HF0.8;Prusa Generic ASA MK4S HF0.8", + "inherits": "Generic ASA @Prusa MK4S HF0.4", "from": "system", "setting_id": "HF59RnyQo2wt5act", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S.json index 80ba2d523b..a8f931c1c6 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa MK4S.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa MK4S", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA @MK4S;Prusa Generic ASA MK4S", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "THc7WYsGi7nwc5wv", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA @Prusa.json b/resources/profiles/Prusa/filament/Generic ASA @Prusa.json index 19d7553977..e8df9c7e12 100644 --- a/resources/profiles/Prusa/filament/Generic ASA @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic ASA @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Prusa", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "Uff8hd9OkoS2Yly7", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.6.json index a8806ff0c6..4eba0eaf3f 100644 --- a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA HF @Prusa MINIIS 0.6", - "inherits": "Generic ASA HF @Prusa base", "renamed_from": "Prusa Generic ASA HF @MINIIS 0.6;Prusa Generic ASA HF MINIIS 0.6", + "inherits": "Generic ASA HF @Prusa base", "from": "system", "setting_id": "Xswtt3GpBabtxN4h", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.8.json index cceae0087a..61e088ac76 100644 --- a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA HF @Prusa MINIIS 0.8", - "inherits": "Generic ASA HF @Prusa base", "renamed_from": "Prusa Generic ASA HF @MINIIS 0.8;Prusa Generic ASA HF MINIIS 0.8", + "inherits": "Generic ASA HF @Prusa base", "from": "system", "setting_id": "z13Q2CqpzsnazYwI", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS.json index 4a9bb2b877..2f9e4d232a 100644 --- a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA HF @Prusa MINIIS", - "inherits": "Generic ASA HF @Prusa base", "renamed_from": "Prusa Generic ASA HF @MINIIS;Prusa Generic ASA HF MINIIS", + "inherits": "Generic ASA HF @Prusa base", "from": "system", "setting_id": "zzMFtHrjmImnj77f", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.6.json index e62013867c..a9f7e9941b 100644 --- a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA HF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA HF @MK3.5 0.6;Prusa Generic ASA HF MK3.5 0.6", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "lhsnnKDQp3U8enP3", "filament_id": "OFzRtFM9", diff --git a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.8.json index 74d0b8a4dc..15c68eb01e 100644 --- a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA HF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA HF @MK3.5 0.8;Prusa Generic ASA HF MK3.5 0.8", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "Qb9bphdgmmLKHgnC", "filament_id": "OFzRtFM9", diff --git a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5.json index b5675c32a0..ecbec14fc8 100644 --- a/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic ASA HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA HF @Prusa MK3.5", - "inherits": "fdm_filament_asa", "renamed_from": "Prusa Generic ASA HF @MK3.5;Prusa Generic ASA HF MK3.5", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "C9YvhnKeHonpemK8", "filament_id": "OFzRtFM9", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.25.json index f887a7caca..e78ac3fe42 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MINIIS 0.25", - "inherits": "Generic PA @Prusa base", "renamed_from": "Prusa Generic PA @MINIIS 0.25;Prusa Generic PA MINIIS 0.25", + "inherits": "Generic PA @Prusa base", "from": "system", "setting_id": "zONIDmAy6bC6rkBd", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.6.json index fce5c4f837..91cd7ac4b6 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MINIIS 0.6", - "inherits": "Generic PA @Prusa base", "renamed_from": "Prusa Generic PA @MINIIS 0.6;Prusa Generic PA MINIIS 0.6", + "inherits": "Generic PA @Prusa base", "from": "system", "setting_id": "Ib0bThHzZ0GXWgXv", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.8.json index 35c7df7919..764287a488 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MINIIS 0.8", - "inherits": "Generic PA @Prusa base", "renamed_from": "Prusa Generic PA @MINIIS 0.8;Prusa Generic PA MINIIS 0.8", + "inherits": "Generic PA @Prusa base", "from": "system", "setting_id": "WSCkyvdqYKalsLHg", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS.json index 67e59c92d9..fb8f18d875 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MINIIS", - "inherits": "Generic PA @Prusa base", "renamed_from": "Prusa Generic PA @MINIIS;Prusa Generic PA MINIIS", + "inherits": "Generic PA @Prusa base", "from": "system", "setting_id": "06VxUw37OfEzaSka", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.25.json index eebbafe187..f4dad0fb8d 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA @MK3.5 0.25;Prusa Generic PA MK3.5 0.25", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "htgSl4rIQ1smRBy4", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.6.json index 6405d18e56..d23262e4e9 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA @MK3.5 0.6;Prusa Generic PA MK3.5 0.6", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "LPzPJN0XdHVQDEsd", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.8.json index d85d70d810..773aa08aaa 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA @MK3.5 0.8;Prusa Generic PA MK3.5 0.8", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "WiO6dm6LbzJxOC9j", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5.json index f3309fd275..a089d00fb2 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa MK3.5", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA @MK3.5;Prusa Generic PA MK3.5", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "YfGmmjqpxHcDcRsk", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Prusa/filament/Generic PA @Prusa.json b/resources/profiles/Prusa/filament/Generic PA @Prusa.json index 1ebaec2fe2..d6d2f33cd8 100644 --- a/resources/profiles/Prusa/filament/Generic PA @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PA @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Prusa", - "inherits": "Generic PA @Prusa base", "renamed_from": "Prusa Generic PA", + "inherits": "Generic PA @Prusa base", "from": "system", "setting_id": "zTnz1NYXoXxIHhRv", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.25.json index 85ae694018..15c69ed420 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MINIIS 0.25", - "inherits": "Generic PA-CF @Prusa base", "renamed_from": "Prusa Generic PA-CF @MINIIS 0.25;Prusa Generic PA-CF MINIIS 0.25", + "inherits": "Generic PA-CF @Prusa base", "from": "system", "setting_id": "5OyMl43GFDPQHrx3", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.6.json index e986346eee..d9340c7895 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MINIIS 0.6", - "inherits": "Generic PA-CF @Prusa base", "renamed_from": "Prusa Generic PA-CF @MINIIS 0.6;Prusa Generic PA-CF MINIIS 0.6", + "inherits": "Generic PA-CF @Prusa base", "from": "system", "setting_id": "lvYPxwHzVnW29IKZ", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.8.json index 1e3dd13b49..fdaed32273 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MINIIS 0.8", - "inherits": "Generic PA-CF @Prusa base", "renamed_from": "Prusa Generic PA-CF @MINIIS 0.8;Prusa Generic PA-CF MINIIS 0.8", + "inherits": "Generic PA-CF @Prusa base", "from": "system", "setting_id": "LlGpiQAvrrd5bMCs", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS.json index 6c59be3227..f8bd971d8e 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MINIIS", - "inherits": "Generic PA-CF @Prusa base", "renamed_from": "Prusa Generic PA-CF @MINIIS;Prusa Generic PA-CF MINIIS", + "inherits": "Generic PA-CF @Prusa base", "from": "system", "setting_id": "AfQLoOulI6zwAZDg", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.25.json index 8f0622e2cc..6ff68fc59f 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA-CF @MK3.5 0.25;Prusa Generic PA-CF MK3.5 0.25", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "15pNQLVuXkSI3zjU", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.6.json index bb6fc654ad..5db76e8298 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA-CF @MK3.5 0.6;Prusa Generic PA-CF MK3.5 0.6", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "3ZKi2gcV6LgJwidS", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.8.json index 2ad7d45932..ec0c9e725e 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA-CF @MK3.5 0.8;Prusa Generic PA-CF MK3.5 0.8", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "Ilehw0Za73eW1Z9v", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5.json index 4150a3f625..e5d4621196 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa MK3.5", - "inherits": "fdm_filament_pa", "renamed_from": "Prusa Generic PA-CF @MK3.5;Prusa Generic PA-CF MK3.5", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "yy2FgYPLARliAAmZ", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa.json b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa.json index f60463913f..74b6736fb2 100644 --- a/resources/profiles/Prusa/filament/Generic PA-CF @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PA-CF @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Prusa", - "inherits": "Generic PA-CF @Prusa base", "renamed_from": "Prusa Generic PA-CF", + "inherits": "Generic PA-CF @Prusa base", "from": "system", "setting_id": "R2WthJ8gqw8xdajn", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.25.json index 4c50bdca0c..591f5502ad 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MINIIS 0.25", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MINIIS 0.25;Prusa Generic PC MINIIS 0.25", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "v5LHPemQZ8fEQJrX", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.6.json index f6e67d5d5e..4fb6967e5c 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MINIIS 0.6", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MINIIS 0.6;Prusa Generic PC MINIIS 0.6", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "MOLOCn9YKfvHMmOu", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.8.json index ecfa0c6fea..272adbb49c 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MINIIS 0.8", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MINIIS 0.8;Prusa Generic PC MINIIS 0.8", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "eJ9SwUbq1VyHBciM", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS.json index 088f2be363..dfdd628760 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MINIIS", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MINIIS;Prusa Generic PC MINIIS", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "2QWF3WdcbA7ArFgt", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.25.json index dd823e700d..db337c60b1 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MK3.5 0.25;Prusa Generic PC MK3.5 0.25", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "MWiCzFnPAeMCWxHz", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.6.json index b33d32e71d..64e7a63dbe 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MK3.5 0.6;Prusa Generic PC MK3.5 0.6", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "KEgDSg0oQi1SQlst", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.8.json index a6fa27ed6d..2564c36995 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MK3.5 0.8;Prusa Generic PC MK3.5 0.8", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "LHNmoFsylIuepyww", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5.json index 1891e65703..5a30930fa6 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa MK3.5", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC @MK3.5;Prusa Generic PC MK3.5", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "awF5u8ojSKhvSYud", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC @Prusa.json b/resources/profiles/Prusa/filament/Generic PC @Prusa.json index 59b97e22e5..c9048035b7 100644 --- a/resources/profiles/Prusa/filament/Generic PC @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PC @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Prusa", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "UJ5KpqIb5mpcNXzl", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.6.json index dbd6cb209f..37b44b73e6 100644 --- a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC HF @Prusa MINIIS 0.6", - "inherits": "Generic PC HF @Prusa base", "renamed_from": "Prusa Generic PC HF @MINIIS 0.6;Prusa Generic PC HF MINIIS 0.6", + "inherits": "Generic PC HF @Prusa base", "from": "system", "setting_id": "W3G94E0IQo6Kaq8G", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.8.json index 53bc9b96bd..941e0ef406 100644 --- a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC HF @Prusa MINIIS 0.8", - "inherits": "Generic PC HF @Prusa base", "renamed_from": "Prusa Generic PC HF @MINIIS 0.8;Prusa Generic PC HF MINIIS 0.8", + "inherits": "Generic PC HF @Prusa base", "from": "system", "setting_id": "Fjwchj1gB62f7CUF", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS.json index 4d0785504f..a25fdc2957 100644 --- a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC HF @Prusa MINIIS", - "inherits": "Generic PC HF @Prusa base", "renamed_from": "Prusa Generic PC HF @MINIIS;Prusa Generic PC HF MINIIS", + "inherits": "Generic PC HF @Prusa base", "from": "system", "setting_id": "Wodqshgvx38zWaE2", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.6.json index cb2ad5f37c..00b780d238 100644 --- a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC HF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC HF @MK3.5 0.6;Prusa Generic PC HF MK3.5 0.6", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "Rm7U967jnpk74lPA", "filament_id": "OFwwAQnA", diff --git a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.8.json index 0f684bcca8..74ed4537d9 100644 --- a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC HF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC HF @MK3.5 0.8;Prusa Generic PC HF MK3.5 0.8", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "zFkWWW3PTBvuUWqs", "filament_id": "OFwwAQnA", diff --git a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5.json index aa007446ce..f6dcd5d539 100644 --- a/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PC HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC HF @Prusa MK3.5", - "inherits": "fdm_filament_pc", "renamed_from": "Prusa Generic PC HF @MK3.5;Prusa Generic PC HF MK3.5", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "lvbcRP0xEru9jmms", "filament_id": "OFwwAQnA", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.6.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.6.json index a2f899e88f..4f53e75d4e 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One 0.6", - "inherits": "Generic PETG @Prusa CORE One", "renamed_from": "Prusa Generic PETG @CORE One 0.6;Prusa Generic PETG CORE One 0.6", + "inherits": "Generic PETG @Prusa CORE One", "from": "system", "setting_id": "oPWpCDB3p6hQeY2F", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.8.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.8.json index 669cf219fc..6e05f1a34c 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One 0.8", - "inherits": "Generic PETG @Prusa CORE One", "renamed_from": "Prusa Generic PETG @CORE One 0.8;Prusa Generic PETG CORE One 0.8", + "inherits": "Generic PETG @Prusa CORE One", "from": "system", "setting_id": "OmaayFCLuRLadur0", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.4.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.4.json index 6c9ff68c89..510e1d2baf 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.4.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One HF 0.4", - "inherits": "Generic PETG @Prusa CORE One", "renamed_from": "Prusa Generic PETG @CORE One HF 0.4;Prusa Generic PETG CORE One HF 0.4", + "inherits": "Generic PETG @Prusa CORE One", "from": "system", "setting_id": "7oUyjvRHLH4bJyX0", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.5.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.5.json index 8784e403ab..f28f5f10a3 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.5.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One HF 0.5", - "inherits": "Generic PETG @Prusa CORE One", "renamed_from": "Prusa Generic PETG @CORE One HF 0.5;Prusa Generic PETG CORE One HF 0.5", + "inherits": "Generic PETG @Prusa CORE One", "from": "system", "setting_id": "6HiIOGURZWwman1l", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.6.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.6.json index c0eb6a594f..53dd49907d 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One HF 0.6", - "inherits": "Generic PETG @Prusa CORE One", "renamed_from": "Prusa Generic PETG @CORE One HF 0.6;Prusa Generic PETG CORE One HF 0.6", + "inherits": "Generic PETG @Prusa CORE One", "from": "system", "setting_id": "KKiug7A9NOQPe1m7", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.8.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.8.json index 99748978bf..fc9ac8b755 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One HF 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One HF 0.8", - "inherits": "Generic PETG @Prusa CORE One", "renamed_from": "Prusa Generic PETG @CORE One HF 0.8;Prusa Generic PETG CORE One HF 0.8", + "inherits": "Generic PETG @Prusa CORE One", "from": "system", "setting_id": "vtiAC44hrmtap0Ou", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One.json index a086fb9336..1c940b74b1 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa CORE One.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa CORE One", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG @CORE One;Prusa Generic PETG CORE One", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "W71PW5bpf7CV16D4", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.25.json index 282048f6a3..a6e262c483 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MINIIS 0.25", - "inherits": "Generic PETG @Prusa base", "renamed_from": "Prusa Generic PETG @MINIIS 0.25;Prusa Generic PETG MINIIS 0.25", + "inherits": "Generic PETG @Prusa base", "from": "system", "setting_id": "lKegAyiWytPNEXH0", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.6.json index 40f6d0c685..d0f73f75ef 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MINIIS 0.6", - "inherits": "Generic PETG @Prusa base", "renamed_from": "Prusa Generic PETG @MINIIS 0.6;Prusa Generic PETG MINIIS 0.6", + "inherits": "Generic PETG @Prusa base", "from": "system", "setting_id": "7QT1EXl4qKoNBuqz", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.8.json index a578482dc0..353d01603c 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MINIIS 0.8", - "inherits": "Generic PETG @Prusa base", "renamed_from": "Prusa Generic PETG @MINIIS 0.8;Prusa Generic PETG MINIIS 0.8", + "inherits": "Generic PETG @Prusa base", "from": "system", "setting_id": "zl2HOUtcoIR2dFQH", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS.json index 5a135dfd2d..c5df3291e1 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MINIIS", - "inherits": "Generic PETG @Prusa base", "renamed_from": "Prusa Generic PETG @MINIIS;Prusa Generic PETG MINIIS", + "inherits": "Generic PETG @Prusa base", "from": "system", "setting_id": "COQ9qpnYRGAFRBoq", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.25.json index e338514096..66cbb86acc 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG @MK3.5 0.25;Prusa Generic PETG MK3.5 0.25", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "M0vmzxmP3IVIUTuv", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.6.json index d57e0fdb3f..9ffccc5462 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG @MK3.5 0.6;Prusa Generic PETG MK3.5 0.6", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "OvkhxGhjjRMjwb4C", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.8.json index 59e45d94f6..1b83f6983e 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG @MK3.5 0.8;Prusa Generic PETG MK3.5 0.8", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "kZSlkCTdghAi8LFG", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5.json index 7d63599c7a..4d868e63e0 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK3.5", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG @MK3.5;Prusa Generic PETG MK3.5", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "6PUbXHNUBfWjVvse", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4.json index 68f627daa4..167303226a 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4", - "inherits": "Generic PETG @Prusa base", "renamed_from": "Prusa Generic PETG @MK4;Prusa Generic PETG MK4", + "inherits": "Generic PETG @Prusa base", "from": "system", "setting_id": "ieo6hcpwnV0j76eo", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.6.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.6.json index ddfbb665be..f755d3343c 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S 0.6", - "inherits": "Generic PETG @Prusa MK4S", "renamed_from": "Prusa Generic PETG @MK4S 0.6;Prusa Generic PETG MK4S 0.6", + "inherits": "Generic PETG @Prusa MK4S", "from": "system", "setting_id": "z5Ys1AU5ujQF9D5U", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.8.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.8.json index 8e8fee1973..77aabc46a0 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S 0.8", - "inherits": "Generic PETG @Prusa MK4S", "renamed_from": "Prusa Generic PETG @MK4S 0.8;Prusa Generic PETG MK4S 0.8", + "inherits": "Generic PETG @Prusa MK4S", "from": "system", "setting_id": "LKUzA7cbyYL6kxar", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.4.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.4.json index ebbdb73717..ef4945eb07 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.4.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S HF0.4", - "inherits": "Generic PETG @Prusa MK4S", "renamed_from": "Prusa Generic PETG @MK4S HF0.4;Prusa Generic PETG MK4S HF0.4", + "inherits": "Generic PETG @Prusa MK4S", "from": "system", "setting_id": "lLapCyweW6Svj7cV", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.5.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.5.json index e424f13c82..ba6a2d5373 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.5.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S HF0.5", - "inherits": "Generic PETG @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic PETG @MK4S HF0.5;Prusa Generic PETG MK4S HF0.5", + "inherits": "Generic PETG @Prusa MK4S HF0.4", "from": "system", "setting_id": "lu9twhsjDkBT1kyn", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.6.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.6.json index c0d46b3ca1..2835358872 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S HF0.6", - "inherits": "Generic PETG @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic PETG @MK4S HF0.6;Prusa Generic PETG MK4S HF0.6", + "inherits": "Generic PETG @Prusa MK4S HF0.4", "from": "system", "setting_id": "d7ocKzA4YSAit63Z", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.8.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.8.json index 237c3f116a..cb2834ee4b 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S HF0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S HF0.8", - "inherits": "Generic PETG @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic PETG @MK4S HF0.8;Prusa Generic PETG MK4S HF0.8", + "inherits": "Generic PETG @Prusa MK4S HF0.4", "from": "system", "setting_id": "HSBSswxwznxDClK5", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S.json index b7bbc6094e..8126c317cd 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa MK4S.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa MK4S", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG @MK4S;Prusa Generic PETG MK4S", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "t3ZCKWVct5d69cb8", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Prusa/filament/Generic PETG @Prusa.json b/resources/profiles/Prusa/filament/Generic PETG @Prusa.json index 6881507204..dd9029f4c4 100644 --- a/resources/profiles/Prusa/filament/Generic PETG @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PETG @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Prusa", - "inherits": "Generic PETG @Prusa base", "renamed_from": "Prusa Generic PETG", + "inherits": "Generic PETG @Prusa base", "from": "system", "setting_id": "Vwc0owmwoEYrLhuU", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.6.json index e8de400490..24584986f2 100644 --- a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG HF @Prusa MINIIS 0.6", - "inherits": "Generic PETG HF @Prusa base", "renamed_from": "Prusa Generic PETG HF @MINIIS 0.6;Prusa Generic PETG HF MINIIS 0.6", + "inherits": "Generic PETG HF @Prusa base", "from": "system", "setting_id": "nF8YzRMvaT4D8LBD", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.8.json index adc5401268..5a50d4e42c 100644 --- a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG HF @Prusa MINIIS 0.8", - "inherits": "Generic PETG HF @Prusa base", "renamed_from": "Prusa Generic PETG HF @MINIIS 0.8;Prusa Generic PETG HF MINIIS 0.8", + "inherits": "Generic PETG HF @Prusa base", "from": "system", "setting_id": "7itUjrAu9Oj9hxiU", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS.json index 9148f5e849..1c2f083063 100644 --- a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG HF @Prusa MINIIS", - "inherits": "Generic PETG HF @Prusa base", "renamed_from": "Prusa Generic PETG HF @MINIIS;Prusa Generic PETG HF MINIIS", + "inherits": "Generic PETG HF @Prusa base", "from": "system", "setting_id": "dPNOryBcrviemefo", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.6.json index 71481537b1..c799624fcf 100644 --- a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG HF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG HF @MK3.5 0.6;Prusa Generic PETG HF MK3.5 0.6", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "YqVidH7m1HXR3hHZ", "filament_id": "OF7lOgYF", diff --git a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.8.json index 5dffe82d0b..e5811d0eb7 100644 --- a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG HF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG HF @MK3.5 0.8;Prusa Generic PETG HF MK3.5 0.8", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "vfR067tK5WsrE4pw", "filament_id": "OF7lOgYF", diff --git a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5.json index e343519efd..c5bcb47158 100644 --- a/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PETG HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG HF @Prusa MK3.5", - "inherits": "fdm_filament_pet", "renamed_from": "Prusa Generic PETG HF @MK3.5;Prusa Generic PETG HF MK3.5", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "grvZIUU79fxDOa3O", "filament_id": "OF7lOgYF", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.6.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.6.json index 2e2f9275d4..009a827c7f 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One 0.6", - "inherits": "Generic PLA @Prusa CORE One", "renamed_from": "Prusa Generic PLA @CORE One 0.6;Prusa Generic PLA CORE One 0.6", + "inherits": "Generic PLA @Prusa CORE One", "from": "system", "setting_id": "IkmLxDwrdRkacHWw", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.8.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.8.json index cfe88119de..18a60b5cc1 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One 0.8", - "inherits": "Generic PLA @Prusa CORE One", "renamed_from": "Prusa Generic PLA @CORE One 0.8;Prusa Generic PLA CORE One 0.8", + "inherits": "Generic PLA @Prusa CORE One", "from": "system", "setting_id": "aBengWdqRXg9i2sx", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.4.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.4.json index c0969904c7..e821c4d97d 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.4.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One HF 0.4", - "inherits": "Generic PLA @Prusa CORE One", "renamed_from": "Prusa Generic PLA @CORE One HF 0.4;Prusa Generic PLA CORE One HF 0.4", + "inherits": "Generic PLA @Prusa CORE One", "from": "system", "setting_id": "vniEPaoyABoAfLFa", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.5.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.5.json index 5d6e9fcba2..af02d26924 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.5.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One HF 0.5", - "inherits": "Generic PLA @Prusa CORE One", "renamed_from": "Prusa Generic PLA @CORE One HF 0.5;Prusa Generic PLA CORE One HF 0.5", + "inherits": "Generic PLA @Prusa CORE One", "from": "system", "setting_id": "NPEs4gtBlKWupYZX", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.6.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.6.json index 6575aebf8d..dd830e04cd 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One HF 0.6", - "inherits": "Generic PLA @Prusa CORE One", "renamed_from": "Prusa Generic PLA @CORE One HF 0.6;Prusa Generic PLA CORE One HF 0.6", + "inherits": "Generic PLA @Prusa CORE One", "from": "system", "setting_id": "SnfULjrWGCiA7ljq", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.8.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.8.json index 64471ba72b..45efb6df87 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One HF 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One HF 0.8", - "inherits": "Generic PLA @Prusa CORE One", "renamed_from": "Prusa Generic PLA @CORE One HF 0.8;Prusa Generic PLA CORE One HF 0.8", + "inherits": "Generic PLA @Prusa CORE One", "from": "system", "setting_id": "ZsIuxJUaBzoeWPDv", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One.json index 9bc9e086b0..d16a6c0366 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa CORE One.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa CORE One", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA @CORE One;Prusa Generic PLA CORE One", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "r2i4c7DsYXYIMVCX", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.25.json index 3682a6fcb0..1ac72b15e4 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MINIIS 0.25", - "inherits": "Generic PLA @Prusa base", "renamed_from": "Prusa Generic PLA @MINIIS 0.25;Prusa Generic PLA MINIIS 0.25", + "inherits": "Generic PLA @Prusa base", "from": "system", "setting_id": "t7jm6WSfRqsdSZfz", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.6.json index ae982f46bc..2701d684c6 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MINIIS 0.6", - "inherits": "Generic PLA @Prusa base", "renamed_from": "Prusa Generic PLA @MINIIS 0.6;Prusa Generic PLA MINIIS 0.6", + "inherits": "Generic PLA @Prusa base", "from": "system", "setting_id": "hWk01xYl6gu41B4w", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.8.json index 8a5897d741..77defbf7c1 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MINIIS 0.8", - "inherits": "Generic PLA @Prusa base", "renamed_from": "Prusa Generic PLA @MINIIS 0.8;Prusa Generic PLA MINIIS 0.8", + "inherits": "Generic PLA @Prusa base", "from": "system", "setting_id": "6A9NivZl5nMpNfsz", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS.json index cf2adda390..1a3429b6a7 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MINIIS", - "inherits": "Generic PLA @Prusa base", "renamed_from": "Prusa Generic PLA @MINIIS;Prusa Generic PLA MINIIS", + "inherits": "Generic PLA @Prusa base", "from": "system", "setting_id": "3bPlO5U5udlu8eVv", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.25.json index b3f84dc4e1..3e831471cf 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA @MK3.5 0.25;Prusa Generic PLA MK3.5 0.25", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "IJsZsvdG7N8uwobX", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.6.json index 49d75d5e31..d75f11c181 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA @MK3.5 0.6;Prusa Generic PLA MK3.5 0.6", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "YLx95teMRy5UQWKN", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.8.json index 6590e43c17..0cadf43880 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA @MK3.5 0.8;Prusa Generic PLA MK3.5 0.8", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "bZ42VSqIaJlri1VH", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5.json index 058e05e99e..75bd9f92d2 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK3.5", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA @MK3.5;Prusa Generic PLA MK3.5", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "5tDjTVPzE0lIEReK", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4.json index e7cc5df0d8..548980044c 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4", - "inherits": "Generic PLA @Prusa base", "renamed_from": "Prusa Generic PLA @MK4;Prusa Generic PLA MK4", + "inherits": "Generic PLA @Prusa base", "from": "system", "setting_id": "cBqjSJcxcXvS8sY0", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.6.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.6.json index bcc0847385..ab91482338 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S 0.6", - "inherits": "Generic PLA @Prusa MK4S", "renamed_from": "Prusa Generic PLA @MK4S 0.6;Prusa Generic PLA MK4S 0.6", + "inherits": "Generic PLA @Prusa MK4S", "from": "system", "setting_id": "vLeTzdoXExkeNSdX", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.8.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.8.json index e574ce49a5..92ae855bfe 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S 0.8", - "inherits": "Generic PLA @Prusa MK4S", "renamed_from": "Prusa Generic PLA @MK4S 0.8;Prusa Generic PLA MK4S 0.8", + "inherits": "Generic PLA @Prusa MK4S", "from": "system", "setting_id": "6fyFsevbPLYfgZRb", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.4.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.4.json index 10e37500a8..6ba97466d4 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.4.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S HF0.4", - "inherits": "Generic PLA @Prusa MK4S", "renamed_from": "Prusa Generic PLA @MK4S HF0.4;Prusa Generic PLA MK4S HF0.4", + "inherits": "Generic PLA @Prusa MK4S", "from": "system", "setting_id": "BFvt90DhCobphEF9", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.5.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.5.json index ec1efb5aad..9c227baa46 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.5.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S HF0.5", - "inherits": "Generic PLA @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic PLA @MK4S HF0.5;Prusa Generic PLA MK4S HF0.5", + "inherits": "Generic PLA @Prusa MK4S HF0.4", "from": "system", "setting_id": "IDv2UUR8EH7AVUIA", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.6.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.6.json index 8ce85314dd..5f9bbba153 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S HF0.6", - "inherits": "Generic PLA @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic PLA @MK4S HF0.6;Prusa Generic PLA MK4S HF0.6", + "inherits": "Generic PLA @Prusa MK4S HF0.4", "from": "system", "setting_id": "t7cAPFNPWmeHBeuD", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.8.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.8.json index 968bf56356..383c210e4f 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S HF0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S HF0.8", - "inherits": "Generic PLA @Prusa MK4S HF0.4", "renamed_from": "Prusa Generic PLA @MK4S HF0.8;Prusa Generic PLA MK4S HF0.8", + "inherits": "Generic PLA @Prusa MK4S HF0.4", "from": "system", "setting_id": "t1a58q4l6Xo6kKCC", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S.json index a847cf8334..be71cb6113 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa MK4S.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa MK4S", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA @MK4S;Prusa Generic PLA MK4S", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "lsjHMlvwZzImWgek", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Prusa/filament/Generic PLA @Prusa.json b/resources/profiles/Prusa/filament/Generic PLA @Prusa.json index 83951fb4ab..5e262da446 100644 --- a/resources/profiles/Prusa/filament/Generic PLA @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PLA @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Prusa", - "inherits": "Generic PLA @Prusa base", "renamed_from": "Prusa Generic PLA", + "inherits": "Generic PLA @Prusa base", "from": "system", "setting_id": "SBviEhhXcdsIwj0y", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.6.json index 56c2e823b0..9459c8734a 100644 --- a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Prusa MINIIS 0.6", - "inherits": "Generic PLA HF @Prusa base", "renamed_from": "Prusa Generic PLA HF @MINIIS 0.6;Prusa Generic PLA HF MINIIS 0.6", + "inherits": "Generic PLA HF @Prusa base", "from": "system", "setting_id": "eqBN6ykUB4csEMCR", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.8.json index be0722c134..232e4b6638 100644 --- a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Prusa MINIIS 0.8", - "inherits": "Generic PLA HF @Prusa base", "renamed_from": "Prusa Generic PLA HF @MINIIS 0.8;Prusa Generic PLA HF MINIIS 0.8", + "inherits": "Generic PLA HF @Prusa base", "from": "system", "setting_id": "FuCHQFBuP9yLUzT0", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS.json index 656c756e6d..c59708df52 100644 --- a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Prusa MINIIS", - "inherits": "Generic PLA HF @Prusa base", "renamed_from": "Prusa Generic PLA HF @MINIIS;Prusa Generic PLA HF MINIIS", + "inherits": "Generic PLA HF @Prusa base", "from": "system", "setting_id": "cQJUt7LR5hkKT0Za", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.6.json index 41dce0b5ed..e738c7104e 100644 --- a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA HF @MK3.5 0.6;Prusa Generic PLA HF MK3.5 0.6", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "5vgrugarZSgMZ6FT", "filament_id": "OFZr862X", diff --git a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.8.json index b6af02d8fb..90ce533d55 100644 --- a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA HF @MK3.5 0.8;Prusa Generic PLA HF MK3.5 0.8", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "CM3EYkpRcWwsw7KB", "filament_id": "OFZr862X", diff --git a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5.json index 46ed4d0752..a4a7e5a583 100644 --- a/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PLA HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA HF @Prusa MK3.5", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA HF @MK3.5;Prusa Generic PLA HF MK3.5", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "4N82rUxi9Bbm2Cdd", "filament_id": "OFZr862X", diff --git a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.6.json b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.6.json index aeeba4d5ee..7772677dad 100644 --- a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Prusa CORE One 0.6", - "inherits": "Generic PLA Silk @Prusa CORE One", "renamed_from": "Prusa Generic PLA Silk @CORE One 0.6;Prusa Generic PLA Silk CORE One 0.6", + "inherits": "Generic PLA Silk @Prusa CORE One", "from": "system", "setting_id": "nBWqKjSKw2UEAmkv", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.8.json b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.8.json index 82e3840d37..8eddb354ab 100644 --- a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Prusa CORE One 0.8", - "inherits": "Generic PLA Silk @Prusa CORE One", "renamed_from": "Prusa Generic PLA Silk @CORE One 0.8;Prusa Generic PLA Silk CORE One 0.8", + "inherits": "Generic PLA Silk @Prusa CORE One", "from": "system", "setting_id": "a2KWbhOMQrFTkAZh", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One.json b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One.json index c11965fc72..ba4c693334 100644 --- a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One.json +++ b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa CORE One.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Prusa CORE One", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA Silk @CORE One;Prusa Generic PLA Silk CORE One", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "F9lNHyhZwZi7aD74", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.6.json b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.6.json index 82413605dc..29df44572b 100644 --- a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Prusa MK4S 0.6", - "inherits": "Generic PLA Silk @Prusa MK4S", "renamed_from": "Prusa Generic PLA Silk @MK4S 0.6;Prusa Generic PLA Silk MK4S 0.6", + "inherits": "Generic PLA Silk @Prusa MK4S", "from": "system", "setting_id": "lWYrhnu1MUizrdOB", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.8.json b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.8.json index e94cbdf57a..1342eb8ce2 100644 --- a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Prusa MK4S 0.8", - "inherits": "Generic PLA Silk @Prusa MK4S", "renamed_from": "Prusa Generic PLA Silk @MK4S 0.8;Prusa Generic PLA Silk MK4S 0.8", + "inherits": "Generic PLA Silk @Prusa MK4S", "from": "system", "setting_id": "cyBdMwJ5sAZcQ7wP", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S.json b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S.json index 9a3830fd4a..6f3149cb30 100644 --- a/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S.json +++ b/resources/profiles/Prusa/filament/Generic PLA Silk @Prusa MK4S.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Prusa MK4S", - "inherits": "Generic PLA @Prusa MK4S", "renamed_from": "Prusa Generic PLA Silk @MK4S;Prusa Generic PLA Silk MK4S", + "inherits": "Generic PLA @Prusa MK4S", "from": "system", "setting_id": "9VQ1YVv9EZexIUoF", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.25.json index 9432c36087..201fc6558b 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MINIIS 0.25", - "inherits": "Generic PLA-CF @Prusa base", "renamed_from": "Prusa Generic PLA-CF @MINIIS 0.25;Prusa Generic PLA-CF MINIIS 0.25", + "inherits": "Generic PLA-CF @Prusa base", "from": "system", "setting_id": "uQJghHEl91slhmEP", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.6.json index 7900e25ab2..97708e2263 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MINIIS 0.6", - "inherits": "Generic PLA-CF @Prusa base", "renamed_from": "Prusa Generic PLA-CF @MINIIS 0.6;Prusa Generic PLA-CF MINIIS 0.6", + "inherits": "Generic PLA-CF @Prusa base", "from": "system", "setting_id": "nZEIrx6XaOFsNyHS", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.8.json index 97db4345c8..df0fd97bb1 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MINIIS 0.8", - "inherits": "Generic PLA-CF @Prusa base", "renamed_from": "Prusa Generic PLA-CF @MINIIS 0.8;Prusa Generic PLA-CF MINIIS 0.8", + "inherits": "Generic PLA-CF @Prusa base", "from": "system", "setting_id": "A3VUqeRysd3c5Txq", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS.json index 4c08a4b23c..532dc5f299 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MINIIS", - "inherits": "Generic PLA-CF @Prusa base", "renamed_from": "Prusa Generic PLA-CF @MINIIS;Prusa Generic PLA-CF MINIIS", + "inherits": "Generic PLA-CF @Prusa base", "from": "system", "setting_id": "cNZereL1ltFYG5FZ", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.25.json index 436bf22209..7174067503 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA-CF @MK3.5 0.25;Prusa Generic PLA-CF MK3.5 0.25", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "eID2rl5MlHlkerrQ", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.6.json index db1973c5c8..f81dea6a16 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA-CF @MK3.5 0.6;Prusa Generic PLA-CF MK3.5 0.6", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "FGXPEP83zLoINOZy", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.8.json index bfcbcf2dbc..9d1d02d6c3 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA-CF @MK3.5 0.8;Prusa Generic PLA-CF MK3.5 0.8", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "TM5JPaNUTlZTiuCe", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5.json index 677bbc0d27..5bbd23098d 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa MK3.5", - "inherits": "fdm_filament_pla", "renamed_from": "Prusa Generic PLA-CF @MK3.5;Prusa Generic PLA-CF MK3.5", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "3qImFrQCon7iUj4c", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa.json b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa.json index c572b9f67c..b57c07f4a2 100644 --- a/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PLA-CF @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Prusa", - "inherits": "Generic PLA-CF @Prusa base", "renamed_from": "Prusa Generic PLA-CF", + "inherits": "Generic PLA-CF @Prusa base", "from": "system", "setting_id": "LIL5n1PzMoaNoJ84", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.25.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.25.json index f74228304a..a0485636b5 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MINIIS 0.25", - "inherits": "Generic PVA @Prusa base", "renamed_from": "Prusa Generic PVA @MINIIS 0.25;Prusa Generic PVA MINIIS 0.25", + "inherits": "Generic PVA @Prusa base", "from": "system", "setting_id": "2TecWVXOXcxW37EN", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.6.json index f25c70a70c..7827888a46 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MINIIS 0.6", - "inherits": "Generic PVA @Prusa base", "renamed_from": "Prusa Generic PVA @MINIIS 0.6;Prusa Generic PVA MINIIS 0.6", + "inherits": "Generic PVA @Prusa base", "from": "system", "setting_id": "3UTClbjiwrQUCXsV", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.8.json index 90c4fc2256..1313511a55 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MINIIS 0.8", - "inherits": "Generic PVA @Prusa base", "renamed_from": "Prusa Generic PVA @MINIIS 0.8;Prusa Generic PVA MINIIS 0.8", + "inherits": "Generic PVA @Prusa base", "from": "system", "setting_id": "RKxewqskgDD2DQTk", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS.json index 99014f18a3..221a384ebc 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MINIIS", - "inherits": "Generic PVA @Prusa base", "renamed_from": "Prusa Generic PVA @MINIIS;Prusa Generic PVA MINIIS", + "inherits": "Generic PVA @Prusa base", "from": "system", "setting_id": "XfJmxNhCJiWTWB9i", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.25.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.25.json index a13990f6c7..28d8b6eff4 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.25.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.25.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MK3.5 0.25", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA @MK3.5 0.25;Prusa Generic PVA MK3.5 0.25", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "P9y77rdSQsCFcFwr", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.6.json index 8854a19282..8543ffbf2d 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA @MK3.5 0.6;Prusa Generic PVA MK3.5 0.6", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "rvSzvHZL6FIiOQV1", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.8.json index 718845dc9a..d2c6e71ab8 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA @MK3.5 0.8;Prusa Generic PVA MK3.5 0.8", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "E2sA3y3Cyp0UsQD4", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5.json index 6e1e1c9381..5d895dd35f 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa MK3.5", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA @MK3.5;Prusa Generic PVA MK3.5", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "UTyXSJox9HVdwfXR", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Prusa/filament/Generic PVA @Prusa.json b/resources/profiles/Prusa/filament/Generic PVA @Prusa.json index 3ad6ba8337..5d11a4e854 100644 --- a/resources/profiles/Prusa/filament/Generic PVA @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic PVA @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Prusa", - "inherits": "Generic PVA @Prusa base", "renamed_from": "Prusa Generic PVA", + "inherits": "Generic PVA @Prusa base", "from": "system", "setting_id": "uVzUlzHkXz6rH1ml", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.6.json b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.6.json index f4e03d791f..b6d9877fe8 100644 --- a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA HF @Prusa MINIIS 0.6", - "inherits": "Generic PVA HF @Prusa base", "renamed_from": "Prusa Generic PVA HF @MINIIS 0.6;Prusa Generic PVA HF MINIIS 0.6", + "inherits": "Generic PVA HF @Prusa base", "from": "system", "setting_id": "qeWFOMhrKa1yezHw", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.8.json b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.8.json index e8935f9172..55510df02d 100644 --- a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA HF @Prusa MINIIS 0.8", - "inherits": "Generic PVA HF @Prusa base", "renamed_from": "Prusa Generic PVA HF @MINIIS 0.8;Prusa Generic PVA HF MINIIS 0.8", + "inherits": "Generic PVA HF @Prusa base", "from": "system", "setting_id": "h0RQ3XME0UFEeZVA", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS.json index a4a131da97..d15d79a5a1 100644 --- a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA HF @Prusa MINIIS", - "inherits": "Generic PVA HF @Prusa base", "renamed_from": "Prusa Generic PVA HF @MINIIS;Prusa Generic PVA HF MINIIS", + "inherits": "Generic PVA HF @Prusa base", "from": "system", "setting_id": "VZcvmjCAtivpMepD", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.6.json b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.6.json index 1b78b6b0bc..299a2925c0 100644 --- a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.6.json +++ b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA HF @Prusa MK3.5 0.6", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA HF @MK3.5 0.6;Prusa Generic PVA HF MK3.5 0.6", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "8R3yU9OjRFBIp1nU", "filament_id": "OFDwBwO5", diff --git a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.8.json b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.8.json index 94f635382e..b7793a0dcf 100644 --- a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.8.json +++ b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA HF @Prusa MK3.5 0.8", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA HF @MK3.5 0.8;Prusa Generic PVA HF MK3.5 0.8", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "OOUVHHPIB95wqeTB", "filament_id": "OFDwBwO5", diff --git a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5.json index c3749316e9..9b50e42404 100644 --- a/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic PVA HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA HF @Prusa MK3.5", - "inherits": "fdm_filament_pva", "renamed_from": "Prusa Generic PVA HF @MK3.5;Prusa Generic PVA HF MK3.5", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "gTh9PfBYkibWdknz", "filament_id": "OFDwBwO5", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.6.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.6.json index dc68ea318c..018ffeb1b7 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.6.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa CORE One 0.6", - "inherits": "Generic TPU @Prusa CORE One", "renamed_from": "Prusa Generic TPU @CORE One 0.6;Prusa Generic TPU CORE One 0.6", + "inherits": "Generic TPU @Prusa CORE One", "from": "system", "setting_id": "VvvSk3OsXXxyerAX", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.8.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.8.json index 93b68e0afa..c4d79ea162 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.8.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa CORE One 0.8", - "inherits": "Generic TPU @Prusa CORE One", "renamed_from": "Prusa Generic TPU @CORE One 0.8;Prusa Generic TPU CORE One 0.8", + "inherits": "Generic TPU @Prusa CORE One", "from": "system", "setting_id": "LUUEXi6UUk0Zs5Pf", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One.json index 3717f8586a..ae0a3edf7b 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa CORE One.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa CORE One", - "inherits": "fdm_filament_flex", "renamed_from": "Prusa Generic TPU @CORE One;Prusa Generic TPU CORE One", + "inherits": "fdm_filament_flex", "from": "system", "setting_id": "jsXqf9CeaXCvsrWM", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa MINIIS.json index 85c60e64a8..f76317163d 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa MINIIS", - "inherits": "Generic TPU @Prusa base", "renamed_from": "Prusa Generic TPU @MINIIS;Prusa Generic TPU MINIIS", + "inherits": "Generic TPU @Prusa base", "from": "system", "setting_id": "bOai5Ib1dggl5Qlc", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK3.5.json index 3e72481ea7..65c6989baf 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa MK3.5", - "inherits": "fdm_filament_tpu", "renamed_from": "Prusa Generic TPU @MK3.5;Prusa Generic TPU MK3.5", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "j6bDPJnwtsB16yBu", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4.json index 52c7ebf182..cc2959bcc5 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa MK4", - "inherits": "Generic TPU @Prusa base", "renamed_from": "Prusa Generic TPU @MK4;Prusa Generic TPU MK4", + "inherits": "Generic TPU @Prusa base", "from": "system", "setting_id": "9wL3LAJZ7PyqBVEb", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.6.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.6.json index 4b5399bd89..674f3bf3d4 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.6.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.6.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa MK4S 0.6", - "inherits": "Generic TPU @Prusa MK4S", "renamed_from": "Prusa Generic TPU @MK4S 0.6;Prusa Generic TPU MK4S 0.6", + "inherits": "Generic TPU @Prusa MK4S", "from": "system", "setting_id": "XM427EDbbCgt2wNZ", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.8.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.8.json index 3a663958f1..a10c0bb03c 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.8.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S 0.8.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa MK4S 0.8", - "inherits": "Generic TPU @Prusa MK4S", "renamed_from": "Prusa Generic TPU @MK4S 0.8;Prusa Generic TPU MK4S 0.8", + "inherits": "Generic TPU @Prusa MK4S", "from": "system", "setting_id": "2UPIZFNertdlZ4o2", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S.json index 75f1895c87..beeefc6393 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa MK4S.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa MK4S", - "inherits": "fdm_filament_tpu", "renamed_from": "Prusa Generic TPU @MK4S;Prusa Generic TPU MK4S", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "wdopbtHBnMKC2rhj", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Prusa/filament/Generic TPU @Prusa.json b/resources/profiles/Prusa/filament/Generic TPU @Prusa.json index 95048f947c..0e51d2d827 100644 --- a/resources/profiles/Prusa/filament/Generic TPU @Prusa.json +++ b/resources/profiles/Prusa/filament/Generic TPU @Prusa.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Prusa", - "inherits": "Generic TPU @Prusa base", "renamed_from": "Prusa Generic TPU", + "inherits": "Generic TPU @Prusa base", "from": "system", "setting_id": "bmtq13tfalfSTRrO", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MINIIS.json b/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MINIIS.json index 4c4ab81b42..dc35f57d09 100644 --- a/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MINIIS.json +++ b/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MINIIS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU HF @Prusa MINIIS", - "inherits": "Generic TPU HF @Prusa base", "renamed_from": "Prusa Generic TPU HF @MINIIS;Prusa Generic TPU HF MINIIS", + "inherits": "Generic TPU HF @Prusa base", "from": "system", "setting_id": "Jw1UjgrXtYG5rMDt", "instantiation": "true", diff --git a/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MK3.5.json b/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MK3.5.json index f958cac588..cc0c571567 100644 --- a/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MK3.5.json +++ b/resources/profiles/Prusa/filament/Generic TPU HF @Prusa MK3.5.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU HF @Prusa MK3.5", - "inherits": "fdm_filament_tpu", "renamed_from": "Prusa Generic TPU HF @MK3.5;Prusa Generic TPU HF MK3.5", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "W8pYAV5JMW70PKlw", "filament_id": "OFnT7Qpb", diff --git a/resources/profiles/Prusa/machine/Prusa MINIIS 0.4 nozzle.json b/resources/profiles/Prusa/machine/Prusa MINIIS 0.4 nozzle.json index 18fe72ef3f..9890e6c88e 100644 --- a/resources/profiles/Prusa/machine/Prusa MINIIS 0.4 nozzle.json +++ b/resources/profiles/Prusa/machine/Prusa MINIIS 0.4 nozzle.json @@ -96,6 +96,7 @@ "0.2" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "fan_speedup_time": "0.2", diff --git a/resources/profiles/Prusa/machine/Prusa MK3.5 0.4 nozzle.json b/resources/profiles/Prusa/machine/Prusa MK3.5 0.4 nozzle.json index ae7df2e583..0c7c1de00f 100644 --- a/resources/profiles/Prusa/machine/Prusa MK3.5 0.4 nozzle.json +++ b/resources/profiles/Prusa/machine/Prusa MK3.5 0.4 nozzle.json @@ -96,6 +96,7 @@ "0.2" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "fan_speedup_time": "0.2", diff --git a/resources/profiles/Qidi.json b/resources/profiles/Qidi.json index 4ccb243fe3..4b6496df31 100644 --- a/resources/profiles/Qidi.json +++ b/resources/profiles/Qidi.json @@ -1,6 +1,6 @@ { "name": "Qidi", - "version": "02.04.00.15", + "version": "02.04.00.16", "force_update": "0", "description": "Qidi configurations", "machine_model_list": [ diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.2 nozzle.json index 2ca51212e7..b9a712df46 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi Q1 Pro 0.2 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi Q1 Pro 0.2 nozzle;Qidi Generic ABS Qidi Q1 Pro 0.2 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "IQDYfIQsv6WlnA3z", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.4 nozzle.json index 7c22168a8e..9f67b4ed0c 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi Q1 Pro 0.4 nozzle;Qidi Generic ABS Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "YS0ov4dEWAJhRRvk", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.6 nozzle.json index b16d7783b2..ed830abf62 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi Q1 Pro 0.6 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi Q1 Pro 0.6 nozzle;Qidi Generic ABS Qidi Q1 Pro 0.6 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "LQTfTgV2MBEm6DDD", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.8 nozzle.json index 61f33e870a..fcc954bd1d 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi Q1 Pro 0.8 nozzle;Qidi Generic ABS Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "ZWOlrWQQwvsDV8xa", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Max 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Max 3 0.2 nozzle.json index fcb9b9f547..5b8101c544 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Max 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Max 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Max 3 0.2 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Max 3 0.2 nozzle;Qidi Generic ABS Qidi X-Max 3 0.2 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "v7w2dLJ1MtUjvy1l", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 3 0.2 nozzle.json index c52716ea4b..7d82df3dfe 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Plus 3 0.2 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Plus 3 0.2 nozzle;Qidi Generic ABS Qidi X-Plus 3 0.2 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "vH2jlch11zfDBUPP", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.2 nozzle.json index 521521c0fe..d6608ea9c7 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Plus 4 0.2 nozzle;Qidi Generic ABS Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "0bwmAx9OQYm5MwVE", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.4 nozzle.json index b5bbbdbf47..ce1d6d1031 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Plus 4 0.4 nozzle;Qidi Generic ABS Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "Y3yAythmKXxr76Pg", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.6 nozzle.json index 27ef9809e8..2d220fae24 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Plus 4 0.6 nozzle;Qidi Generic ABS Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "Bt8ySpZn6WFWC00A", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.8 nozzle.json index 3dcc3d5889..5f70d001c9 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Plus 4 0.8 nozzle;Qidi Generic ABS Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "7j3bweJutseUaoZQ", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Smart 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Smart 3 0.2 nozzle.json index 7503ba737d..abb68163d7 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Smart 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi X-Smart 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi X-Smart 3 0.2 nozzle", - "inherits": "Generic ABS @Qidi", "renamed_from": "Qidi Generic ABS @Qidi X-Smart 3 0.2 nozzle;Qidi Generic ABS Qidi X-Smart 3 0.2 nozzle", + "inherits": "Generic ABS @Qidi", "from": "system", "setting_id": "StJpaMQKORYm7i94", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ABS @Qidi.json b/resources/profiles/Qidi/filament/Generic ABS @Qidi.json index 76a01a3fa6..94bff391e1 100644 --- a/resources/profiles/Qidi/filament/Generic ABS @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic ABS @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Qidi", - "inherits": "fdm_filament_abs", "renamed_from": "Qidi Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "iO5utPsBKAo7cHop", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.2 nozzle.json index 749dddc689..131ed3d9bc 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi Q1 Pro 0.2 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi Q1 Pro 0.2 nozzle;Qidi Generic ASA Qidi Q1 Pro 0.2 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "3LUibDTlv799Gy6r", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.4 nozzle.json index f8ef61a4aa..40aa8e0cce 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi Q1 Pro 0.4 nozzle;Qidi Generic ASA Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "EtjXhHzpmShNgIqj", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.6 nozzle.json index cef5172ed5..042d20b807 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi Q1 Pro 0.6 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi Q1 Pro 0.6 nozzle;Qidi Generic ASA Qidi Q1 Pro 0.6 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "5hlUjx0YAFTR9TYr", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.8 nozzle.json index 93b389d444..beaa056c27 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi Q1 Pro 0.8 nozzle;Qidi Generic ASA Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "oArSgOFOlXLGkueW", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Max 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Max 3 0.2 nozzle.json index 38b0088adb..61b4f99d0b 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Max 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Max 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Max 3 0.2 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Max 3 0.2 nozzle;Qidi Generic ASA Qidi X-Max 3 0.2 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "LfT1OaNir4KZevUP", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 3 0.2 nozzle.json index c0e92e8f7c..e324f211d0 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Plus 3 0.2 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Plus 3 0.2 nozzle;Qidi Generic ASA Qidi X-Plus 3 0.2 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "S2aFIcoyiIsZ5TR8", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.2 nozzle.json index 1f7ec6918c..8a7eef5c24 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Plus 4 0.2 nozzle;Qidi Generic ASA Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "aYowi3jA3nUcr5e8", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.4 nozzle.json index 1a42a6d075..2c40f2f68c 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Plus 4 0.4 nozzle;Qidi Generic ASA Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "Qaogxqa5Zw7i7n0a", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.6 nozzle.json index 6700a02c94..9f071cebf6 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Plus 4 0.6 nozzle;Qidi Generic ASA Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "aP2WrJLkjpGFtt8I", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.8 nozzle.json index 3a1c923505..a7f079c5b9 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Plus 4 0.8 nozzle;Qidi Generic ASA Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "mx6C1Q73i0B7gpag", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Smart 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Smart 3 0.2 nozzle.json index 437ed6c7d8..45110363c3 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Smart 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi X-Smart 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi X-Smart 3 0.2 nozzle", - "inherits": "Generic ASA @Qidi", "renamed_from": "Qidi Generic ASA @Qidi X-Smart 3 0.2 nozzle;Qidi Generic ASA Qidi X-Smart 3 0.2 nozzle", + "inherits": "Generic ASA @Qidi", "from": "system", "setting_id": "6jbwOYmS2ypqTshH", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic ASA @Qidi.json b/resources/profiles/Qidi/filament/Generic ASA @Qidi.json index 6057fbea4a..0e3f924506 100644 --- a/resources/profiles/Qidi/filament/Generic ASA @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic ASA @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Qidi", - "inherits": "fdm_filament_asa", "renamed_from": "Qidi Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "IO7E03K3t2sySCAM", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Qidi/filament/Generic PA @Qidi.json b/resources/profiles/Qidi/filament/Generic PA @Qidi.json index c27771e405..6f56a24db4 100644 --- a/resources/profiles/Qidi/filament/Generic PA @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PA @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Qidi", - "inherits": "fdm_filament_pa", "renamed_from": "Qidi Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "la9e4F5ns9eWv7Lg", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Qidi/filament/Generic PA-CF @Qidi.json b/resources/profiles/Qidi/filament/Generic PA-CF @Qidi.json index bdf39e1630..fa2710c578 100644 --- a/resources/profiles/Qidi/filament/Generic PA-CF @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PA-CF @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Qidi", - "inherits": "fdm_filament_pa", "renamed_from": "Qidi Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "qLuGt33iENH6QTjv", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi 0.2 nozzle.json index 8573598189..ee2ff50daf 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi 0.2 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @0.2 nozzle;Qidi Generic PC 0.2 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "Ei2Izb38mh4A4wgw", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi 0.8 nozzle.json index 491f5917d3..ff71dffad4 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi 0.8 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @0.8 nozzle;Qidi Generic PC 0.8 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "marM5nqtpl08NP9b", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.2 nozzle.json index fb85345598..ad21c9206a 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi Q1 Pro 0.2 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi Q1 Pro 0.2 nozzle;Qidi Generic PC Qidi Q1 Pro 0.2 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "5sAcMTaVI41PCs3n", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.4 nozzle.json index b7057b6c2f..d635aa6da6 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi Q1 Pro 0.4 nozzle;Qidi Generic PC Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "QmaeYzkbcmKJCJSv", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.6 nozzle.json index 56a5a8e132..e774dac351 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi Q1 Pro 0.6 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi Q1 Pro 0.6 nozzle;Qidi Generic PC Qidi Q1 Pro 0.6 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "heIlhCMIZ9MXeDHE", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.8 nozzle.json index 13f13ea759..f9f3fa7cef 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi Q1 Pro 0.8 nozzle;Qidi Generic PC Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "JlztE3hk1LB23o4h", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.2 nozzle.json index 29c7c1658b..b1ff25edbd 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi X-Plus 4 0.2 nozzle;Qidi Generic PC Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "2eI2cXfCN6vlk6UV", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.4 nozzle.json index ba52effd22..c8427080e2 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi X-Plus 4 0.4 nozzle;Qidi Generic PC Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "kGhUT0TAXku3by9D", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.6 nozzle.json index e3f9c180ba..78afa33a2e 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi X-Plus 4 0.6 nozzle;Qidi Generic PC Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "HzAwEYvedOi3GRMY", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.8 nozzle.json index e6c8d1586d..c85b2b7230 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic PC @Qidi", "renamed_from": "Qidi Generic PC @Qidi X-Plus 4 0.8 nozzle;Qidi Generic PC Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic PC @Qidi", "from": "system", "setting_id": "iq1u1nPMi9GT31p9", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PC @Qidi.json b/resources/profiles/Qidi/filament/Generic PC @Qidi.json index c69f050f5c..574c75e189 100644 --- a/resources/profiles/Qidi/filament/Generic PC @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PC @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Qidi", - "inherits": "fdm_filament_pc", "renamed_from": "Qidi Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "m1fBauBqqvKdIAAr", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.2 nozzle.json index 02004cab28..a2ea56a059 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi Q1 Pro 0.2 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi Q1 Pro 0.2 nozzle;Qidi Generic PETG Qidi Q1 Pro 0.2 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "D2QwO7VczuscejBF", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.4 nozzle.json index 10a2b2f080..b8e5e3ed9f 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi Q1 Pro 0.4 nozzle;Qidi Generic PETG Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "GeV4szn47hD1UedT", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.6 nozzle.json index 995b79eb68..c739178dfd 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi Q1 Pro 0.6 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi Q1 Pro 0.6 nozzle;Qidi Generic PETG Qidi Q1 Pro 0.6 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "hwVzOmBJL0wnhzVj", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.8 nozzle.json index f1d1298d8d..ebc69da5df 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi Q1 Pro 0.8 nozzle;Qidi Generic PETG Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "QKyHd7rHutldls1y", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Max 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Max 3 0.2 nozzle.json index 9eb15c7a9c..c4728dd56b 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Max 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Max 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Max 3 0.2 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Max 3 0.2 nozzle;Qidi Generic PETG Qidi X-Max 3 0.2 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "afJiGzHpK1vEgb0S", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 3 0.2 nozzle.json index 7994ab710f..fcce9fc73a 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Plus 3 0.2 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Plus 3 0.2 nozzle;Qidi Generic PETG Qidi X-Plus 3 0.2 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "grlFOKGDoAo075zz", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.2 nozzle.json index f8de246245..e545d2e6f5 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Plus 4 0.2 nozzle;Qidi Generic PETG Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "hb1v0ytZ8KFm0KeO", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.4 nozzle.json index 0419f9669d..7d13f3211b 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Plus 4 0.4 nozzle;Qidi Generic PETG Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "V8YvTFXnlItPw97m", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.6 nozzle.json index f4a3448c63..40fcfa53e8 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Plus 4 0.6 nozzle;Qidi Generic PETG Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "X9FiUfQBLABTKIKO", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.8 nozzle.json index 6bc15f85a2..2381fdb58c 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Plus 4 0.8 nozzle;Qidi Generic PETG Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "5XdW6h65aMPX61o9", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Smart 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Smart 3 0.2 nozzle.json index ac5c820791..c08df1141a 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Smart 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi X-Smart 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi X-Smart 3 0.2 nozzle", - "inherits": "Generic PETG @Qidi", "renamed_from": "Qidi Generic PETG @Qidi X-Smart 3 0.2 nozzle;Qidi Generic PETG Qidi X-Smart 3 0.2 nozzle", + "inherits": "Generic PETG @Qidi", "from": "system", "setting_id": "MynfKhfKlXwFaVOJ", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG @Qidi.json b/resources/profiles/Qidi/filament/Generic PETG @Qidi.json index b4747dc9df..94b2ec8002 100644 --- a/resources/profiles/Qidi/filament/Generic PETG @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PETG @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Qidi", - "inherits": "fdm_filament_pet", "renamed_from": "Qidi Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "zRfo4sbJ3auEJtiC", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Qidi/filament/Generic PETG-CF @Qidi.json b/resources/profiles/Qidi/filament/Generic PETG-CF @Qidi.json index fbe5386405..d99e3af12b 100644 --- a/resources/profiles/Qidi/filament/Generic PETG-CF @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PETG-CF @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Qidi", - "inherits": "fdm_filament_pet", "renamed_from": "Qidi Generic PETG-CF", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "1ehKRzcekplfoFdJ", "filament_id": "OFoYSJKi", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.2 nozzle.json index 4c0c00e6ba..86c04e8e84 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi Q1 Pro 0.2 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi Q1 Pro 0.2 nozzle;Qidi Generic PLA Qidi Q1 Pro 0.2 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "2TNFziuyxg2X4zgY", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.4 nozzle.json index 5b49e8560e..b8f25d0170 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi Q1 Pro 0.4 nozzle;Qidi Generic PLA Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "PNCPMC8uMY9h5SZr", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.6 nozzle.json index 442f46e559..ef0c9e0b58 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi Q1 Pro 0.6 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi Q1 Pro 0.6 nozzle;Qidi Generic PLA Qidi Q1 Pro 0.6 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "23t94qXoDPSdi7fS", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.8 nozzle.json index d915ed03a8..04e92b79fd 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi Q1 Pro 0.8 nozzle;Qidi Generic PLA Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "aWIicFWyadhnYKfF", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.2 nozzle.json index 52ee24c470..619675bfa9 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Max 3 0.2 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Max 3 0.2 nozzle;Qidi Generic PLA Qidi X-Max 3 0.2 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "VhP4JYzAah2X1Kr3", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.6 nozzle.json index 76521556dd..7da0c07712 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Max 3 0.6 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Max 3 0.6 nozzle;Qidi Generic PLA Qidi X-Max 3 0.6 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "uhzFvazl2rWd0YN3", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.8 nozzle.json index 4246b7fc19..3a054b001a 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Max 3 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Max 3 0.8 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Max 3 0.8 nozzle;Qidi Generic PLA Qidi X-Max 3 0.8 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "t7bkbAgWCK7ObiK4", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.2 nozzle.json index 7508b21dc3..c2c3235b9d 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 3 0.2 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 3 0.2 nozzle;Qidi Generic PLA Qidi X-Plus 3 0.2 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "1iUDRQmhNsb4Tlag", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.6 nozzle.json index fcdcb48de7..ecad4ab984 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 3 0.6 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 3 0.6 nozzle;Qidi Generic PLA Qidi X-Plus 3 0.6 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "qbT3T9cRjqK7aO4M", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.8 nozzle.json index d42c838771..9fea437ebe 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 3 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 3 0.8 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 3 0.8 nozzle;Qidi Generic PLA Qidi X-Plus 3 0.8 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "dMVLTDJInWMo2fMP", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.2 nozzle.json index 8124fb26b0..8aeb08e0d0 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 4 0.2 nozzle;Qidi Generic PLA Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "4OyCs9habQtGhoot", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.4 nozzle.json index 90d822953f..60aef44069 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 4 0.4 nozzle;Qidi Generic PLA Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "SU5XqpfPO5g87dfL", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.6 nozzle.json index 2cc9b574c1..77199ca160 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 4 0.6 nozzle;Qidi Generic PLA Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "7ALKguzkoK6KLHVv", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.8 nozzle.json index 2f0ab0b4c7..3b54f66229 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Plus 4 0.8 nozzle;Qidi Generic PLA Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "jzfMNZP4WaNcNixD", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.2 nozzle.json index c9af562ff6..0947ec5a64 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Smart 3 0.2 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Smart 3 0.2 nozzle;Qidi Generic PLA Qidi X-Smart 3 0.2 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "gNbvzCkxedrQ7nQe", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.6 nozzle.json index 497283dd4c..b4c5017daf 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Smart 3 0.6 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Smart 3 0.6 nozzle;Qidi Generic PLA Qidi X-Smart 3 0.6 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "t8uPl9peXZRJbdLj", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.8 nozzle.json index 6b125ee3aa..1139e581ec 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi X-Smart 3 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi X-Smart 3 0.8 nozzle", - "inherits": "Generic PLA @Qidi", "renamed_from": "Qidi Generic PLA @Qidi X-Smart 3 0.8 nozzle;Qidi Generic PLA Qidi X-Smart 3 0.8 nozzle", + "inherits": "Generic PLA @Qidi", "from": "system", "setting_id": "VsoBEmU35N8eW3CO", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA @Qidi.json b/resources/profiles/Qidi/filament/Generic PLA @Qidi.json index e3e1f6eb48..c49b7ada5c 100644 --- a/resources/profiles/Qidi/filament/Generic PLA @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PLA @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Qidi", - "inherits": "fdm_filament_pla", "renamed_from": "Qidi Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "illxClFj0LphvnHh", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.2 nozzle.json index 75f9a19364..75bb815bb9 100644 --- a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic PLA @Qidi X-Plus 4 0.2 nozzle", "renamed_from": "Qidi Generic PLA High Speed @Qidi X-Plus 4 0.2 nozzle;Qidi Generic PLA High Speed Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic PLA @Qidi X-Plus 4 0.2 nozzle", "from": "system", "setting_id": "ktWvoEzkA0mJ0Q5T", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.4 nozzle.json index 7067954ef5..ff45958f89 100644 --- a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic PLA @Qidi X-Plus 4 0.4 nozzle", "renamed_from": "Qidi Generic PLA High Speed @Qidi X-Plus 4 0.4 nozzle;Qidi Generic PLA High Speed Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic PLA @Qidi X-Plus 4 0.4 nozzle", "from": "system", "setting_id": "lBa0yfqPsQgr4U3m", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.6 nozzle.json index d4bd50b020..aea3f32b82 100644 --- a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic PLA @Qidi X-Plus 4 0.6 nozzle", "renamed_from": "Qidi Generic PLA High Speed @Qidi X-Plus 4 0.6 nozzle;Qidi Generic PLA High Speed Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic PLA @Qidi X-Plus 4 0.6 nozzle", "from": "system", "setting_id": "Ls5CQx5Yf8QuC4T3", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.8 nozzle.json index dd77278778..e290cff0c9 100644 --- a/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA High Speed @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic PLA @Qidi X-Plus 4 0.8 nozzle", "renamed_from": "Qidi Generic PLA High Speed @Qidi X-Plus 4 0.8 nozzle;Qidi Generic PLA High Speed Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic PLA @Qidi X-Plus 4 0.8 nozzle", "from": "system", "setting_id": "VyCsuptxJnVw1KqD", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi Q1 Pro 0.4 nozzle.json index fbf48ad575..365da21bae 100644 --- a/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic PLA Silk @Qidi", "renamed_from": "Qidi Generic PLA Silk @Qidi Q1 Pro 0.4 nozzle;Qidi Generic PLA Silk Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic PLA Silk @Qidi", "from": "system", "setting_id": "VusYzaMdLpjravVc", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi X-Plus 4 0.4 nozzle.json index bbfd984880..76fa98a2b6 100644 --- a/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic PLA Silk @Qidi", "renamed_from": "Qidi Generic PLA Silk @Qidi X-Plus 4 0.4 nozzle;Qidi Generic PLA Silk Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic PLA Silk @Qidi", "from": "system", "setting_id": "9GVORPqwLq0s3mlY", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi.json b/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi.json index c9fed29f60..d2ebb83e3e 100644 --- a/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PLA Silk @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Qidi", - "inherits": "fdm_filament_pla", "renamed_from": "Qidi Generic PLA Silk", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "qmNmFB6yN23u389x", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.2 nozzle.json index e61e507c68..755924040f 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi Q1 Pro 0.2 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi Q1 Pro 0.2 nozzle;Qidi Generic PLA+ Qidi Q1 Pro 0.2 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "S5IihmYwqdoEXiOT", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.4 nozzle.json index 842010a166..4a5ceebc40 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi Q1 Pro 0.4 nozzle;Qidi Generic PLA+ Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "iZYrNv7L15yrfAPR", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.6 nozzle.json index 1b48ab6b10..09eb399d77 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi Q1 Pro 0.6 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi Q1 Pro 0.6 nozzle;Qidi Generic PLA+ Qidi Q1 Pro 0.6 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "zDYfWdaJGDL64gzD", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.8 nozzle.json index 677620b7b7..7d90ab5d6a 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi Q1 Pro 0.8 nozzle;Qidi Generic PLA+ Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "eAtbANg8BCzaurOY", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.2 nozzle.json index f3fa9ec4b4..ef4ddb5536 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Max 3 0.2 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Max 3 0.2 nozzle;Qidi Generic PLA+ Qidi X-Max 3 0.2 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "ak1iDHwta1iV5CXw", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.6 nozzle.json index 2e151c9e14..5041834b25 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Max 3 0.6 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Max 3 0.6 nozzle;Qidi Generic PLA+ Qidi X-Max 3 0.6 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "JwpYPwMfRZtymarF", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.8 nozzle.json index b829c40c1a..c236f16d65 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Max 3 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Max 3 0.8 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Max 3 0.8 nozzle;Qidi Generic PLA+ Qidi X-Max 3 0.8 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "ZOuRUZf07g43ZV9u", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.2 nozzle.json index 2a761a1946..94d972de5f 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 3 0.2 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 3 0.2 nozzle;Qidi Generic PLA+ Qidi X-Plus 3 0.2 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "DujfIhzIsPDdHZlg", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.6 nozzle.json index 657b16a6a4..9a38c47abf 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 3 0.6 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 3 0.6 nozzle;Qidi Generic PLA+ Qidi X-Plus 3 0.6 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "BA46FjbkAt4dhdfQ", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.8 nozzle.json index 9455380809..f861a4a8b3 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 3 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 3 0.8 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 3 0.8 nozzle;Qidi Generic PLA+ Qidi X-Plus 3 0.8 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "TEqTy5MhYC1CLkrr", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.2 nozzle.json index ecfb501bb0..7a20b6c326 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 4 0.2 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 4 0.2 nozzle;Qidi Generic PLA+ Qidi X-Plus 4 0.2 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "TO1cgOHqLFnimX9m", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.4 nozzle.json index c0ff54ee65..7368ff43ef 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 4 0.4 nozzle;Qidi Generic PLA+ Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "Dyf2Y7pDd4UWIIJ5", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.6 nozzle.json index 5ddca086f7..b3271efaeb 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 4 0.6 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 4 0.6 nozzle;Qidi Generic PLA+ Qidi X-Plus 4 0.6 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "ty1M4Mik83FlDWKj", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.8 nozzle.json index 937e85aff4..1b9f32fb89 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Plus 4 0.8 nozzle;Qidi Generic PLA+ Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "Wyo0NeD4dPzA365C", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.2 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.2 nozzle.json index a32c884550..2b35f41efa 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.2 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Smart 3 0.2 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Smart 3 0.2 nozzle;Qidi Generic PLA+ Qidi X-Smart 3 0.2 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "lypNmywVe3qfhs2q", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.6 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.6 nozzle.json index fe84ef4f8c..d7013cfd45 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Smart 3 0.6 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Smart 3 0.6 nozzle;Qidi Generic PLA+ Qidi X-Smart 3 0.6 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "Hxpe6y8Xo37WmcQr", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.8 nozzle.json index 59a6efb166..e37624442b 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi X-Smart 3 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi X-Smart 3 0.8 nozzle", - "inherits": "Generic PLA+ @Qidi", "renamed_from": "Qidi Generic PLA+ @Qidi X-Smart 3 0.8 nozzle;Qidi Generic PLA+ Qidi X-Smart 3 0.8 nozzle", + "inherits": "Generic PLA+ @Qidi", "from": "system", "setting_id": "2jjI8l22cAXTuxMl", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi.json b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi.json index 2c1e136f6b..c102baea70 100644 --- a/resources/profiles/Qidi/filament/Generic PLA+ @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PLA+ @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA+ @Qidi", - "inherits": "fdm_filament_pla", "renamed_from": "Qidi Generic PLA+", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "JhZ9hP9n1gBNGwBq", "filament_id": "OFEWYR89", diff --git a/resources/profiles/Qidi/filament/Generic PLA-CF @Qidi.json b/resources/profiles/Qidi/filament/Generic PLA-CF @Qidi.json index 1381442943..e3981e0cca 100644 --- a/resources/profiles/Qidi/filament/Generic PLA-CF @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PLA-CF @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Qidi", - "inherits": "fdm_filament_pla", "renamed_from": "Qidi Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "XspRlBSqR3DsiFBM", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Qidi/filament/Generic PVA @Qidi.json b/resources/profiles/Qidi/filament/Generic PVA @Qidi.json index ffd25855a1..d38624664c 100644 --- a/resources/profiles/Qidi/filament/Generic PVA @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic PVA @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Qidi", - "inherits": "fdm_filament_pva", "renamed_from": "Qidi Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "dmGcoGkH9lvmgsJL", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi Q1 Pro 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi Q1 Pro 0.8 nozzle.json index 3fab5170d7..57cf52644e 100644 --- a/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi Q1 Pro 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi Q1 Pro 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU 95A @Qidi Q1 Pro 0.8 nozzle", - "inherits": "Generic TPU 95A @Qidi", "renamed_from": "Qidi Generic TPU 95A @Qidi Q1 Pro 0.8 nozzle;Qidi Generic TPU 95A Qidi Q1 Pro 0.8 nozzle", + "inherits": "Generic TPU 95A @Qidi", "from": "system", "setting_id": "lwRnIxnWLYp1Hww4", "filament_id": "OFjiXpyf", diff --git a/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi X-Plus 4 0.8 nozzle.json b/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi X-Plus 4 0.8 nozzle.json index 7e964fd0b8..5e7c3dffa0 100644 --- a/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi X-Plus 4 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi X-Plus 4 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU 95A @Qidi X-Plus 4 0.8 nozzle", - "inherits": "Generic TPU 95A @Qidi", "renamed_from": "Qidi Generic TPU 95A @Qidi X-Plus 4 0.8 nozzle;Qidi Generic TPU 95A Qidi X-Plus 4 0.8 nozzle", + "inherits": "Generic TPU 95A @Qidi", "from": "system", "setting_id": "BPUUHxYPhHcPIWs9", "filament_id": "OFjiXpyf", diff --git a/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi.json b/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi.json index 2c9602ee2e..330c6fbeee 100644 --- a/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic TPU 95A @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU 95A @Qidi", - "inherits": "fdm_filament_tpu", "renamed_from": "Qidi Generic TPU 95A", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "nXjylLuhXqtlLGEv", "filament_id": "OFjiXpyf", diff --git a/resources/profiles/Qidi/filament/Generic TPU @Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic TPU @Qidi Q1 Pro 0.4 nozzle.json index 93793f8d8e..6df699563f 100644 --- a/resources/profiles/Qidi/filament/Generic TPU @Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic TPU @Qidi Q1 Pro 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Qidi Q1 Pro 0.4 nozzle", - "inherits": "Generic TPU @Qidi", "renamed_from": "Qidi Generic TPU @Qidi Q1 Pro 0.4 nozzle;Qidi Generic TPU Qidi Q1 Pro 0.4 nozzle", + "inherits": "Generic TPU @Qidi", "from": "system", "setting_id": "ToMKfKFZDCHyEHw9", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Qidi/filament/Generic TPU @Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/filament/Generic TPU @Qidi X-Plus 4 0.4 nozzle.json index f1c8117c47..5e75f2e8c9 100644 --- a/resources/profiles/Qidi/filament/Generic TPU @Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/Generic TPU @Qidi X-Plus 4 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Qidi X-Plus 4 0.4 nozzle", - "inherits": "Generic TPU @Qidi", "renamed_from": "Qidi Generic TPU @Qidi X-Plus 4 0.4 nozzle;Qidi Generic TPU Qidi X-Plus 4 0.4 nozzle", + "inherits": "Generic TPU @Qidi", "from": "system", "setting_id": "AACIHxmLhuNAGo6d", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Qidi/filament/Generic TPU @Qidi.json b/resources/profiles/Qidi/filament/Generic TPU @Qidi.json index a525b49520..d34a036466 100644 --- a/resources/profiles/Qidi/filament/Generic TPU @Qidi.json +++ b/resources/profiles/Qidi/filament/Generic TPU @Qidi.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Qidi", - "inherits": "fdm_filament_tpu", "renamed_from": "Qidi Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "0jwJs0mTFs0904VK", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.2 nozzle.json index 32352a70c8..7debd40941 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "v4Of6ePWz1oGVLqU", "name": "Bambu ABS @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "v4Of6ePWz1oGVLqU", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.4 nozzle.json index 8b6bc2ebb6..80a312cc50 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "K3KqxJ3z6lSKoCsQ", "name": "Bambu ABS @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "K3KqxJ3z6lSKoCsQ", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.6 nozzle.json index 3fa0dfca1f..4cce902594 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "D3OOS6ShJDdn4dlU", "name": "Bambu ABS @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "D3OOS6ShJDdn4dlU", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.8 nozzle.json index 833774ecff..a71a5904d9 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu ABS @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "8zWM4mqGjwjy2yJb", "name": "Bambu ABS @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "8zWM4mqGjwjy2yJb", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu ABS @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Bambu ABS @X-Plus 5.json index 0e0fdb08b0..ee457bf4e8 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu ABS @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Bambu ABS @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFhuaUQB", "name": "Bambu ABS@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFhuaUQB", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.2 nozzle.json index 67725a5ee4..185809e35c 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ed9ZVS66ll61akjK", "name": "Bambu PETG @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "ed9ZVS66ll61akjK", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.4 nozzle.json index 953359bb36..008572349b 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "mPLqTb7smgIDOZTg", "name": "Bambu PETG @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "mPLqTb7smgIDOZTg", + "instantiation": "true", "pressure_advance": [ "0.056" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.6 nozzle.json index 77014127cd..e34ce6538c 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "A3K4JfwyqUnciD2e", "name": "Bambu PETG @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "A3K4JfwyqUnciD2e", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.8 nozzle.json index 3e95da1618..a8dfcfb925 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PETG @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "4qjG4MYXmLPJ5Qjm", "name": "Bambu PETG @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "4qjG4MYXmLPJ5Qjm", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PETG @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Bambu PETG @X-Plus 5.json index ef6ea57354..714f89223c 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PETG @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PETG @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFLYDngx", "name": "Bambu PETG@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFLYDngx", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.2 nozzle.json index 8cebbd7581..d3bdaf4de5 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "cI5eJwzwoecS97SU", "name": "Bambu PLA @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "cI5eJwzwoecS97SU", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.4 nozzle.json index 3e7d24cf85..f8d805f9cf 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "UP5ST3BYA3nWaT5i", "name": "Bambu PLA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "UP5ST3BYA3nWaT5i", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.6 nozzle.json index e3e192d1e8..984e925e9d 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "jSFJn0WmV76aBwPt", "name": "Bambu PLA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "jSFJn0WmV76aBwPt", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.8 nozzle.json index 2390355042..f9f59c8f53 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PLA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "MYCn1SS32p63RzX0", "name": "Bambu PLA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Bambu PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "MYCn1SS32p63RzX0", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/Bambu PLA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Bambu PLA @X-Plus 5.json index ad90cb8a81..244c43220a 100644 --- a/resources/profiles/Qidi/filament/X5/Bambu PLA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Bambu PLA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF1dpPrW", "name": "Bambu PLA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF1dpPrW", + "instantiation": "false", "filament_adhesiveness_category": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.2 nozzle.json index c12bcc6687..fe7c8c77cb 100644 --- a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "xxRxeoAbiYJcH1P4", "name": "Generic ABS @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "xxRxeoAbiYJcH1P4", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.4 nozzle.json index 7807bc8420..96f99c0806 100644 --- a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "MM6yfNPfpCtbsm2M", "name": "Generic ABS @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "MM6yfNPfpCtbsm2M", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.6 nozzle.json index 6de2b02613..974d4f2294 100644 --- a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "BIiPt2AExUkASm2F", "name": "Generic ABS @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "BIiPt2AExUkASm2F", + "instantiation": "true", "filament_max_volumetric_speed": [ "24.5" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.8 nozzle.json index 6e7bda8441..4db5f22815 100644 --- a/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic ABS @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "VzKqGnik79qlJ1bA", "name": "Generic ABS @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "VzKqGnik79qlJ1bA", + "instantiation": "true", "filament_max_volumetric_speed": [ "24.5" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic ABS @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic ABS @X-Plus 5.json index 79a52578a4..df28065bdb 100644 --- a/resources/profiles/Qidi/filament/X5/Generic ABS @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic ABS @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFY9muEs", "name": "Generic ABS@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFY9muEs", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.2 nozzle.json index da5c50af1a..ad3e9d3128 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ERbh7DQQfK7A623W", "name": "Generic PC @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PC@X-Plus 5-Series", + "from": "system", + "setting_id": "ERbh7DQQfK7A623W", + "instantiation": "true", "filament_flow_ratio": [ "0.94" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.4 nozzle.json index 487d8dd31d..ede9e25962 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "MK8OyxUEziAeEbXk", "name": "Generic PC @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PC@X-Plus 5-Series", + "from": "system", + "setting_id": "MK8OyxUEziAeEbXk", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.6 nozzle.json index 90829d6463..a7aa10707f 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "EQIfBmyVNumOKVWU", "name": "Generic PC @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PC@X-Plus 5-Series", + "from": "system", + "setting_id": "EQIfBmyVNumOKVWU", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.8 nozzle.json index 514715f8a2..adb328a7f5 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PC @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "FsTuQT5hxmfjHyVZ", "name": "Generic PC @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PC@X-Plus 5-Series", + "from": "system", + "setting_id": "FsTuQT5hxmfjHyVZ", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PC @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic PC @X-Plus 5.json index 79745adfce..22a8e9ae48 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PC @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic PC @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFLakOUI", "name": "Generic PC@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFLakOUI", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.2 nozzle.json index 2b4e220a54..ddb382e1b4 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KaxkabCgu6EWZBzj", "name": "Generic PETG @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "KaxkabCgu6EWZBzj", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.4 nozzle.json index 4da60c3c48..d92c9c31e3 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ckqzES7LsTgYKKhb", "name": "Generic PETG @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "ckqzES7LsTgYKKhb", + "instantiation": "true", "pressure_advance": [ "0.056" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.6 nozzle.json index 6f1b9667ab..27071937e8 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "1ID4LaQVZN4WjJ4v", "name": "Generic PETG @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "1ID4LaQVZN4WjJ4v", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.8 nozzle.json index 764e313efe..2948194a2a 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PETG @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "yzkFoRA3R01K3lCa", "name": "Generic PETG @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "yzkFoRA3R01K3lCa", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PETG @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic PETG @X-Plus 5.json index 0e65fe68f7..ccbd996499 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PETG @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic PETG @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFYPdQJh", "name": "Generic PETG@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFYPdQJh", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.2 nozzle.json index 218b407d21..704366e9a4 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "m5zUk3OpAayCbBwF", "name": "Generic PLA @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "m5zUk3OpAayCbBwF", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.4 nozzle.json index c8dd22aba5..a7d0a7552d 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "5Eorr9nKVhLbnYAZ", "name": "Generic PLA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "5Eorr9nKVhLbnYAZ", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.6 nozzle.json index ee352a5667..bb9627c447 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "nqOawjrkU2lp3P0K", "name": "Generic PLA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "nqOawjrkU2lp3P0K", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.8 nozzle.json index 14a7fa59c1..0c25dc2848 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "nA20S71nTMCso0Bn", "name": "Generic PLA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "nA20S71nTMCso0Bn", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic PLA @X-Plus 5.json index 3b7690cc38..2d41995886 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFDSrzZ8", "name": "Generic PLA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFDSrzZ8", + "instantiation": "false", "additional_cooling_fan_speed": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.4 nozzle.json index f701cf5b50..3d298c969a 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "42feLKkUTBQTPNDm", "name": "Generic PLA Silk @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA Silk@X-Plus 5-Series", + "from": "system", + "setting_id": "42feLKkUTBQTPNDm", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.6 nozzle.json index b898df762a..755122bcfd 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA Silk @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "uyCmwBkoRNNRbG5R", "name": "Generic PLA Silk @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA Silk@X-Plus 5-Series", + "from": "system", + "setting_id": "uyCmwBkoRNNRbG5R", + "instantiation": "true", "pressure_advance": [ "0.014" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA Silk @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic PLA Silk @X-Plus 5.json index afa64cc602..d4470e4420 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA Silk @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA Silk @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFesA6rF", "name": "Generic PLA Silk@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFesA6rF", + "instantiation": "false", "additional_cooling_fan_speed": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.2 nozzle.json index a7a736a95a..33abeac017 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "aD9SNuHAOxVFczNM", "name": "Generic PLA+ @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA+@X-Plus 5-Series", + "from": "system", + "setting_id": "aD9SNuHAOxVFczNM", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.4 nozzle.json index e10196f45c..2bbaf88d12 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "QDAKF2VaO4MkiYZ7", "name": "Generic PLA+ @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA+@X-Plus 5-Series", + "from": "system", + "setting_id": "QDAKF2VaO4MkiYZ7", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.6 nozzle.json index 62c8ce9de1..faac0f9236 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "kNONALYQIZ8hkU2f", "name": "Generic PLA+ @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA+@X-Plus 5-Series", + "from": "system", + "setting_id": "kNONALYQIZ8hkU2f", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.8 nozzle.json index 78599cb326..cbe051a130 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA+ @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ehm8mY40hPq6Bjby", "name": "Generic PLA+ @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA+@X-Plus 5-Series", + "from": "system", + "setting_id": "ehm8mY40hPq6Bjby", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic PLA+ @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic PLA+ @X-Plus 5.json index 72d7b6f9c6..13769cac67 100644 --- a/resources/profiles/Qidi/filament/X5/Generic PLA+ @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic PLA+ @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFEWYR89", "name": "Generic PLA+@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFEWYR89", + "instantiation": "false", "additional_cooling_fan_speed": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.4 nozzle.json index 525652742c..db09af9899 100644 --- a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "blCxzXDeplxz7FrS", "name": "Generic TPU 95A @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic TPU 95A@X-Plus 5-Series", + "from": "system", + "setting_id": "blCxzXDeplxz7FrS", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.6 nozzle.json index f17a6e91e5..023195f39f 100644 --- a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "mXwJpelMKlY7SQR8", "name": "Generic TPU 95A @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic TPU 95A@X-Plus 5-Series", + "from": "system", + "setting_id": "mXwJpelMKlY7SQR8", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.8 nozzle.json index 072983e488..482a66f549 100644 --- a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "o9NLhClfpsJFEE3P", "name": "Generic TPU 95A @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Generic TPU 95A@X-Plus 5-Series", + "from": "system", + "setting_id": "o9NLhClfpsJFEE3P", + "instantiation": "true", "nozzle_temperature": [ "220" ], diff --git a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @X-Plus 5.json index b98a3a0a2f..7a9f80d609 100644 --- a/resources/profiles/Qidi/filament/X5/Generic TPU 95A @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Generic TPU 95A @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFjiXpyf", "name": "Generic TPU 95A@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFjiXpyf", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "30" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.2 nozzle.json index 2346539b73..ad98af14f4 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "uarx8NrJerlKsoA8", "name": "HATCHBOX ABS @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "uarx8NrJerlKsoA8", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.4 nozzle.json index 4566ece152..902fe4e144 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "T52l6W0u1uoiXrAx", "name": "HATCHBOX ABS @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "T52l6W0u1uoiXrAx", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.6 nozzle.json index bb16d32b06..ec263bee9b 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "krTIEBmeK9q2R60M", "name": "HATCHBOX ABS @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "krTIEBmeK9q2R60M", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.8 nozzle.json index 19b4ce995f..aefeac6176 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "B99z7PiwClkWtyqv", "name": "HATCHBOX ABS @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "B99z7PiwClkWtyqv", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @X-Plus 5.json index 323fcf3e90..7142ad1de3 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX ABS @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFwLBAGf", "name": "HATCHBOX ABS@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFwLBAGf", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.2 nozzle.json index dc87553374..47ba45ca0c 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "2y03Jbrd8epf06MW", "name": "HATCHBOX PETG @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "2y03Jbrd8epf06MW", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.4 nozzle.json index 21441a8d3e..863b7cc3f2 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KHbEUzPhVICXYhTs", "name": "HATCHBOX PETG @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "KHbEUzPhVICXYhTs", + "instantiation": "true", "pressure_advance": [ "0.056" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.6 nozzle.json index 85219cea79..90413c57b2 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "3HPxSQqEM8XGZqgU", "name": "HATCHBOX PETG @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "3HPxSQqEM8XGZqgU", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.8 nozzle.json index c6b4b699cd..c71cb3a6ec 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "eZnTfUmPGkeoEP87", "name": "HATCHBOX PETG @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PETG@X-Plus 5-Series", + "from": "system", + "setting_id": "eZnTfUmPGkeoEP87", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @X-Plus 5.json index 6f0495c45b..ab0b15a5f7 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PETG @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFIWMSGX", "name": "HATCHBOX PETG@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFIWMSGX", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.2 nozzle.json index a1838c2041..12ebb48fcf 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Sn0LAKII01kQONZS", "name": "HATCHBOX PLA @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "Sn0LAKII01kQONZS", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.4 nozzle.json index 82e54e389e..dc60b97e1d 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "HWmejqWfehK4LG6C", "name": "HATCHBOX PLA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "HWmejqWfehK4LG6C", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.6 nozzle.json index d6ac4c9a7e..0c08bf069f 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "zjIVoA34wN8AT6cp", "name": "HATCHBOX PLA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "zjIVoA34wN8AT6cp", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.8 nozzle.json index 5b89e541e3..e1e42418d9 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "sTjweBRTvE0P6YtE", "name": "HATCHBOX PLA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "HATCHBOX PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "sTjweBRTvE0P6YtE", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @X-Plus 5.json index 7ee05c27f7..056f920c67 100644 --- a/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/HATCHBOX PLA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFeelsSM", "name": "HATCHBOX PLA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFeelsSM", + "instantiation": "false", "filament_adhesiveness_category": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.2 nozzle.json index 7194b54b7f..e65fd300ae 100644 --- a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "tLj2E2dWAdLKpC4K", "name": "Overture ABS @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "tLj2E2dWAdLKpC4K", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.4 nozzle.json index 5e50aa5dbc..556a0d1708 100644 --- a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "1IkBG0ywAkk3VhOd", "name": "Overture ABS @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "1IkBG0ywAkk3VhOd", + "instantiation": "true", "pressure_advance": [ "0.033" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.6 nozzle.json index 9bacef9d3a..36b67e90b2 100644 --- a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "4SXA27uTG5kcbnAq", "name": "Overture ABS @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "4SXA27uTG5kcbnAq", + "instantiation": "true", "pressure_advance": [ "0.02" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.8 nozzle.json index a53148ed26..fcdf219ca0 100644 --- a/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture ABS @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "AzC8XjbkzsxEPDMG", "name": "Overture ABS @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "AzC8XjbkzsxEPDMG", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture ABS @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Overture ABS @X-Plus 5.json index 82863e8d80..19084c236d 100644 --- a/resources/profiles/Qidi/filament/X5/Overture ABS @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Overture ABS @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFK8XHPn", "name": "Overture ABS@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFK8XHPn", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.2 nozzle.json index f209b21a6e..9cea361938 100644 --- a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "2TAd2Dlk6KPvvmMg", "name": "Overture PLA @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "2TAd2Dlk6KPvvmMg", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.4 nozzle.json index a625953f60..a48b32d09a 100644 --- a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "1rKASIobH0DqQUeH", "name": "Overture PLA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "1rKASIobH0DqQUeH", + "instantiation": "true", "pressure_advance": [ "0.037" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.6 nozzle.json index 5a3dfdee8f..7f9e0702d4 100644 --- a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "UWQ7bLf74AxEPDdc", "name": "Overture PLA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "UWQ7bLf74AxEPDdc", + "instantiation": "true", "pressure_advance": [ "0.019" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.8 nozzle.json index 86d8605933..6da685b581 100644 --- a/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Overture PLA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "bIg1NW0EwTlmRNAF", "name": "Overture PLA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Overture PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "bIg1NW0EwTlmRNAF", + "instantiation": "true", "pressure_advance": [ "0.012" ], diff --git a/resources/profiles/Qidi/filament/X5/Overture PLA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Overture PLA @X-Plus 5.json index 0dbb498feb..3ef4391d22 100644 --- a/resources/profiles/Qidi/filament/X5/Overture PLA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Overture PLA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFc3xdm9", "name": "Overture PLA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFc3xdm9", + "instantiation": "false", "filament_adhesiveness_category": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.2 nozzle.json index 0618d3c36f..232efa107a 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "AJYooe7fIzg43McT", "name": "PolyLite ABS @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "AJYooe7fIzg43McT", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.4 nozzle.json index 36e012b0d6..927c0262a1 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "S0uCyMruXw5waEYf", "name": "PolyLite ABS @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "S0uCyMruXw5waEYf", + "instantiation": "true", "pressure_advance": [ "0.033" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.6 nozzle.json index 1bf7cdf030..986b891898 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "oYlfF3MMF5DEeJpK", "name": "PolyLite ABS @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "oYlfF3MMF5DEeJpK", + "instantiation": "true", "pressure_advance": [ "0.02" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.8 nozzle.json index 9d1f541dfc..8167d40eda 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite ABS @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "hHXz74Ps9x4T7kZl", "name": "PolyLite ABS @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite ABS@X-Plus 5-Series", + "from": "system", + "setting_id": "hHXz74Ps9x4T7kZl", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite ABS @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/PolyLite ABS @X-Plus 5.json index 1cf57f8ce3..f58163af9f 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite ABS @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite ABS @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFOvv91M", "name": "PolyLite ABS@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFOvv91M", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.2 nozzle.json index f823b38e67..60378002c0 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "kKfybaeH6Llb3Vdc", "name": "PolyLite PLA @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "kKfybaeH6Llb3Vdc", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.4 nozzle.json index b7f3ef07f6..41678a9375 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "hzEsCxIKwuV2ubrz", "name": "PolyLite PLA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "hzEsCxIKwuV2ubrz", + "instantiation": "true", "pressure_advance": [ "0.037" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.6 nozzle.json index 8b98d3842a..1ad4796c5b 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "PODs7XKIgMiJZI5x", "name": "PolyLite PLA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "PODs7XKIgMiJZI5x", + "instantiation": "true", "pressure_advance": [ "0.019" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.8 nozzle.json index f4b6b8c2ee..7dec540c25 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite PLA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "LQ1rP7NSTjw2moHk", "name": "PolyLite PLA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "PolyLite PLA@X-Plus 5-Series", + "from": "system", + "setting_id": "LQ1rP7NSTjw2moHk", + "instantiation": "true", "pressure_advance": [ "0.012" ], diff --git a/resources/profiles/Qidi/filament/X5/PolyLite PLA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/PolyLite PLA @X-Plus 5.json index 4702c9ba1c..b33091774b 100644 --- a/resources/profiles/Qidi/filament/X5/PolyLite PLA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/PolyLite PLA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF5CgdDq", "name": "PolyLite PLA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF5CgdDq", + "instantiation": "false", "filament_adhesiveness_category": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.2 nozzle.json index 78389ceeb5..9d31e4b943 100644 --- a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "p9cDXBgbjwjOX5me", "name": "Polymaker PLA-HT @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Polymaker PLA-HT@X-Plus 5-Series", + "from": "system", + "setting_id": "p9cDXBgbjwjOX5me", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.4 nozzle.json index 9f77b41119..9088048ab5 100644 --- a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "TpI2jqmcVygyTO8N", "name": "Polymaker PLA-HT @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Polymaker PLA-HT@X-Plus 5-Series", + "from": "system", + "setting_id": "TpI2jqmcVygyTO8N", + "instantiation": "true", "pressure_advance": [ "0.037" ], diff --git a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.6 nozzle.json index 3c46385369..ba1b143068 100644 --- a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "69AgpjCCTxF5ffW1", "name": "Polymaker PLA-HT @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Polymaker PLA-HT@X-Plus 5-Series", + "from": "system", + "setting_id": "69AgpjCCTxF5ffW1", + "instantiation": "true", "pressure_advance": [ "0.019" ], diff --git a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.8 nozzle.json index 788db83504..314c12302a 100644 --- a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "tcoQNICpWYGdE24e", "name": "Polymaker PLA-HT @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Polymaker PLA-HT@X-Plus 5-Series", + "from": "system", + "setting_id": "tcoQNICpWYGdE24e", + "instantiation": "true", "pressure_advance": [ "0.012" ], diff --git a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @X-Plus 5.json index 233542bab1..4cb74f25b5 100644 --- a/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/Polymaker PLA-HT @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFfYHK5z", "name": "Polymaker PLA-HT@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFfYHK5z", + "instantiation": "false", "filament_adhesiveness_category": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.2 nozzle.json index 254422bb19..7e2954ea55 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "8SvrXXv743rCyyeN", "name": "QIDI ABS Odorless @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Odorless@X-Plus 5-Series", + "from": "system", + "setting_id": "8SvrXXv743rCyyeN", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.4 nozzle.json index 1bd37ac08a..c1af1b6f1c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "YviPsfkGYv6Q3r3T", "name": "QIDI ABS Odorless @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Odorless@X-Plus 5-Series", + "from": "system", + "setting_id": "YviPsfkGYv6Q3r3T", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.6 nozzle.json index cbb361fb9c..0ec0bd3a8b 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "YLOcbaCppSmQ1twv", "name": "QIDI ABS Odorless @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Odorless@X-Plus 5-Series", + "from": "system", + "setting_id": "YLOcbaCppSmQ1twv", + "instantiation": "true", "filament_max_volumetric_speed": [ "24.5" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.8 nozzle.json index 912dc04ed7..a0a88a324e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Klsu6iALsWgbg3vK", "name": "QIDI ABS Odorless @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Odorless@X-Plus 5-Series", + "from": "system", + "setting_id": "Klsu6iALsWgbg3vK", + "instantiation": "true", "filament_max_volumetric_speed": [ "24.5" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @X-Plus 5.json index 7a80b433df..c5b84a18fb 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Odorless @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFma5TXH", "name": "QIDI ABS Odorless@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFma5TXH", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.2 nozzle.json index 99a9e16c08..892be9f985 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "bTwNiMSHwex0gxrd", "name": "QIDI ABS Rapido @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "bTwNiMSHwex0gxrd", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.4 nozzle.json index 30086f5dce..c22b5114cc 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "mcPlHcr33zPv3aIf", "name": "QIDI ABS Rapido @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "mcPlHcr33zPv3aIf", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.6 nozzle.json index 47278a61b1..4ace571ef5 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "0np334pRpl3qa8Uq", "name": "QIDI ABS Rapido @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "0np334pRpl3qa8Uq", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.8 nozzle.json index f79fcfdfac..4307b82a73 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Vp2bJxFhsPvW6K0P", "name": "QIDI ABS Rapido @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "Vp2bJxFhsPvW6K0P", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @X-Plus 5.json index 0afffa18f4..5b5626a5f7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFT2jon4", "name": "QIDI ABS Rapido@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFT2jon4", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json index 34632b393f..cba33e6e48 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "U69dFGlkEk9twDF6", "name": "QIDI ABS Rapido Metal @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "U69dFGlkEk9twDF6", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json index 59492201a5..4ccea8f40b 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "XaJbATawtVrUsXpz", "name": "QIDI ABS Rapido Metal @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "XaJbATawtVrUsXpz", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json index 93b4cb3aba..cb23a6e9aa 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Xb0A7YqmqP2peSM3", "name": "QIDI ABS Rapido Metal @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "Xb0A7YqmqP2peSM3", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json index c4edce73be..bf577771af 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "4AA9wGDNebbTHf4X", "name": "QIDI ABS Rapido Metal @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "4AA9wGDNebbTHf4X", + "instantiation": "true", "nozzle_temperature": [ "250" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @X-Plus 5.json index 9614cab30f..5e0f760698 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS Rapido Metal @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFeCJqxx", "name": "QIDI ABS Rapido Metal@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFeCJqxx", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.4 nozzle.json index d81d623d33..27c682c04b 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "V9h7YWcaTejmFCh0", "name": "QIDI ABS-GF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "V9h7YWcaTejmFCh0", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.6 nozzle.json index 88ee5f2146..1a0fd60db1 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "hO8H1GUCzMkwFtQH", "name": "QIDI ABS-GF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "hO8H1GUCzMkwFtQH", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.8 nozzle.json index 997e67a0f0..6691f987d0 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "LskHdeEngKlRCSmg", "name": "QIDI ABS-GF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ABS-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "LskHdeEngKlRCSmg", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @X-Plus 5.json index 5336842811..59c26ea74c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ABS-GF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFt3HtlG", "name": "QIDI ABS-GF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFt3HtlG", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.2 nozzle.json index d417265f5a..9b5ee8720f 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "FgeIGgT8xZCm4UO8", "name": "QIDI ASA @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA@X-Plus 5-Series", + "from": "system", + "setting_id": "FgeIGgT8xZCm4UO8", + "instantiation": "true", "chamber_temperatures": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.4 nozzle.json index ed86d714a1..e42e13f776 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "VRicNQizOCKkgLBJ", "name": "QIDI ASA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA@X-Plus 5-Series", + "from": "system", + "setting_id": "VRicNQizOCKkgLBJ", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.6 nozzle.json index a7870accce..a071f0b7f0 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KDjln7WdhhbSztX3", "name": "QIDI ASA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA@X-Plus 5-Series", + "from": "system", + "setting_id": "KDjln7WdhhbSztX3", + "instantiation": "true", "filament_max_volumetric_speed": [ "13" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.8 nozzle.json index 30496917d1..73ce4a3d38 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "X9TOBuOKBbJIoF7y", "name": "QIDI ASA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA@X-Plus 5-Series", + "from": "system", + "setting_id": "X9TOBuOKBbJIoF7y", + "instantiation": "true", "filament_max_volumetric_speed": [ "13" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ASA @X-Plus 5.json index b8fe444dd2..624e97dbd0 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFTsHNQi", "name": "QIDI ASA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFTsHNQi", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @Qidi X-Plus 5 0.4 nozzle.json index 08a4ed22a9..a5979282e9 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "g5F7NP83yx0Iub4c", "name": "QIDI ASA-Aero @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA-Aero@X-Plus 5-Series", + "from": "system", + "setting_id": "g5F7NP83yx0Iub4c", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @X-Plus 5.json index 73fb83834d..2e186ef10c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA-Aero @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFu1E4ur", "name": "QIDI ASA-Aero@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFu1E4ur", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.4 nozzle.json index be97fdfd58..295be4eefa 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Aqh00EJ8ZaiPCU6F", "name": "QIDI ASA-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "Aqh00EJ8ZaiPCU6F", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.6 nozzle.json index cd8bbc98bd..98f3269be5 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "fgwkL5igRvM0leJf", "name": "QIDI ASA-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "fgwkL5igRvM0leJf", + "instantiation": "true", "filament_max_volumetric_speed": [ "13" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.8 nozzle.json index 3095a16138..b4bdf7413b 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "bDAcTzwdiXT4fFnT", "name": "QIDI ASA-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI ASA-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "bDAcTzwdiXT4fFnT", + "instantiation": "true", "filament_max_volumetric_speed": [ "13" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @X-Plus 5.json index 12606c993b..442c6322c8 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI ASA-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF1W7c76", "name": "QIDI ASA-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF1W7c76", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.4 nozzle.json index 165c5cfb62..6bf8f36b07 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "vDXAb7Kkj7nFc8go", "name": "QIDI PA12-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PA12-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "vDXAb7Kkj7nFc8go", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.6 nozzle.json index ad26af1f86..29b7b7a0cd 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KjZ3jgo2Zoklkk0F", "name": "QIDI PA12-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PA12-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "KjZ3jgo2Zoklkk0F", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.8 nozzle.json index 5324f0c183..e0cf068166 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Xcl3UPe7tmXw9hXa", "name": "QIDI PA12-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PA12-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "Xcl3UPe7tmXw9hXa", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @X-Plus 5.json index d4af23e160..fd8437e120 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA12-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFn6WpN7", "name": "QIDI PA12-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFn6WpN7", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.4 nozzle.json index fbe5870078..bb8370b591 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "qTjsP8oR1sbh56Gh", "name": "QIDI PA6-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PA6-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "qTjsP8oR1sbh56Gh", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.6 nozzle.json index 016f9bb2e4..255402fa16 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "4kzkdzJmDYGic0aa", "name": "QIDI PA6-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PA6-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "4kzkdzJmDYGic0aa", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.8 nozzle.json index ba0d981c29..20b6fdf5c5 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "97peVPSildpjdDQj", "name": "QIDI PA6-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PA6-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "97peVPSildpjdDQj", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @X-Plus 5.json index 1c70ef53a0..8ad2e48c7e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PA6-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFZ3K2cL", "name": "QIDI PA6-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFZ3K2cL", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.4 nozzle.json index 68d604414d..11be5e1010 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "3iw5hq0KFa9NU4b3", "name": "QIDI PAHT-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PAHT-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "3iw5hq0KFa9NU4b3", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.6 nozzle.json index 0ca7290e39..22388a4791 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "7eBDjJbetxOC3aNT", "name": "QIDI PAHT-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PAHT-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "7eBDjJbetxOC3aNT", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.8 nozzle.json index b3b88d5f28..99a545da7e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "hkIpB0QZOGZpoYFX", "name": "QIDI PAHT-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PAHT-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "hkIpB0QZOGZpoYFX", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @X-Plus 5.json index fec939caa8..db77ecc2ca 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFKgmsqE", "name": "QIDI PAHT-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFKgmsqE", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.4 nozzle.json index 9638d33afc..dc6a820d2c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "R7cctkITobdKgMkY", "name": "QIDI PAHT-GF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PAHT-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "R7cctkITobdKgMkY", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.6 nozzle.json index 4d926ff370..3d1c6d6d9c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "cVzpHjaSzsDm0bwG", "name": "QIDI PAHT-GF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PAHT-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "cVzpHjaSzsDm0bwG", + "instantiation": "true", "pressure_advance": [ "0.015" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.8 nozzle.json index ce49e3ef04..e706c99f0e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "N0aUkpcJD6CvODci", "name": "QIDI PAHT-GF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PAHT-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "N0aUkpcJD6CvODci", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @X-Plus 5.json index de72deb697..b0ad404197 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PAHT-GF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFo15hcT", "name": "QIDI PAHT-GF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFo15hcT", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.4 nozzle.json index e4842206ed..331183714a 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "uYwbMiemSo7LxiqR", "name": "QIDI PC/ABS-FR @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PC/ABS-FR@X-Plus 5-Series", + "from": "system", + "setting_id": "uYwbMiemSo7LxiqR", + "instantiation": "true", "pressure_advance": [ "0.042" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.6 nozzle.json index 35c317e8d3..a649c493b5 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Fxkv0PN8RU17fkB0", "name": "QIDI PC/ABS-FR @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PC/ABS-FR@X-Plus 5-Series", + "from": "system", + "setting_id": "Fxkv0PN8RU17fkB0", + "instantiation": "true", "pressure_advance": [ "0.031" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.8 nozzle.json index 456a93a6d0..4043236cf7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "oKNGzYqymTnWQsBB", "name": "QIDI PC/ABS-FR @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PC/ABS-FR@X-Plus 5-Series", + "from": "system", + "setting_id": "oKNGzYqymTnWQsBB", + "instantiation": "true", "pressure_advance": [ "0.024" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @X-Plus 5.json index c7e407cd2e..29e56dae89 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PC-ABS-FR @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFDIrhbu", "name": "QIDI PC/ABS-FR@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFDIrhbu", + "instantiation": "false", "box_temperature_range_high": [ "50" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.4 nozzle.json index 5fa07706a9..275b1188b4 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "hgdi1oL4EFzh0h7h", "name": "QIDI PEBA 95A @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PEBA 95A@X-Plus 5-Series", + "from": "system", + "setting_id": "hgdi1oL4EFzh0h7h", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.6 nozzle.json index f44261951e..360cea614c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "iNZpBz1iklW3sJlj", "name": "QIDI PEBA 95A @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PEBA 95A@X-Plus 5-Series", + "from": "system", + "setting_id": "iNZpBz1iklW3sJlj", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @X-Plus 5.json index bf56f12203..9de796f2be 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PEBA 95A @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFhiJE7Y", "name": "QIDI PEBA 95A@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFhiJE7Y", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "30" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.4 nozzle.json index bfdd1aed31..f4a91aa343 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "bILtWMlzBPi4Ft8a", "name": "QIDI PET-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PET-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "bILtWMlzBPi4Ft8a", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.6 nozzle.json index cb78cf3afc..5716a20bb7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "E0Y6g3qpoERrgSUH", "name": "QIDI PET-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PET-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "E0Y6g3qpoERrgSUH", + "instantiation": "true", "pressure_advance": [ "0.025" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.8 nozzle.json index ae40d594ff..c35eddb490 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "e2HuHVJZck2nKANa", "name": "QIDI PET-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PET-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "e2HuHVJZck2nKANa", + "instantiation": "true", "pressure_advance": [ "0.025" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @X-Plus 5.json index 9163c3344e..913df35758 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFKfJTwL", "name": "QIDI PET-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFKfJTwL", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.4 nozzle.json index 97029aeb25..7ea2ee2d4f 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "2NHbKFmgDoN1oHlo", "name": "QIDI PET-GF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PET-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "2NHbKFmgDoN1oHlo", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.6 nozzle.json index 480d13bb65..f189d6847e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "cMlzOMKIIIro4H62", "name": "QIDI PET-GF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PET-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "cMlzOMKIIIro4H62", + "instantiation": "true", "pressure_advance": [ "0.014" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.8 nozzle.json index 2cc0cfe2cb..f83d62dfce 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "evxG7nCDQx2Y5UV5", "name": "QIDI PET-GF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PET-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "evxG7nCDQx2Y5UV5", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @X-Plus 5.json index 83e68f579f..767ab88e1d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PET-GF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PET-GF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFhx4uOG", "name": "QIDI PET-GF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFhx4uOG", + "instantiation": "false", "box_temperature_range_high": [ "50" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.2 nozzle.json index 6689cca71a..ee872fe154 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "k4jOZFY5QV2bMKHK", "name": "QIDI PETG Basic @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "k4jOZFY5QV2bMKHK", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.4 nozzle.json index c1b29f1b75..6fe6c7bb9e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "b55sLpGKCrWLiDPf", "name": "QIDI PETG Basic @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "b55sLpGKCrWLiDPf", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.6 nozzle.json index 3be97a337f..27a8aa59bf 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "XcxbsZ4d8Dh21WX0", "name": "QIDI PETG Basic @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "XcxbsZ4d8Dh21WX0", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.8 nozzle.json index 92a57fb1b8..3c35473c25 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "9MEoOjLU7AOCvb9X", "name": "QIDI PETG Basic @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "9MEoOjLU7AOCvb9X", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @X-Plus 5.json index 7254fd50bb..ab14286d6d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Basic @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFuJ49uH", "name": "QIDI PETG Basic@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFuJ49uH", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.2 nozzle.json index 220a6ce55a..151b6bafd4 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "oi5JKM4fwEYHefs0", "name": "QIDI PETG Rapido @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "oi5JKM4fwEYHefs0", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.4 nozzle.json index 9fe3affac2..9c695c8b5a 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "SZOwb16vrcdtaDzJ", "name": "QIDI PETG Rapido @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "SZOwb16vrcdtaDzJ", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.6 nozzle.json index a550919113..3b0ee18299 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "4LKxL4N0ccD6vZ60", "name": "QIDI PETG Rapido @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "4LKxL4N0ccD6vZ60", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.8 nozzle.json index b56b55d1ff..70e2c8de58 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "rsNDDt3IFUOMYV3O", "name": "QIDI PETG Rapido @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "rsNDDt3IFUOMYV3O", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @X-Plus 5.json index 01a3e6cabe..89af24cc85 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Rapido @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF4S3To3", "name": "QIDI PETG Rapido@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF4S3To3", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.2 nozzle.json index 7708ebba0d..b74a782893 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "k4kLQheLeWOw8bwp", "name": "QIDI PETG Tough @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Tough@X-Plus 5-Series", + "from": "system", + "setting_id": "k4kLQheLeWOw8bwp", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.4 nozzle.json index 5c8c182a2b..46d3107ff9 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "WEyrSDtW2CJeLQmg", "name": "QIDI PETG Tough @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Tough@X-Plus 5-Series", + "from": "system", + "setting_id": "WEyrSDtW2CJeLQmg", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.6 nozzle.json index ad75cc5722..6949cb951d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "Morgo6GIzU3Voc0Q", "name": "QIDI PETG Tough @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Tough@X-Plus 5-Series", + "from": "system", + "setting_id": "Morgo6GIzU3Voc0Q", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.8 nozzle.json index 37c0beddb9..9b02b7f1c8 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "DsoxBXKOjsENLEZf", "name": "QIDI PETG Tough @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Tough@X-Plus 5-Series", + "from": "system", + "setting_id": "DsoxBXKOjsENLEZf", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @X-Plus 5.json index ed1b218139..65bcd87f2d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Tough @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFQ40XeN", "name": "QIDI PETG Tough@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFQ40XeN", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.2 nozzle.json index 03e72feba9..63875362fe 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "2UJnG0rXeU2nCIQL", "name": "QIDI PETG Translucent @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Translucent@X-Plus 5-Series", + "from": "system", + "setting_id": "2UJnG0rXeU2nCIQL", + "instantiation": "true", "filament_max_volumetric_speed": [ "1" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.4 nozzle.json index 545bd42538..9730016f67 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "S2DQ7jy5KqbiVNnV", "name": "QIDI PETG Translucent @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Translucent@X-Plus 5-Series", + "from": "system", + "setting_id": "S2DQ7jy5KqbiVNnV", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.6 nozzle.json index 963916f76e..929eff1456 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "G33dlk73weGNFNwg", "name": "QIDI PETG Translucent @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Translucent@X-Plus 5-Series", + "from": "system", + "setting_id": "G33dlk73weGNFNwg", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.8 nozzle.json index 42bf38bde4..b6a99d1f9d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "zqI9F8vplNFfm2pa", "name": "QIDI PETG Translucent @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG Translucent@X-Plus 5-Series", + "from": "system", + "setting_id": "zqI9F8vplNFfm2pa", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @X-Plus 5.json index 94792b7a75..5bedf7bcf2 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG Translucent @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFf0MkD5", "name": "QIDI PETG Translucent@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFf0MkD5", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.4 nozzle.json index 04176974f5..15b1691904 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "cXbQtMQKmAFqwmqK", "name": "QIDI PETG-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "cXbQtMQKmAFqwmqK", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.6 nozzle.json index ce16a13acf..a828f3958b 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "YNIWSLXvW6kSPRFG", "name": "QIDI PETG-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "YNIWSLXvW6kSPRFG", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.8 nozzle.json index e1ce42ee0a..19a87d0ea7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "O0lwfGXO3BdPCask", "name": "QIDI PETG-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "O0lwfGXO3BdPCask", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @X-Plus 5.json index 19f7f473dd..91a9dbcc9f 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF4iWKrE", "name": "QIDI PETG-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF4iWKrE", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.4 nozzle.json index 46b3b1176a..3a81d10184 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "zfI1VXQ7E0re78CC", "name": "QIDI PETG-GF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "zfI1VXQ7E0re78CC", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.6 nozzle.json index 4af6b7db02..77eb2fc3b4 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "zYEbjZPipK4BgHRO", "name": "QIDI PETG-GF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "zYEbjZPipK4BgHRO", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.8 nozzle.json index bf819e04a9..2388ed7488 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "5ef246YwGEK0eVCr", "name": "QIDI PETG-GF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PETG-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "5ef246YwGEK0eVCr", + "instantiation": "true", "pressure_advance": [ "0.04" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @X-Plus 5.json index 3bed003091..a278471f44 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PETG-GF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFdtPd9h", "name": "QIDI PETG-GF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFdtPd9h", + "instantiation": "false", "box_temperature_range_high": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.2 nozzle.json index 4ec7f05eb9..7ccc28f4ea 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "sfrpgBzPufKwgBCT", "name": "QIDI PLA Basic @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "sfrpgBzPufKwgBCT", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.4 nozzle.json index 20dd378bd2..a0ca3347bd 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "6ZscfuWENwCkdSYE", "name": "QIDI PLA Basic @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "6ZscfuWENwCkdSYE", + "instantiation": "true", "pressure_advance": [ "0.038" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.6 nozzle.json index 574e748c98..ebb3690322 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "pEry2GMq8UJEw7c7", "name": "QIDI PLA Basic @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "pEry2GMq8UJEw7c7", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.8 nozzle.json index 527eb00054..73c062b226 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "MTq8xcAKCWABLI2k", "name": "QIDI PLA Basic @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "MTq8xcAKCWABLI2k", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @X-Plus 5.json index 30e12990e3..5e0fe80a47 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Basic @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF4nQ62r", "name": "QIDI PLA Basic@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF4nQ62r", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.2 nozzle.json index 0078600f36..f70f0cc585 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "54iiCCwizthHtT1v", "name": "QIDI PLA Matte Basic @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Matte Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "54iiCCwizthHtT1v", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.4 nozzle.json index d67aa77dc4..b5a20a483f 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ojnl8sBbBL4QBL8q", "name": "QIDI PLA Matte Basic @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Matte Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "ojnl8sBbBL4QBL8q", + "instantiation": "true", "pressure_advance": [ "0.038" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.6 nozzle.json index 6575396e45..479b0f01d7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "XtZarwF2HIipdHjN", "name": "QIDI PLA Matte Basic @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Matte Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "XtZarwF2HIipdHjN", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.8 nozzle.json index 8c4584a70b..23fa3c1ce8 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "TRkCNQeoDvLBaJMt", "name": "QIDI PLA Matte Basic @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Matte Basic@X-Plus 5-Series", + "from": "system", + "setting_id": "TRkCNQeoDvLBaJMt", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @X-Plus 5.json index 2843092024..f59be1d0c7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Matte Basic @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFughwKn", "name": "QIDI PLA Matte Basic@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFughwKn", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.2 nozzle.json index 3ea3dac12f..e963435867 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "S56TixVPmXr4uFut", "name": "QIDI PLA Rapido @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "S56TixVPmXr4uFut", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.4 nozzle.json index 178fcfd08d..478bd28b07 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KATHrxoL84i7MiVJ", "name": "QIDI PLA Rapido @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "KATHrxoL84i7MiVJ", + "instantiation": "true", "pressure_advance": [ "0.038" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.6 nozzle.json index 2ad1d18a60..f57cabb657 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "YE6WmGAG5Ua6bbap", "name": "QIDI PLA Rapido @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "YE6WmGAG5Ua6bbap", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.8 nozzle.json index ffc9edfb78..ed1b1ef153 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KPqnbBv0Np93O02u", "name": "QIDI PLA Rapido @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "KPqnbBv0Np93O02u", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @X-Plus 5.json index 6327908055..c8292370bb 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFKIQO2W", "name": "QIDI PLA Rapido@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFKIQO2W", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "45" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.2 nozzle.json index e469cf1fd1..1de6949d00 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "jlUpp5oaYSWwaNn1", "name": "QIDI PLA Rapido Matte @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Matte@X-Plus 5-Series", + "from": "system", + "setting_id": "jlUpp5oaYSWwaNn1", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.4 nozzle.json index 3f74323770..cf3780c37a 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "E0gYAZUksoFlebuH", "name": "QIDI PLA Rapido Matte @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Matte@X-Plus 5-Series", + "from": "system", + "setting_id": "E0gYAZUksoFlebuH", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.6 nozzle.json index f45479c37f..42deb84165 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "juxpaK6EosaHj2ok", "name": "QIDI PLA Rapido Matte @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Matte@X-Plus 5-Series", + "from": "system", + "setting_id": "juxpaK6EosaHj2ok", + "instantiation": "true", "pressure_advance": [ "0.016" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.8 nozzle.json index 7e4ec99248..e5020c3aa0 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "OlgI3WQA3QLhPsdw", "name": "QIDI PLA Rapido Matte @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Matte@X-Plus 5-Series", + "from": "system", + "setting_id": "OlgI3WQA3QLhPsdw", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @X-Plus 5.json index 9e2380faea..6d66f820ac 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Matte @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF3IKafc", "name": "QIDI PLA Rapido Matte@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF3IKafc", + "instantiation": "false", "additional_cooling_fan_speed": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json index 7506c80541..0a456a70c8 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "t9qUv1IlI5VJ8LoV", "name": "QIDI PLA Rapido Metal @Qidi X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "t9qUv1IlI5VJ8LoV", + "instantiation": "true", "filament_max_volumetric_speed": [ "2" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json index e2be1216f3..821ae99c83 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ARcrUoVsGSM0RB1a", "name": "QIDI PLA Rapido Metal @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "ARcrUoVsGSM0RB1a", + "instantiation": "true", "pressure_advance": [ "0.038" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json index 2b3fae0a1e..3dc29e0274 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "A23HjUFAyt4GeHAW", "name": "QIDI PLA Rapido Metal @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "A23HjUFAyt4GeHAW", + "instantiation": "true", "pressure_advance": [ "0.020" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json index e6868b6772..fe0b014127 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "nMpSP1jmsQIUjGPb", "name": "QIDI PLA Rapido Metal @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Rapido Metal@X-Plus 5-Series", + "from": "system", + "setting_id": "nMpSP1jmsQIUjGPb", + "instantiation": "true", "pressure_advance": [ "0.01" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @X-Plus 5.json index bc9f655538..9f94f435be 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Rapido Metal @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFANFm4x", "name": "QIDI PLA Rapido Metal@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFANFm4x", + "instantiation": "false", "filament_type": [ "PLA" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.4 nozzle.json index dfd789a216..32461ff6d1 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "IUU7TApRivYtrrt0", "name": "QIDI PLA Silk @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Silk@X-Plus 5-Series", + "from": "system", + "setting_id": "IUU7TApRivYtrrt0", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.6 nozzle.json index 286c1d3a36..aa4b899180 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "lx9Dqv6EMmZ0C2SD", "name": "QIDI PLA Silk @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA Silk@X-Plus 5-Series", + "from": "system", + "setting_id": "lx9Dqv6EMmZ0C2SD", + "instantiation": "true", "pressure_advance": [ "0.021" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @X-Plus 5.json index 2b6574b104..81a6411737 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA Silk @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF2TQpOO", "name": "QIDI PLA Silk@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF2TQpOO", + "instantiation": "false", "additional_cooling_fan_speed": [ "100" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.4 nozzle.json index c341f7c71d..9537368024 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "5PocTwpY0SnNzcdc", "name": "QIDI PLA-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "5PocTwpY0SnNzcdc", + "instantiation": "true", "pressure_advance": [ "0.034" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.6 nozzle.json index 5c08e7f67f..2157d07648 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "5NETSLSQlaoR2MYD", "name": "QIDI PLA-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "5NETSLSQlaoR2MYD", + "instantiation": "true", "pressure_advance": [ "0.012" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.8 nozzle.json index 7435222e8b..5dd00e049d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "AUO7iSMEa6GDvM7Y", "name": "QIDI PLA-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PLA-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "AUO7iSMEa6GDvM7Y", + "instantiation": "true", "filament_max_volumetric_speed": [ "18" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @X-Plus 5.json index 390b331556..cf71930b51 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PLA-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFhWrAuP", "name": "QIDI PLA-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFhWrAuP", + "instantiation": "false", "additional_cooling_fan_speed": [ "0" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.4 nozzle.json index 2c2d573713..761944e013 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "FwWut7sJIMbe87XC", "name": "QIDI PPS-CF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PPS-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "FwWut7sJIMbe87XC", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.6 nozzle.json index 9cc0556490..1547ca8bec 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "gDIuKCdgoP59Xc0G", "name": "QIDI PPS-CF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PPS-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "gDIuKCdgoP59Xc0G", + "instantiation": "true", "pressure_advance": [ "0.021" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.8 nozzle.json index 573f8e17f8..512bc7617e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "D29sGCB9OI4cTn0S", "name": "QIDI PPS-CF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PPS-CF@X-Plus 5-Series", + "from": "system", + "setting_id": "D29sGCB9OI4cTn0S", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @X-Plus 5.json index b482042819..c70f3c26b2 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-CF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFZOuWrO", "name": "QIDI PPS-CF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFZOuWrO", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.4 nozzle.json index de96ad5f7a..5e6446b802 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "5C6dIIgQOt4NiTu0", "name": "QIDI PPS-GF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PPS-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "5C6dIIgQOt4NiTu0", + "instantiation": "true", "pressure_advance": [ "0.03" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.6 nozzle.json index 470839ef59..e88688b456 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "aSd6UW4Mrlxpa15E", "name": "QIDI PPS-GF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PPS-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "aSd6UW4Mrlxpa15E", + "instantiation": "true", "pressure_advance": [ "0.021" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.8 nozzle.json index 6cc49dbd68..277492f8e4 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "7JC2zAUgtGu5zSGo", "name": "QIDI PPS-GF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI PPS-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "7JC2zAUgtGu5zSGo", + "instantiation": "true", "pressure_advance": [ "0.008" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @X-Plus 5.json index f973121e62..61d4c6a502 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI PPS-GF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFp57RRC", "name": "QIDI PPS-GF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFp57RRC", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.4 nozzle.json index 5bd3b85fb9..44e8e0df5d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "oMvDD9rKJGcezwpq", "name": "QIDI Support For PAHT @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI Support For PAHT@X-Plus 5-Series", + "from": "system", + "setting_id": "oMvDD9rKJGcezwpq", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.6 nozzle.json index 37f474533e..e37712ead6 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "6BhbbuUP6HCVScDd", "name": "QIDI Support For PAHT @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI Support For PAHT@X-Plus 5-Series", + "from": "system", + "setting_id": "6BhbbuUP6HCVScDd", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.8 nozzle.json index f28e56c5b1..a568d0cd8a 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "kA4fvvj6xZEhArXv", "name": "QIDI Support For PAHT @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI Support For PAHT@X-Plus 5-Series", + "from": "system", + "setting_id": "kA4fvvj6xZEhArXv", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @X-Plus 5.json index 63941c851b..5484c472f5 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PAHT @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFXn3Vd9", "name": "QIDI Support For PAHT@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFXn3Vd9", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.4 nozzle.json index 615d9af041..99cc873ddf 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "0xy82KbAJD5uBara", "name": "QIDI Support For PET/PA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI Support For PET/PA@X-Plus 5-Series", + "from": "system", + "setting_id": "0xy82KbAJD5uBara", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.6 nozzle.json index 1e0c81424c..e8c4526fc7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "2oCGYFdC4dfpNUw4", "name": "QIDI Support For PET/PA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI Support For PET/PA@X-Plus 5-Series", + "from": "system", + "setting_id": "2oCGYFdC4dfpNUw4", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.8 nozzle.json index 2d47d18707..9e9160a2b5 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "hFYahJkYIgmjcuPb", "name": "QIDI Support For PET/PA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI Support For PET/PA@X-Plus 5-Series", + "from": "system", + "setting_id": "hFYahJkYIgmjcuPb", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @X-Plus 5.json index 969fc2bccc..34d1baa32f 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI Support For PET-PA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFqcL5UF", "name": "QIDI Support For PET/PA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFqcL5UF", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.4 nozzle.json index 1f2db1eb25..6be778053d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "ygLg4KVojo7YoG5K", "name": "QIDI TPU 95A-HF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU 95A-HF@X-Plus 5-Series", + "from": "system", + "setting_id": "ygLg4KVojo7YoG5K", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.6 nozzle.json index 94e992d0e9..30e5899f0b 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "K98nPXclatc5HnIx", "name": "QIDI TPU 95A-HF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU 95A-HF@X-Plus 5-Series", + "from": "system", + "setting_id": "K98nPXclatc5HnIx", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.8 nozzle.json index e05faeed65..2f41c696dc 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "pTxBir6QC9KhWrLU", "name": "QIDI TPU 95A-HF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU 95A-HF@X-Plus 5-Series", + "from": "system", + "setting_id": "pTxBir6QC9KhWrLU", + "instantiation": "true", "nozzle_temperature": [ "220" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @X-Plus 5.json index 7b06c92253..c7a7ed62cd 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU 95A-HF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFR1XLMN", "name": "QIDI TPU 95A-HF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFR1XLMN", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "30" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.4 nozzle.json index 592ad5a51c..17ca5e5a60 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "KIIwoI87n5MkT83b", "name": "QIDI TPU-Aero @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU-Aero@X-Plus 5-Series", + "from": "system", + "setting_id": "KIIwoI87n5MkT83b", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.6 nozzle.json index f18b67f608..03b11ef242 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "eUNygrv7weqgX7e0", "name": "QIDI TPU-Aero @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU-Aero@X-Plus 5-Series", + "from": "system", + "setting_id": "eUNygrv7weqgX7e0", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @X-Plus 5.json index 4ede2d7d6e..fd8964a9f9 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-Aero @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFMDHOcT", "name": "QIDI TPU-Aero@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFMDHOcT", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "30" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.4 nozzle.json index 8e88b23151..8857639b58 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "AtsowCGhOIw4GeRJ", "name": "QIDI TPU-GF @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "AtsowCGhOIw4GeRJ", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.6 nozzle.json index 5a7687b51c..d5a590bf3e 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "wqk4I1KaRyLEm12W", "name": "QIDI TPU-GF @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "wqk4I1KaRyLEm12W", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.8 nozzle.json index 2fe800d6ab..4349ea9820 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "o2JjRsoi03ST3Wh2", "name": "QIDI TPU-GF @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI TPU-GF@X-Plus 5-Series", + "from": "system", + "setting_id": "o2JjRsoi03ST3Wh2", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @X-Plus 5.json index 90de30cb02..d4a4e6cd55 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI TPU-GF @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF9EHUKK", "name": "QIDI TPU-GF@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF9EHUKK", + "instantiation": "false", "cool_plate_temp_initial_layer": [ "30" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.4 nozzle.json index ae7b99531e..b924628294 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "RzZGtHGu2xKASwwu", "name": "QIDI UltraPA @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI UltraPA@X-Plus 5-Series", + "from": "system", + "setting_id": "RzZGtHGu2xKASwwu", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.6 nozzle.json index e9bfbe4362..7f2e0c6f76 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "0seF33ojhYF6lNM4", "name": "QIDI UltraPA @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI UltraPA@X-Plus 5-Series", + "from": "system", + "setting_id": "0seF33ojhYF6lNM4", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.6 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.8 nozzle.json index 6f03ff7b5a..c2441fd612 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "vfr7Lv94OHi4KOCw", "name": "QIDI UltraPA @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI UltraPA@X-Plus 5-Series", + "from": "system", + "setting_id": "vfr7Lv94OHi4KOCw", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.8 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @X-Plus 5.json index 75a89479e2..84bcd1025d 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFWDe7YH", "name": "QIDI UltraPA@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFWDe7YH", + "instantiation": "false", "box_temperature_range_high": [ "55" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.4 nozzle.json index c88635f447..5988080581 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "8h1ITuLzHYf0J4NA", "name": "QIDI UltraPA-CF25 @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI UltraPA-CF25@X-Plus 5-Series", + "from": "system", + "setting_id": "8h1ITuLzHYf0J4NA", + "instantiation": "true", "compatible_printers": [ "Qidi X-Plus 5 0.4 nozzle" ] diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.6 nozzle.json index 66ac797bb8..c36fea25b1 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "WK63qDyLkG4fznPW", "name": "QIDI UltraPA-CF25 @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI UltraPA-CF25@X-Plus 5-Series", + "from": "system", + "setting_id": "WK63qDyLkG4fznPW", + "instantiation": "true", "pressure_advance": [ "0.022" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.8 nozzle.json index 282fed912a..4e729f5d62 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "53sirpAAiDOx0c8P", "name": "QIDI UltraPA-CF25 @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI UltraPA-CF25@X-Plus 5-Series", + "from": "system", + "setting_id": "53sirpAAiDOx0c8P", + "instantiation": "true", "pressure_advance": [ "0.02" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @X-Plus 5.json index 82c261fbd5..9e8518cacb 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI UltraPA-CF25 @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OF9PELEb", "name": "QIDI UltraPA-CF25@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OF9PELEb", + "instantiation": "false", "box_temperature_range_high": [ "65" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.4 nozzle.json index 2232226b78..eafa4d90e7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "gIumq0YfeZrNDTZt", "name": "QIDI WOOD Rapido @Qidi X-Plus 5 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI WOOD Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "gIumq0YfeZrNDTZt", + "instantiation": "true", "pressure_advance": [ "0.044" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.6 nozzle.json index b9ecf201ba..2067b842b7 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "qUjZ8AUjivOk8uCf", "name": "QIDI WOOD Rapido @Qidi X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI WOOD Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "qUjZ8AUjivOk8uCf", + "instantiation": "true", "pressure_advance": [ "0.024" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.8 nozzle.json index fc15698443..6cd6d5e192 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @Qidi X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "filament", - "setting_id": "A2kztfG9PA7Qxh7r", "name": "QIDI WOOD Rapido @Qidi X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "QIDI WOOD Rapido@X-Plus 5-Series", + "from": "system", + "setting_id": "A2kztfG9PA7Qxh7r", + "instantiation": "true", "pressure_advance": [ "0.012" ], diff --git a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @X-Plus 5.json b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @X-Plus 5.json index efbe41d51d..280d05e09c 100644 --- a/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @X-Plus 5.json +++ b/resources/profiles/Qidi/filament/X5/QIDI WOOD Rapido @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "filament", - "filament_id": "OFvdZ2bx", "name": "QIDI WOOD Rapido@X-Plus 5-Series", - "from": "system", - "instantiation": "false", "inherits": "fdm_filament_x5_common", + "from": "system", + "filament_id": "OFvdZ2bx", + "instantiation": "false", "additional_cooling_fan_speed": [ "100" ], diff --git a/resources/profiles/Qidi/machine/Qidi Q1 Pro 0.4 nozzle.json b/resources/profiles/Qidi/machine/Qidi Q1 Pro 0.4 nozzle.json index a085ce6cfe..bd2398ae7a 100644 --- a/resources/profiles/Qidi/machine/Qidi Q1 Pro 0.4 nozzle.json +++ b/resources/profiles/Qidi/machine/Qidi Q1 Pro 0.4 nozzle.json @@ -63,15 +63,19 @@ "112x112" ], "machine_max_jerk_e": [ + "2", "2" ], "machine_max_jerk_x": [ + "8", "8" ], "machine_max_jerk_y": [ + "8", "8" ], "machine_max_jerk_z": [ + "3", "3" ], "extruder_clearance_radius": "70", diff --git a/resources/profiles/Qidi/machine/Qidi Q2 0.4 nozzle.json b/resources/profiles/Qidi/machine/Qidi Q2 0.4 nozzle.json index 6a0a91b2ac..623bbf841d 100644 --- a/resources/profiles/Qidi/machine/Qidi Q2 0.4 nozzle.json +++ b/resources/profiles/Qidi/machine/Qidi Q2 0.4 nozzle.json @@ -33,18 +33,23 @@ "machine_end_gcode": "DISABLE_BOX_HEATER\nM141 S0\nM140 S0\nBUFFER_MONITORING ENABLE=0\nDISABLE_ALL_SENSOR\nG1 E-3 F1800\nG0 Z{max_layer_z + 3} F600\nUNLOAD_FILAMENT T=[current_extruder]\nG0 Y270 F12000\nG0 X90 Y270 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}\nM104 S0", "machine_load_filament_time": "35", "machine_max_jerk_e": [ + "4", "4" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "4", "4" ], "machine_max_speed_z": [ + "20", "20" ], "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Qidi/machine/Qidi Q2C 0.4 nozzle.json b/resources/profiles/Qidi/machine/Qidi Q2C 0.4 nozzle.json index 9d4683885f..84f3e8700a 100644 --- a/resources/profiles/Qidi/machine/Qidi Q2C 0.4 nozzle.json +++ b/resources/profiles/Qidi/machine/Qidi Q2C 0.4 nozzle.json @@ -33,18 +33,23 @@ "machine_end_gcode": "DISABLE_BOX_HEATER\nM140 S0\nBUFFER_MONITORING ENABLE=0\nDISABLE_ALL_SENSOR\nG1 E-3 F1800\nG0 Z{max_layer_z + 3} F600\nUNLOAD_FILAMENT T=[current_extruder]\nG0 Y270 F12000\nG0 X90 Y270 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}\nM104 S0", "machine_load_filament_time": "35", "machine_max_jerk_e": [ + "4", "4" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "4", "4" ], "machine_max_speed_z": [ + "20", "20" ], "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Qidi/machine/Qidi X-Max 4 0.4 nozzle.json b/resources/profiles/Qidi/machine/Qidi X-Max 4 0.4 nozzle.json index ef26c0a620..f7cda2a1cd 100644 --- a/resources/profiles/Qidi/machine/Qidi X-Max 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/machine/Qidi X-Max 4 0.4 nozzle.json @@ -30,31 +30,40 @@ "layer_change_gcode": "{if timelapse_type == 1} ; timelapse with wipe tower\nG92 E0\nG1 E-[retraction_length] F1800\nG2 Z{layer_z + 0.4} I0.86 J0.86 P1 F20000 ; spiral lift a little\nMOVE_TO_TRASH\n{if layer_z <=25}\nG1 Z25\n{endif}\nG92 E0\nM400\nTIMELAPSE_TAKE_FRAME\nG1 E[retraction_length] F300\nG1 X180 F8000\nG1 Y380\n{if layer_z <=25}\nG1 Z[layer_z]\n{endif}\n{elsif timelapse_type == 0} ; timelapse without wipe tower\nTIMELAPSE_TAKE_FRAME\n{endif}\nG92 E0\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1}", "machine_end_gcode": "SET_PRINT_MAIN_STATUS MAIN_STATUS=print_end\nDISABLE_BOX_HEATER\nM141 S0\nM140 S0\nDISABLE_ALL_SENSOR\nG1 E-3 F1800\nG0 Z{max_layer_z + 3} F600\nUNLOAD_FILAMENT T=[current_extruder]\nG0 Y380 F12000\nG0 X128 Y380 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}\nM104 S0\nPRINT_END", "machine_max_jerk_e": [ + "4", "4" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "4", "4" ], "machine_max_speed_z": [ + "20", "20" ], "machine_pause_gcode": "PAUSE", "machine_max_acceleration_x": [ + "30000", "30000" ], "machine_max_acceleration_y": [ + "30000", "30000" ], "machine_max_speed_x": [ + "800", "800" ], "machine_max_speed_y": [ + "800", "800" ], "machine_start_gcode": ";===== PRINT_PHASE_INIT =====\nSET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nSET_PRINT_MAIN_STATUS MAIN_STATUS=print_start\nM220 S100\nM221 S100\nDISABLE_ALL_SENSOR\nM1002 R1\nM107\nCLEAR_PAUSE\nM140 S[bed_temperature_initial_layer_single]\nM141 S[chamber_temperature]\nG29.0\nSET_PRINT_SUB_STATUS SUB_STATUS=tool_head_reset\nG28\n\n;===== BOX_PREPAR =====\nSET_PRINT_SUB_STATUS SUB_STATUS=change_filament\nBOX_PRINT_START EXTRUDER=[initial_no_support_extruder] HOTENDTEMP={nozzle_temperature_range_high[initial_tool]}\nM400\nEXTRUSION_AND_FLUSH HOTEND=[nozzle_temperature_initial_layer]\n\n;===== CLEAR_NOZZLE =====\nSET_PRINT_SUB_STATUS SUB_STATUS=flush_filament\nG1 Z20 F480\nMOVE_TO_TRASH\nG1 Y403.5 F2000\n{if chamber_temperature[0] == 0}\nM106 P3 S[during_print_exhaust_fan_speed]\n{else}\nM106 P3 S0\n{endif}\nM1004\nM106 S0\nM109 S[nozzle_temperature_initial_layer]\nG92 E0\nM83\nG1 E5 F80\nG1 E250 F300\nM400\nM106 S255\nG1 E-3 F1000\nM104 S140\nSET_PRINT_SUB_STATUS SUB_STATUS=clear_nozzle\nM109.1 S{nozzle_temperature_initial_layer[0]-30}\nM204 S10000\nG1 Y403 F2000\nG1 X163 F8000\nG1 X145 F5000\nG1 X163 F8000\nG1 X145 F5000\nG1 X175 F6000\nG1 X163\nG1 X175\nG1 X163\nG1 X175\nG1 X163\nG1 X180 F10000\nG1 Y395 F6000\nG1 X188\nG1 Z-0.2 F480\nM106 S255\nM109.1 S150\nG91\nG1 X15 F200\nG1 Y2\nG1 X-15\nG1 Y-2\nG1 X15\nG90\nG2 I0.5 J0.5 F480\nG2 I0.5 J0.5\nG2 I0.5 J0.5\nG1 Z10\nG1 Y383 F12000\nG1 X116\nG1 Y403\nG1 X163 F8000\nG1 X145 F5000\nG1 X163 F8000\nG1 X145 F5000\nG1 X175 F6000\nG1 X163\nG1 X175\nG1 X163\nG1 X175\nG1 X163\nG1 X180 F10000\nG1 X195 Y195\nM106 S0\nSET_PRINT_SUB_STATUS SUB_STATUS=wait_bed_temp\nM190 S[bed_temperature_initial_layer_single]\nSET_PRINT_SUB_STATUS SUB_STATUS=wait_chamber_temp\nM191 S[chamber_temperature]\nG1 Y0 F15000\nG1 X15\nG1 X3 F5000\nG4 P1000\nG1 X4 F1000\nG1 X3 F5000\nG4 P1000\nG1 E-4 F1800\nG1 X15 F3000\nG1 X20 Y20 F15000\nSET_PRINT_SUB_STATUS SUB_STATUS=z_tilt_adjust\nZ_TILT_ADJUST\nSET_PRINT_SUB_STATUS SUB_STATUS=auto_bed_adjust\nG29\nM1002 A1\nG1 X195 Y195 Z10 F20000\nG92_ Z{10 - ((nozzle_temperature_initial_layer[initial_tool] - 130) / 14 - 5.0) / 100}\nG0 Y1\nM109 S[nozzle_temperature_initial_layer]\nENABLE_ALL_SENSOR\n\n;===== PRINT_START =====\n; LAYER_HEIGHT: 0.2\nT[initial_tool]\nM140 S[bed_temperature_initial_layer_single]\nM104 S[nozzle_temperature_initial_layer]\nM141 S[chamber_temperature]\nG4 P3000\nprobe samples=1\nG91\nG0 Z0.6 F480\nG90\nG1 X175 Y1 F20000\nG1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\nG1 X215 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\nG1 Z1 F480\nSET_PRINT_MAIN_STATUS MAIN_STATUS=printing", diff --git a/resources/profiles/Qidi/machine/Qidi X-Plus 4 0.4 nozzle.json b/resources/profiles/Qidi/machine/Qidi X-Plus 4 0.4 nozzle.json index a7d2f09195..21c4b29044 100644 --- a/resources/profiles/Qidi/machine/Qidi X-Plus 4 0.4 nozzle.json +++ b/resources/profiles/Qidi/machine/Qidi X-Plus 4 0.4 nozzle.json @@ -68,21 +68,27 @@ "96x96" ], "machine_max_jerk_e": [ + "4", "4" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "4", "4" ], "machine_max_acceleration_retracting": [ + "20000", "20000" ], "machine_max_speed_z": [ + "20", "20" ], "retract_lift_below": [ diff --git a/resources/profiles/Qidi/machine/Qidi X-Plus 5 0.4 nozzle.json b/resources/profiles/Qidi/machine/Qidi X-Plus 5 0.4 nozzle.json index f23f86af2a..7ee84157f8 100644 --- a/resources/profiles/Qidi/machine/Qidi X-Plus 5 0.4 nozzle.json +++ b/resources/profiles/Qidi/machine/Qidi X-Plus 5 0.4 nozzle.json @@ -32,30 +32,39 @@ "layer_change_gcode": "{if timelapse_type == 1} ; timelapse with wipe tower\nG92 E0\nG1 E-[retraction_length] F1800\n{if layer_z + 0.4 > max_print_height}\nG2 Z{max_print_height} I0.86 J0.86 P1 F20000 ; spiral lift a little\n{else}\nG2 Z{layer_z + 0.4} I0.86 J0.86 P1 F20000 ; spiral lift a little\n{endif}\nMOVE_TO_TRASH\n{if layer_z <=25}\nG1 Z25\n{endif}\nG92 E0\nM400\nTIMELAPSE_TAKE_FRAME\nG1 E[retraction_length] F300\nG1 X140 F8000\nG1 Y319\n{if layer_z <=25}\nG1 Z[layer_z]\n{endif}\n{elsif timelapse_type == 0} ; timelapse without wipe tower\nTIMELAPSE_TAKE_FRAME\n{endif}\nG92 E0\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1}", "machine_end_gcode": "SET_PRINT_MAIN_STATUS MAIN_STATUS=print_end\nDISABLE_BOX_HEATER\nM141 S0\nM140 S0\nDISABLE_ALL_SENSOR\nG1 E-3 F1800\n{if max_layer_z + 3 > max_print_height}\nG0 Z{max_print_height} F600\n{else}\nG0 Z{max_layer_z + 3} F600\n{endif}\nUNLOAD_FILAMENT T=[current_extruder]\nG0 Y320 F12000\nG0 X105 Y320 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}\nM104 S0\nPRINT_END", "machine_max_acceleration_x": [ + "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", "20000" ], "machine_max_jerk_e": [ + "4", "4" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "4", "4" ], "machine_max_speed_x": [ + "600", "600" ], "machine_max_speed_y": [ + "600", "600" ], "machine_max_speed_z": [ + "20", "20" ], "machine_pause_gcode": "PAUSE", diff --git a/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5 0.2 nozzle.json index 6ef2deee1a..290b2a8785 100644 --- a/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "ojwggKwtZ95dDdGn", "name": "0.08mm High Quality @X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "ojwggKwtZ95dDdGn", + "instantiation": "true", "bottom_color_penetration_layers": "5", "bottom_shell_layers": "5", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5.json b/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5.json index 5b76c79ef4..3ffa85deba 100644 --- a/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.08mm High Quality @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "pdbmnAHtrlkeD1D6", "name": "0.08mm High Quality @X-Plus 5", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "pdbmnAHtrlkeD1D6", + "instantiation": "true", "bottom_color_penetration_layers": "7", "bottom_shell_layers": "7", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.10mm Standard @X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/process/0.10mm Standard @X-Plus 5 0.2 nozzle.json index a8a9aa5f37..79c6ac4712 100644 --- a/resources/profiles/Qidi/process/0.10mm Standard @X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/process/0.10mm Standard @X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "3k8N3voNC9Kp0Ov6", "name": "0.10mm Standard @X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "3k8N3voNC9Kp0Ov6", + "instantiation": "true", "bottom_color_penetration_layers": "5", "bottom_shell_layers": "5", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.12mm Balanced Quality @X-Plus 5 0.2 nozzle.json b/resources/profiles/Qidi/process/0.12mm Balanced Quality @X-Plus 5 0.2 nozzle.json index 1c1d304ccd..5dc8f6532b 100644 --- a/resources/profiles/Qidi/process/0.12mm Balanced Quality @X-Plus 5 0.2 nozzle.json +++ b/resources/profiles/Qidi/process/0.12mm Balanced Quality @X-Plus 5 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "O20HfmdyTRg2xayA", "name": "0.12mm Balanced Quality @X-Plus 5 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "O20HfmdyTRg2xayA", + "instantiation": "true", "bottom_color_penetration_layers": "5", "bottom_shell_layers": "5", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.12mm High Quality @X-Plus 5.json b/resources/profiles/Qidi/process/0.12mm High Quality @X-Plus 5.json index a74aecb369..d2b490a4b1 100644 --- a/resources/profiles/Qidi/process/0.12mm High Quality @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.12mm High Quality @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "xWoxLO8XiKAOEvPO", "name": "0.12mm High Quality @X-Plus 5", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "xWoxLO8XiKAOEvPO", + "instantiation": "true", "bottom_color_penetration_layers": "5", "bottom_shell_layers": "5", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.16mm High Quality @X-Plus 5.json b/resources/profiles/Qidi/process/0.16mm High Quality @X-Plus 5.json index 54f20f7324..7d0d689ddb 100644 --- a/resources/profiles/Qidi/process/0.16mm High Quality @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.16mm High Quality @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "7hYw7osV25Xu2yiu", "name": "0.16mm High Quality @X-Plus 5", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "7hYw7osV25Xu2yiu", + "instantiation": "true", "bottom_color_penetration_layers": "4", "bottom_shell_layers": "4", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.16mm Standard @X-Plus 5.json b/resources/profiles/Qidi/process/0.16mm Standard @X-Plus 5.json index 5399e693aa..1501ed2daf 100644 --- a/resources/profiles/Qidi/process/0.16mm Standard @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.16mm Standard @X-Plus 5.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "xP7mco0WGscmPNoV", "name": "0.16mm Standard @X-Plus 5", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "xP7mco0WGscmPNoV", + "instantiation": "true", "bottom_color_penetration_layers": "4", "bottom_shell_layers": "4", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.18mm Balanced Quality @X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/process/0.18mm Balanced Quality @X-Plus 5 0.6 nozzle.json index 85d94d49a7..50c7af3c16 100644 --- a/resources/profiles/Qidi/process/0.18mm Balanced Quality @X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/process/0.18mm Balanced Quality @X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "kj7YrKOrYowWXXrY", "name": "0.18mm Balanced Quality @X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "kj7YrKOrYowWXXrY", + "instantiation": "true", "bridge_flow": "1", "bridge_speed": [ "30" diff --git a/resources/profiles/Qidi/process/0.20mm High Quality @X-Plus 5.json b/resources/profiles/Qidi/process/0.20mm High Quality @X-Plus 5.json index 4f8c7b4ef4..5fdcac42e1 100644 --- a/resources/profiles/Qidi/process/0.20mm High Quality @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.20mm High Quality @X-Plus 5.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "azERQAEOdeNEo2z7", "name": "0.20mm High Quality @X-Plus 5", - "from": "system", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "azERQAEOdeNEo2z7", "instantiation": "true", "bottom_shell_layers": "3", "bridge_flow": "1", diff --git a/resources/profiles/Qidi/process/0.20mm Standard @X-Plus 5.json b/resources/profiles/Qidi/process/0.20mm Standard @X-Plus 5.json index decaceecae..49a75ca11b 100644 --- a/resources/profiles/Qidi/process/0.20mm Standard @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.20mm Standard @X-Plus 5.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ug7kxxCLKKE7MoJW", "name": "0.20mm Standard @X-Plus 5", - "from": "system", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "ug7kxxCLKKE7MoJW", "instantiation": "true", "bridge_flow": "1", "default_acceleration": [ diff --git a/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.6 nozzle.json index 16e25dcef3..bdccab0dbb 100644 --- a/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "BWwslzDWus0iHZM8", "name": "0.24mm Balanced Quality @X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "BWwslzDWus0iHZM8", + "instantiation": "true", "bridge_flow": "1", "bridge_speed": [ "30" diff --git a/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.8 nozzle.json index e7d69b3f09..65649a82e2 100644 --- a/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/process/0.24mm Balanced Quality @X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "TdXf6dJK5dAiFtIW", "name": "0.24mm Balanced Quality @X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "TdXf6dJK5dAiFtIW", + "instantiation": "true", "bridge_flow": "1", "bridge_speed": [ "30" diff --git a/resources/profiles/Qidi/process/0.24mm Standard @X-Plus 5.json b/resources/profiles/Qidi/process/0.24mm Standard @X-Plus 5.json index 8a435e69e7..952d161781 100644 --- a/resources/profiles/Qidi/process/0.24mm Standard @X-Plus 5.json +++ b/resources/profiles/Qidi/process/0.24mm Standard @X-Plus 5.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "fiMTwk6ObF3WNpi5", "name": "0.24mm Standard @X-Plus 5", - "from": "system", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "fiMTwk6ObF3WNpi5", "instantiation": "true", "bridge_flow": "1", "default_acceleration": [ diff --git a/resources/profiles/Qidi/process/0.30mm Standard @X-Plus 5 0.6 nozzle.json b/resources/profiles/Qidi/process/0.30mm Standard @X-Plus 5 0.6 nozzle.json index a297f33bac..5024f95495 100644 --- a/resources/profiles/Qidi/process/0.30mm Standard @X-Plus 5 0.6 nozzle.json +++ b/resources/profiles/Qidi/process/0.30mm Standard @X-Plus 5 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "ZHUAMUGv0HI3h8fQ", "name": "0.30mm Standard @X-Plus 5 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "ZHUAMUGv0HI3h8fQ", + "instantiation": "true", "bridge_flow": "1", "bridge_speed": [ "30" diff --git a/resources/profiles/Qidi/process/0.32mm Balanced Quality @X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/process/0.32mm Balanced Quality @X-Plus 5 0.8 nozzle.json index be02d140d6..d063b5a735 100644 --- a/resources/profiles/Qidi/process/0.32mm Balanced Quality @X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/process/0.32mm Balanced Quality @X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "Vl4hMKR69J1JcquX", "name": "0.32mm Balanced Quality @X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "Vl4hMKR69J1JcquX", + "instantiation": "true", "bridge_flow": "1", "bridge_speed": [ "30" diff --git a/resources/profiles/Qidi/process/0.40mm Standard @X-Plus 5 0.8 nozzle.json b/resources/profiles/Qidi/process/0.40mm Standard @X-Plus 5 0.8 nozzle.json index cb3f30c20e..343fdc744b 100644 --- a/resources/profiles/Qidi/process/0.40mm Standard @X-Plus 5 0.8 nozzle.json +++ b/resources/profiles/Qidi/process/0.40mm Standard @X-Plus 5 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "6EBzl1Pg5Px36Cu6", "name": "0.40mm Standard @X-Plus 5 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_n_common", + "from": "system", + "setting_id": "6EBzl1Pg5Px36Cu6", + "instantiation": "true", "bridge_flow": "1", "bridge_speed": [ "30" diff --git a/resources/profiles/RH3D.json b/resources/profiles/RH3D.json index 3e177c5efd..09b413845f 100644 --- a/resources/profiles/RH3D.json +++ b/resources/profiles/RH3D.json @@ -1,6 +1,6 @@ { "name": "RH3D", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "RH3D - printer profiles", "machine_model_list": [ diff --git a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.2 nozzle.json b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.2 nozzle.json index cc2c23cfd2..0a5e6fc99a 100644 --- a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.2 nozzle.json +++ b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.2 nozzle.json @@ -1,14 +1,14 @@ -{ - "type": "machine", - "name": "E3NG v1.2S - 0.2 nozzle", - "printer_model": "E3NG v1.2S", - "inherits": "fdm_common_E3NG v1.2S", - "from": "system", - "setting_id": "gPm0noz1896R4GyO", - "instantiation": "true", - "default_print_profile": "0.10mm Standard @E3NG v1.2S", - "nozzle_diameter": [ - "0.2" - ], - "printer_variant": "0.2" -} +{ + "type": "machine", + "name": "E3NG v1.2S - 0.2 nozzle", + "inherits": "fdm_common_E3NG v1.2S", + "from": "system", + "setting_id": "gPm0noz1896R4GyO", + "instantiation": "true", + "printer_model": "E3NG v1.2S", + "default_print_profile": "0.10mm Standard @E3NG v1.2S", + "nozzle_diameter": [ + "0.2" + ], + "printer_variant": "0.2" +} diff --git a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.3 nozzle.json b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.3 nozzle.json index 7c3e5e837f..0feb4065cb 100644 --- a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.3 nozzle.json +++ b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.3 nozzle.json @@ -1,14 +1,14 @@ -{ - "type": "machine", - "name": "E3NG v1.2S - 0.3 nozzle", - "printer_model": "E3NG v1.2S", - "inherits": "fdm_common_E3NG v1.2S", - "from": "system", - "setting_id": "UQ67wIWTbJiUiPoy", - "instantiation": "true", - "default_print_profile": "0.15mm Standard @E3NG v1.2S", - "nozzle_diameter": [ - "0.3" - ], - "printer_variant": "0.3" -} +{ + "type": "machine", + "name": "E3NG v1.2S - 0.3 nozzle", + "inherits": "fdm_common_E3NG v1.2S", + "from": "system", + "setting_id": "UQ67wIWTbJiUiPoy", + "instantiation": "true", + "printer_model": "E3NG v1.2S", + "default_print_profile": "0.15mm Standard @E3NG v1.2S", + "nozzle_diameter": [ + "0.3" + ], + "printer_variant": "0.3" +} diff --git a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.4 nozzle.json b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.4 nozzle.json index a0ee4cae85..d199950c27 100644 --- a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.4 nozzle.json +++ b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.4 nozzle.json @@ -1,14 +1,14 @@ -{ - "type": "machine", - "name": "E3NG v1.2S - 0.4 nozzle", - "printer_model": "E3NG v1.2S", - "inherits": "fdm_common_E3NG v1.2S", - "from": "system", - "setting_id": "Ngr03MsSBAkmFnld", - "instantiation": "true", - "default_print_profile": "0.20mm Standard @E3NG v1.2S", - "nozzle_diameter": [ - "0.4" - ], - "printer_variant": "0.4" -} +{ + "type": "machine", + "name": "E3NG v1.2S - 0.4 nozzle", + "inherits": "fdm_common_E3NG v1.2S", + "from": "system", + "setting_id": "Ngr03MsSBAkmFnld", + "instantiation": "true", + "printer_model": "E3NG v1.2S", + "default_print_profile": "0.20mm Standard @E3NG v1.2S", + "nozzle_diameter": [ + "0.4" + ], + "printer_variant": "0.4" +} diff --git a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.5 nozzle.json b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.5 nozzle.json index 12131e5f84..0d1491ef32 100644 --- a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.5 nozzle.json +++ b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.5 nozzle.json @@ -1,14 +1,14 @@ -{ - "type": "machine", - "name": "E3NG v1.2S - 0.5 nozzle", - "printer_model": "E3NG v1.2S", - "inherits": "fdm_common_E3NG v1.2S", - "from": "system", - "setting_id": "GSUiav9EILSf8XF4", - "instantiation": "true", - "default_print_profile": "0.20mm Standard @E3NG v1.2S", - "nozzle_diameter": [ - "0.5" - ], - "printer_variant": "0.5" -} +{ + "type": "machine", + "name": "E3NG v1.2S - 0.5 nozzle", + "inherits": "fdm_common_E3NG v1.2S", + "from": "system", + "setting_id": "GSUiav9EILSf8XF4", + "instantiation": "true", + "printer_model": "E3NG v1.2S", + "default_print_profile": "0.20mm Standard @E3NG v1.2S", + "nozzle_diameter": [ + "0.5" + ], + "printer_variant": "0.5" +} diff --git a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.6 nozzle.json b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.6 nozzle.json index c8288a67bf..a04ef63e45 100644 --- a/resources/profiles/RH3D/machine/E3NG v1.2S - 0.6 nozzle.json +++ b/resources/profiles/RH3D/machine/E3NG v1.2S - 0.6 nozzle.json @@ -1,14 +1,14 @@ -{ - "type": "machine", - "name": "E3NG v1.2S - 0.6 nozzle", - "printer_model": "E3NG v1.2S", - "inherits": "fdm_common_E3NG v1.2S", - "from": "system", - "setting_id": "jVNTcmQwQIwJMfFd", - "instantiation": "true", - "default_print_profile": "0.25mm Standard @E3NG v1.2S", - "nozzle_diameter": [ - "0.6" - ], - "printer_variant": "0.6" -} +{ + "type": "machine", + "name": "E3NG v1.2S - 0.6 nozzle", + "inherits": "fdm_common_E3NG v1.2S", + "from": "system", + "setting_id": "jVNTcmQwQIwJMfFd", + "instantiation": "true", + "printer_model": "E3NG v1.2S", + "default_print_profile": "0.25mm Standard @E3NG v1.2S", + "nozzle_diameter": [ + "0.6" + ], + "printer_variant": "0.6" +} diff --git a/resources/profiles/RH3D/machine/VIRTU E3 - 0.2 nozzle.json b/resources/profiles/RH3D/machine/VIRTU E3 - 0.2 nozzle.json index 8814f25e0c..516ad310e1 100644 --- a/resources/profiles/RH3D/machine/VIRTU E3 - 0.2 nozzle.json +++ b/resources/profiles/RH3D/machine/VIRTU E3 - 0.2 nozzle.json @@ -1,11 +1,11 @@ { "type": "machine", "name": "VIRTU E3 - 0.2 nozzle", - "printer_model": "VIRTU E3", "inherits": "fdm_common_VIRTU E3", "from": "system", "setting_id": "NEqwtUJ9txtcf1vY", "instantiation": "true", + "printer_model": "VIRTU E3", "default_print_profile": "0.10mm Standard @VIRTU E3", "nozzle_diameter": [ "0.2" diff --git a/resources/profiles/RH3D/machine/VIRTU E3 - 0.3 nozzle.json b/resources/profiles/RH3D/machine/VIRTU E3 - 0.3 nozzle.json index 4c27b80bb8..1a9a5dfe55 100644 --- a/resources/profiles/RH3D/machine/VIRTU E3 - 0.3 nozzle.json +++ b/resources/profiles/RH3D/machine/VIRTU E3 - 0.3 nozzle.json @@ -1,11 +1,11 @@ { "type": "machine", "name": "VIRTU E3 - 0.3 nozzle", - "printer_model": "VIRTU E3", "inherits": "fdm_common_VIRTU E3", "from": "system", "setting_id": "3PjlEiZxmdLJjoGw", "instantiation": "true", + "printer_model": "VIRTU E3", "default_print_profile": "0.15mm Standard @VIRTU E3", "nozzle_diameter": [ "0.3" diff --git a/resources/profiles/RH3D/machine/VIRTU E3 - 0.4 nozzle.json b/resources/profiles/RH3D/machine/VIRTU E3 - 0.4 nozzle.json index 7b02993a2b..2f78ffc1ca 100644 --- a/resources/profiles/RH3D/machine/VIRTU E3 - 0.4 nozzle.json +++ b/resources/profiles/RH3D/machine/VIRTU E3 - 0.4 nozzle.json @@ -1,11 +1,11 @@ { "type": "machine", "name": "VIRTU E3 - 0.4 nozzle", - "printer_model": "VIRTU E3", "inherits": "fdm_common_VIRTU E3", "from": "system", "setting_id": "mYCTx4ovF6z0STDL", "instantiation": "true", + "printer_model": "VIRTU E3", "default_print_profile": "0.20mm Standard @VIRTU E3", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/RH3D/machine/VIRTU E3 - 0.5 nozzle.json b/resources/profiles/RH3D/machine/VIRTU E3 - 0.5 nozzle.json index 660dd35305..e8b64a12b3 100644 --- a/resources/profiles/RH3D/machine/VIRTU E3 - 0.5 nozzle.json +++ b/resources/profiles/RH3D/machine/VIRTU E3 - 0.5 nozzle.json @@ -1,11 +1,11 @@ { "type": "machine", "name": "VIRTU E3 - 0.5 nozzle", - "printer_model": "VIRTU E3", "inherits": "fdm_common_VIRTU E3", "from": "system", "setting_id": "iMnENFt2zw6UTcbM", "instantiation": "true", + "printer_model": "VIRTU E3", "default_print_profile": "0.20mm Standard @VIRTU E3", "nozzle_diameter": [ "0.5" diff --git a/resources/profiles/RH3D/machine/VIRTU E3 - 0.6 nozzle.json b/resources/profiles/RH3D/machine/VIRTU E3 - 0.6 nozzle.json index bce4e91736..8963f1b68a 100644 --- a/resources/profiles/RH3D/machine/VIRTU E3 - 0.6 nozzle.json +++ b/resources/profiles/RH3D/machine/VIRTU E3 - 0.6 nozzle.json @@ -1,11 +1,11 @@ { "type": "machine", "name": "VIRTU E3 - 0.6 nozzle", - "printer_model": "VIRTU E3", "inherits": "fdm_common_VIRTU E3", "from": "system", "setting_id": "T1RuDWhyFkI1GH1h", "instantiation": "true", + "printer_model": "VIRTU E3", "default_print_profile": "0.25mm Standard @VIRTU E3", "nozzle_diameter": [ "0.6" diff --git a/resources/profiles/Raise3D.json b/resources/profiles/Raise3D.json index 5f98b967d4..740c9c33e6 100644 --- a/resources/profiles/Raise3D.json +++ b/resources/profiles/Raise3D.json @@ -1,7 +1,7 @@ { "name": "Raise3D", "url": "", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "0", "description": "Raise3D configurations", "machine_model_list": [ diff --git a/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Dual).json b/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Dual).json index 64b55dffaa..73d4a4344e 100644 --- a/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Dual).json +++ b/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Dual).json @@ -26,65 +26,98 @@ "0x300" ], "printable_height": "300", - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "3000", + "3000", "3000", "3000" ], "machine_max_acceleration_extruding": [ + "1000", + "300", "1000", "300" ], "machine_max_acceleration_retracting": [ + "3000", + "1500", "3000", "1500" ], "machine_max_acceleration_travel": [ + "1500", + "500", "1500", "500" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Left).json b/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Left).json index 5275f02ccf..97eee4b9c3 100644 --- a/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Left).json +++ b/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Left).json @@ -26,65 +26,98 @@ "0x300" ], "printable_height": "300", - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "3000", + "3000", "3000", "3000" ], "machine_max_acceleration_extruding": [ + "1000", + "300", "1000", "300" ], "machine_max_acceleration_retracting": [ + "3000", + "1500", "3000", "1500" ], "machine_max_acceleration_travel": [ + "1500", + "500", "1500", "500" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Right).json b/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Right).json index 59b86fd468..2d42bf5b53 100644 --- a/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Right).json +++ b/resources/profiles/Raise3D/machine/Raise3D Pro3 0.4 nozzle (Right).json @@ -26,65 +26,98 @@ "0x300" ], "printable_height": "300", - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "3000", + "3000", "3000", "3000" ], "machine_max_acceleration_extruding": [ + "1000", + "300", "1000", "300" ], "machine_max_acceleration_retracting": [ + "3000", + "1500", "3000", "1500" ], "machine_max_acceleration_travel": [ + "1500", + "500", "1500", "500" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Dual).json b/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Dual).json index e576937531..a70c9d4583 100644 --- a/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Dual).json +++ b/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Dual).json @@ -26,65 +26,98 @@ "0x300" ], "printable_height": "605", - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "3000", + "3000", "3000", "3000" ], "machine_max_acceleration_extruding": [ + "1000", + "300", "1000", "300" ], "machine_max_acceleration_retracting": [ + "3000", + "1500", "3000", "1500" ], "machine_max_acceleration_travel": [ + "1500", + "500", "1500", "500" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Left).json b/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Left).json index a7da5981f0..69fa4fcb07 100644 --- a/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Left).json +++ b/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Left).json @@ -26,65 +26,98 @@ "0x300" ], "printable_height": "605", - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "3000", + "3000", "3000", "3000" ], "machine_max_acceleration_extruding": [ + "1000", + "300", "1000", "300" ], "machine_max_acceleration_retracting": [ + "3000", + "1500", "3000", "1500" ], "machine_max_acceleration_travel": [ + "1500", + "500", "1500", "500" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Right).json b/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Right).json index 2ee32e65d3..d7274d5185 100644 --- a/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Right).json +++ b/resources/profiles/Raise3D/machine/Raise3D Pro3 Plus 0.4 nozzle (Right).json @@ -26,65 +26,98 @@ "0x300" ], "printable_height": "605", - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "3000", + "3000", "3000", "3000" ], "machine_max_acceleration_extruding": [ + "1000", + "300", "1000", "300" ], "machine_max_acceleration_retracting": [ + "3000", + "1500", "3000", "1500" ], "machine_max_acceleration_travel": [ + "1500", + "500", "1500", "500" ], "machine_max_acceleration_x": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], diff --git a/resources/profiles/Ratrig.json b/resources/profiles/Ratrig.json index 743333f9aa..4f161b0001 100644 --- a/resources/profiles/Ratrig.json +++ b/resources/profiles/Ratrig.json @@ -1,6 +1,6 @@ { "name": "RatRig", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "RatRig configurations", "machine_model_list": [ diff --git a/resources/profiles/Ratrig/filament/Generic ABS @RatRig.json b/resources/profiles/Ratrig/filament/Generic ABS @RatRig.json index d45720cf60..6086cfa0e8 100644 --- a/resources/profiles/Ratrig/filament/Generic ABS @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic ABS @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @RatRig", - "inherits": "fdm_filament_abs", "renamed_from": "RatRig Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "0BepsauXBs5bxPYO", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Ratrig/filament/Generic ABS BigNozzle @RatRig.json b/resources/profiles/Ratrig/filament/Generic ABS BigNozzle @RatRig.json index 3d071c779a..19cc67c606 100644 --- a/resources/profiles/Ratrig/filament/Generic ABS BigNozzle @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic ABS BigNozzle @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS BigNozzle @RatRig", - "inherits": "fdm_filament_abs", "renamed_from": "RatRig BigNozzle ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "4GJ4GHOuApWBbQoS", "filament_id": "OFnyHfcv", diff --git a/resources/profiles/Ratrig/filament/Generic ASA @RatRig.json b/resources/profiles/Ratrig/filament/Generic ASA @RatRig.json index 9b70da5bab..83cbfc3240 100644 --- a/resources/profiles/Ratrig/filament/Generic ASA @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic ASA @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @RatRig", - "inherits": "fdm_filament_asa", "renamed_from": "RatRig Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "cogJbKPAXzyCQgvf", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Ratrig/filament/Generic ASA BigNozzle @RatRig.json b/resources/profiles/Ratrig/filament/Generic ASA BigNozzle @RatRig.json index f6f85f78e7..6a66e5856c 100644 --- a/resources/profiles/Ratrig/filament/Generic ASA BigNozzle @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic ASA BigNozzle @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA BigNozzle @RatRig", - "inherits": "fdm_filament_asa", "renamed_from": "RatRig BigNozzle ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "n2V9gkhbqWJzsQBK", "filament_id": "OF4GM5qX", diff --git a/resources/profiles/Ratrig/filament/Generic PA @RatRig.json b/resources/profiles/Ratrig/filament/Generic PA @RatRig.json index 58d6757d78..15f498d4cf 100644 --- a/resources/profiles/Ratrig/filament/Generic PA @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PA @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @RatRig", - "inherits": "fdm_filament_pa", "renamed_from": "RatRig Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "5rpTzhFjS6Ar4Xy8", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Ratrig/filament/Generic PA-CF @RatRig.json b/resources/profiles/Ratrig/filament/Generic PA-CF @RatRig.json index 5b0ea38d75..fe0c69592a 100644 --- a/resources/profiles/Ratrig/filament/Generic PA-CF @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PA-CF @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @RatRig", - "inherits": "fdm_filament_pa", "renamed_from": "RatRig Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "ps7duiwT8adNshEO", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Ratrig/filament/Generic PC @RatRig.json b/resources/profiles/Ratrig/filament/Generic PC @RatRig.json index c6dc89cce5..6ca17d3395 100644 --- a/resources/profiles/Ratrig/filament/Generic PC @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PC @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @RatRig", - "inherits": "fdm_filament_pc", "renamed_from": "RatRig Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "7x5VtUIevdAmBqqA", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Ratrig/filament/Generic PCTG @RatRig.json b/resources/profiles/Ratrig/filament/Generic PCTG @RatRig.json index d3e06685b5..2a4e89addc 100644 --- a/resources/profiles/Ratrig/filament/Generic PCTG @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PCTG @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PCTG @RatRig", - "inherits": "fdm_filament_pet", "renamed_from": "RatRig Generic PCTG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "JMTUqdhoQzCb6ZxJ", "filament_id": "OFu1evlr", diff --git a/resources/profiles/Ratrig/filament/Generic PCTG BigNozzle @RatRig.json b/resources/profiles/Ratrig/filament/Generic PCTG BigNozzle @RatRig.json index 2e47eb6765..a197e62102 100644 --- a/resources/profiles/Ratrig/filament/Generic PCTG BigNozzle @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PCTG BigNozzle @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PCTG BigNozzle @RatRig", - "inherits": "fdm_filament_pctg", "renamed_from": "RatRig BigNozzle PCTG", + "inherits": "fdm_filament_pctg", "from": "system", "setting_id": "HPaol79uY9NdhasQ", "filament_id": "OFXW4CDh", diff --git a/resources/profiles/Ratrig/filament/Generic PETG @RatRig.json b/resources/profiles/Ratrig/filament/Generic PETG @RatRig.json index b0182712b1..633c0a30db 100644 --- a/resources/profiles/Ratrig/filament/Generic PETG @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PETG @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @RatRig", - "inherits": "fdm_filament_pet", "renamed_from": "RatRig Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "6p3FfhhSIAOQGEzT", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Ratrig/filament/Generic PETG BigNozzle @RatRig.json b/resources/profiles/Ratrig/filament/Generic PETG BigNozzle @RatRig.json index 213f41628c..6b3c70b39d 100644 --- a/resources/profiles/Ratrig/filament/Generic PETG BigNozzle @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PETG BigNozzle @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG BigNozzle @RatRig", - "inherits": "fdm_filament_pet", "renamed_from": "RatRig BigNozzle PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "pRM6IVX5T3y6Ywj4", "filament_id": "OFvD0Qqt", diff --git a/resources/profiles/Ratrig/filament/Generic PLA @RatRig.json b/resources/profiles/Ratrig/filament/Generic PLA @RatRig.json index b8a33f4da4..c8a70e0751 100644 --- a/resources/profiles/Ratrig/filament/Generic PLA @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PLA @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @RatRig", - "inherits": "fdm_filament_pla", "renamed_from": "RatRig Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "BsQA6ChWHTDUSlii", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Ratrig/filament/Generic PLA BigNozzle @RatRig.json b/resources/profiles/Ratrig/filament/Generic PLA BigNozzle @RatRig.json index 08d546aafc..50774b8799 100644 --- a/resources/profiles/Ratrig/filament/Generic PLA BigNozzle @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PLA BigNozzle @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA BigNozzle @RatRig", - "inherits": "fdm_filament_pla", "renamed_from": "RatRig BigNozzle PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "WEI4QiKyANQOK7dG", "filament_id": "OFqFRiLb", diff --git a/resources/profiles/Ratrig/filament/Generic PLA-CF @RatRig.json b/resources/profiles/Ratrig/filament/Generic PLA-CF @RatRig.json index 288c892f09..4771b2caad 100644 --- a/resources/profiles/Ratrig/filament/Generic PLA-CF @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PLA-CF @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @RatRig", - "inherits": "fdm_filament_pla", "renamed_from": "RatRig Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "ai3I13fL5giqq5LW", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Ratrig/filament/Generic PVA @RatRig.json b/resources/profiles/Ratrig/filament/Generic PVA @RatRig.json index 016b146181..09e8cad05a 100644 --- a/resources/profiles/Ratrig/filament/Generic PVA @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic PVA @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @RatRig", - "inherits": "fdm_filament_pva", "renamed_from": "RatRig Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "y6DJYhqAmxMng8Kf", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Ratrig/filament/Generic TPU @RatRig.json b/resources/profiles/Ratrig/filament/Generic TPU @RatRig.json index e8ea6176b7..6ed3edbeb0 100644 --- a/resources/profiles/Ratrig/filament/Generic TPU @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic TPU @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @RatRig", - "inherits": "fdm_filament_tpu", "renamed_from": "RatRig Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "dAIGKmZctSRhP1Lu", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/Ratrig/filament/Generic TPU BigNozzle @RatRig.json b/resources/profiles/Ratrig/filament/Generic TPU BigNozzle @RatRig.json index 4714f57d5a..8bd40ac062 100644 --- a/resources/profiles/Ratrig/filament/Generic TPU BigNozzle @RatRig.json +++ b/resources/profiles/Ratrig/filament/Generic TPU BigNozzle @RatRig.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU BigNozzle @RatRig", - "inherits": "fdm_filament_tpu", "renamed_from": "RatRig BigNozzle TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "9UWg2cO61XFdlWxo", "filament_id": "OF5tX6va", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json index 28412dd804..db452dcf21 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json @@ -2,10 +2,10 @@ "type": "machine", "name": "RatRig V-Core 4 300 0.8 nozzle", "inherits": "fdm_klipper_common", - "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "from": "system", "setting_id": "feTeGuFkLzWFFSC4", "instantiation": "true", + "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "printer_model": "RatRig V-Core 4 300", "nozzle_diameter": [ "0.8" diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json index a40343b574..649efabebf 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json @@ -2,10 +2,10 @@ "type": "machine", "name": "RatRig V-Core 4 400 0.8 nozzle", "inherits": "fdm_klipper_common", - "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "from": "system", "setting_id": "DQ7Lzsuk87A4qtav", "instantiation": "true", + "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "printer_model": "RatRig V-Core 4 400", "printer_variant": "0.8", "nozzle_diameter": [ diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json index 828b2d8711..75f518c286 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json @@ -2,10 +2,10 @@ "type": "machine", "name": "RatRig V-Core 4 500 0.8 nozzle", "inherits": "fdm_klipper_common", - "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "from": "system", "setting_id": "VMKIyofeEpPvUvkY", "instantiation": "true", + "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "printer_model": "RatRig V-Core 4 500", "printer_variant": "0.8", "nozzle_diameter": [ diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.4 nozzle.json index 9e3f45189c..d5cae37925 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.4 nozzle.json @@ -24,62 +24,92 @@ "0x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,12 +123,15 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ @@ -106,12 +139,15 @@ "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.5 nozzle.json index 51856c4305..be901905a7 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.5 nozzle.json @@ -24,62 +24,92 @@ "0x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.25", "0.25" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.6 nozzle.json index f255b58824..5fbbf455cc 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.6 nozzle.json @@ -24,62 +24,92 @@ "0x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.3", "0.3" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.8 nozzle.json index cca40b5979..56f1e96dac 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 0.8 nozzle.json @@ -24,62 +24,92 @@ "0x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.3", "0.3" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.4 nozzle.json index 4b49fc36a7..e6789ac2f4 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.4 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.5 nozzle.json index 5e9a55e6e6..532351fa0e 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.5 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.6 nozzle.json index 69848e1743..196b0970e3 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.6 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.8 nozzle.json index 0018a5d250..1a5b501ca9 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 COPY MODE 0.8 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.4 nozzle.json index 902ba9a044..24dff4f024 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.4 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.5 nozzle.json index 873385c476..37bc1f5f00 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.5 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.6 nozzle.json index b9ba5860ea..433d140877 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.6 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.8 nozzle.json index 83cac78c49..d1f2d58e25 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 300 MIRROR MODE 0.8 nozzle.json @@ -24,62 +24,92 @@ "75x300" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.4 nozzle.json index 8d4683eeed..8bd346b1bb 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.4 nozzle.json @@ -24,62 +24,92 @@ "0x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,12 +123,15 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ @@ -106,12 +139,15 @@ "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.5 nozzle.json index cc30cfd0dc..11a65871b7 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.5 nozzle.json @@ -24,62 +24,92 @@ "0x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.25", "0.25" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.6 nozzle.json index e960f29742..0111ef8e99 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.6 nozzle.json @@ -24,62 +24,92 @@ "0x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.3", "0.3" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.8 nozzle.json index 568f9ab12f..d3ec81c9c9 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 0.8 nozzle.json @@ -24,62 +24,92 @@ "0x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.3", "0.3" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.4 nozzle.json index 8837dd0937..ff40588926 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.4 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.5 nozzle.json index be7c731a19..1590ca8b97 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.5 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.6 nozzle.json index f0af89ed75..70e56acda2 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.6 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.8 nozzle.json index 2079c3f39e..e56436666d 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 COPY MODE 0.8 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.4 nozzle.json index 034fbc4477..ead084348a 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.4 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.5 nozzle.json index 2e5d00ff9f..a8b8e11c10 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.5 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.6 nozzle.json index 00c1a3d339..e003b9ff29 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.6 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.8 nozzle.json index 668450c706..4732e2874b 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 400 MIRROR MODE 0.8 nozzle.json @@ -24,62 +24,92 @@ "100x400" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.4 nozzle.json index e117439353..23fe24b867 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.4 nozzle.json @@ -24,62 +24,92 @@ "0x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,12 +123,15 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ @@ -106,12 +139,15 @@ "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.5 nozzle.json index 87096aa4e7..5cd0d2a7aa 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.5 nozzle.json @@ -24,62 +24,92 @@ "0x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.25", "0.25" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.6 nozzle.json index 61903d2dc6..f2beb5c4cd 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.6 nozzle.json @@ -24,62 +24,92 @@ "0x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.3", "0.3" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.8 nozzle.json index 275241f8bf..1db28524d5 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 0.8 nozzle.json @@ -24,62 +24,92 @@ "0x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.3", "0.3" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "START_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.4 nozzle.json index 1ecc8bb035..53fe2527a3 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.4 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.5 nozzle.json index 08ca62e3bb..2ef06808bf 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.5 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.6 nozzle.json index 3f7c43607e..41687594a6 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.6 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.8 nozzle.json index ab1a259368..508b740eda 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 COPY MODE 0.8 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_COPY\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.4 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.4 nozzle.json index f4d6d57d1b..33f40fbeb6 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.4 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.4 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.5 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.5 nozzle.json index 5c89275a42..e41b672612 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.5 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.5 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.6 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.6 nozzle.json index 1b8edc1400..f1f959b1c6 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.6 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.6 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.8 nozzle.json index 12ca6a0a2a..95d215cfb8 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 IDEX 500 MIRROR MODE 0.8 nozzle.json @@ -24,62 +24,92 @@ "125x500" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "200", + "200", "200", "200" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "200", + "200", "200", "200" ], "machine_max_acceleration_e": [ + "5000", + "5000", "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_retracting": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_travel": [ + "20000", + "20000", "20000", "20000" ], "machine_max_jerk_x": [ + "5", + "5", "5", "5" ], "machine_max_jerk_y": [ + "5", + "5", "5", "5" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], @@ -93,24 +123,31 @@ "extruder_clearance_height_to_rod": "25", "extruder_clearance_height_to_lid": "140", "retract_lift_below": [ + "0.2", "0.2" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_speed": [ + "120", "120" ], "deretraction_speed": [ + "120", "120" ], "wipe": [ + "1", "1" ], "retract_before_wipe": [ + "70%", "70%" ], "z_hop": [ + "0.2", "0.2" ], "machine_start_gcode": "G28\nIDEX_MIRROR\nSTART_PRINT EXTRUDER_TEMP={first_layer_temperature[0]},{first_layer_temperature[1]} EXTRUDER_OTHER_LAYER_TEMP={temperature[0]},{temperature[1]} BED_TEMP=[first_layer_bed_temperature] INITIAL_TOOL={initial_tool} TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}", diff --git a/resources/profiles/RolohaunDesign.json b/resources/profiles/RolohaunDesign.json index e0b7a33301..18eb9e4fc3 100644 --- a/resources/profiles/RolohaunDesign.json +++ b/resources/profiles/RolohaunDesign.json @@ -1,6 +1,6 @@ { "name": "RolohaunDesign", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "0", "description": "RolohaunDesign Printer Profiles", "machine_model_list": [ diff --git a/resources/profiles/RolohaunDesign/machine/Rolohaun Delta Flyer Refit 0.4 nozzle.json b/resources/profiles/RolohaunDesign/machine/Rolohaun Delta Flyer Refit 0.4 nozzle.json index f5c095918f..4637e5ad14 100644 --- a/resources/profiles/RolohaunDesign/machine/Rolohaun Delta Flyer Refit 0.4 nozzle.json +++ b/resources/profiles/RolohaunDesign/machine/Rolohaun Delta Flyer Refit 0.4 nozzle.json @@ -3,8 +3,8 @@ "name": "Rolohaun Delta Flyer Refit 0.4 nozzle", "inherits": "fdm_common_Rook MK1 LDO", "from": "system", - "instantiation": "true", "setting_id": "xRvK2POOU8rx7dLH", + "instantiation": "true", "bed_custom_model": "", "printer_structure": "delta", "deretraction_speed": [ diff --git a/resources/profiles/SecKit.json b/resources/profiles/SecKit.json index 91804bff0a..e4d4f91e80 100644 --- a/resources/profiles/SecKit.json +++ b/resources/profiles/SecKit.json @@ -1,6 +1,6 @@ { "name": "SecKit", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "SecKit configurations", "machine_model_list": [ diff --git a/resources/profiles/SecKit/filament/Generic ABS @SecKit.json b/resources/profiles/SecKit/filament/Generic ABS @SecKit.json index cdd9ce2f62..32db36b0fb 100644 --- a/resources/profiles/SecKit/filament/Generic ABS @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic ABS @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @SecKit", - "inherits": "fdm_filament_abs", "renamed_from": "SecKit Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "VSrXBQUNBQMwUc08", "filament_id": "OFY9muEs", diff --git a/resources/profiles/SecKit/filament/Generic ASA @SecKit.json b/resources/profiles/SecKit/filament/Generic ASA @SecKit.json index 366b20172b..7d48828374 100644 --- a/resources/profiles/SecKit/filament/Generic ASA @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic ASA @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @SecKit", - "inherits": "fdm_filament_asa", "renamed_from": "SecKit Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "usCYRq4VuLqXvb0T", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/SecKit/filament/Generic PA @SecKit.json b/resources/profiles/SecKit/filament/Generic PA @SecKit.json index 7746d8628a..0c3ac3a4c2 100644 --- a/resources/profiles/SecKit/filament/Generic PA @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PA @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @SecKit", - "inherits": "fdm_filament_pa", "renamed_from": "SecKit Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "uAuptETLwGxTsthC", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/SecKit/filament/Generic PA-CF @SecKit.json b/resources/profiles/SecKit/filament/Generic PA-CF @SecKit.json index 52c0bae450..0833f7c993 100644 --- a/resources/profiles/SecKit/filament/Generic PA-CF @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PA-CF @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @SecKit", - "inherits": "fdm_filament_pa", "renamed_from": "SecKit Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "P6G8DjjyfAFgGaj2", "filament_id": "OFQLcbps", diff --git a/resources/profiles/SecKit/filament/Generic PC @SecKit.json b/resources/profiles/SecKit/filament/Generic PC @SecKit.json index 689f3ea553..4d08959ca5 100644 --- a/resources/profiles/SecKit/filament/Generic PC @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PC @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @SecKit", - "inherits": "fdm_filament_pc", "renamed_from": "SecKit Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "PxmBHXsdhZGR9bYv", "filament_id": "OFLakOUI", diff --git a/resources/profiles/SecKit/filament/Generic PETG @SecKit.json b/resources/profiles/SecKit/filament/Generic PETG @SecKit.json index 05c5c753c6..2b2181c88d 100644 --- a/resources/profiles/SecKit/filament/Generic PETG @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PETG @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @SecKit", - "inherits": "fdm_filament_pet", "renamed_from": "SecKit Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "Qt4oXABB5Fukbz46", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/SecKit/filament/Generic PLA @SecKit.json b/resources/profiles/SecKit/filament/Generic PLA @SecKit.json index b3cd1c2ffc..7a87454000 100644 --- a/resources/profiles/SecKit/filament/Generic PLA @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PLA @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @SecKit", - "inherits": "fdm_filament_pla", "renamed_from": "SecKit Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "uWvI4RDQiYLFN7pp", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/SecKit/filament/Generic PLA-CF @SecKit.json b/resources/profiles/SecKit/filament/Generic PLA-CF @SecKit.json index 507716caee..d68c13d36b 100644 --- a/resources/profiles/SecKit/filament/Generic PLA-CF @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PLA-CF @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @SecKit", - "inherits": "fdm_filament_pla", "renamed_from": "SecKit Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "znagqvEsDcHYse9M", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/SecKit/filament/Generic PVA @SecKit.json b/resources/profiles/SecKit/filament/Generic PVA @SecKit.json index 13f7d50673..b149854c0e 100644 --- a/resources/profiles/SecKit/filament/Generic PVA @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic PVA @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @SecKit", - "inherits": "fdm_filament_pva", "renamed_from": "SecKit Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "DIUaGXpIF3fUfxqg", "filament_id": "OFDvXujf", diff --git a/resources/profiles/SecKit/filament/Generic TPU @SecKit.json b/resources/profiles/SecKit/filament/Generic TPU @SecKit.json index 96d9c38a60..d4e3952768 100644 --- a/resources/profiles/SecKit/filament/Generic TPU @SecKit.json +++ b/resources/profiles/SecKit/filament/Generic TPU @SecKit.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @SecKit", - "inherits": "fdm_filament_tpu", "renamed_from": "SecKit Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "agKm2K9w4ZOmZN8c", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/SeeMeCNC.json b/resources/profiles/SeeMeCNC.json index 21db5e4e3e..8bff5661ae 100644 --- a/resources/profiles/SeeMeCNC.json +++ b/resources/profiles/SeeMeCNC.json @@ -1,6 +1,6 @@ { "name": "SeeMeCNC", - "version": "2.4.0.05", + "version": "2.4.0.06", "force_update": "1", "description": "SeeMeCNC configurations - Full profile set for Artemis, BOSSdelta, and RostockMAX printers", "machine_model_list": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_4mm.json index 23ccc8cd08..6aabc9d4c3 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_5mm.json index f16bdf8620..9fb7eef8a8 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_7mm.json index 7bf1733799..f72a25c9cc 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_1_0mm.json index 68316ff085..098a6fcc49 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_Artemis_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_4mm.json index 4709989e11..d36eb598e8 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_5mm.json index a09599a118..b88111ae62 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_7mm.json index a045d6acb6..4c121f7906 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_1_0mm.json index 4fbdc6cdf0..06fdc03bd9 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0505_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_4mm.json index 1d40d2b7d8..d70145fc2a 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_5mm.json index f007e2c307..cf29664116 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_7mm.json index ae455b50bc..4e0388eacc 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_1_0mm.json index 28a865c33e..38d26bdf65 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0510_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_4mm.json index 6db1c32408..dd7e5b4e42 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_5mm.json index 0bba926946..727b56ffa1 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_7mm.json index 623edc7966..8eac323e8b 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_1_0mm.json index 9f1b324a3b..ecdda09652 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta500_0521_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_4mm.json index 51ca348ee2..7acf96a631 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_5mm.json index 78638f67ad..fe13b26823 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_7mm.json index d3d58505ed..3e898ebed7 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_1_0mm.json index c2ffdb20a0..f192d5c620 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_BOSSdelta_300_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_4mm.json index c53c7f7085..a883274039 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_5mm.json index 3e8b24699f..f9ae2d5ceb 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_7mm.json index d1fd58da56..e3f08f903f 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_1_0mm.json index 648c797d61..d8131eab5b 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v3.2_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_4mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_4mm.json index 39252fa29e..86febcf52a 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_4mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_4mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_5mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_5mm.json index f1dbfc5e2f..1ca829f83c 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_5mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_5mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_7mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_7mm.json index c7bce4faca..2a9320d542 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_7mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_0_7mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_1_0mm.json b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_1_0mm.json index f1ec174cf2..6213c30b3a 100644 --- a/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_1_0mm.json +++ b/resources/profiles/SeeMeCNC/machine/SeeMeCNC_RostockMAX_v4_1_0mm.json @@ -120,6 +120,7 @@ "15" ], "machine_max_junction_deviation": [ + "0.01", "0.01" ], "machine_max_speed_e": [ diff --git a/resources/profiles/Snapmaker.json b/resources/profiles/Snapmaker.json index 06acef0b0e..d13ed8bf21 100644 --- a/resources/profiles/Snapmaker.json +++ b/resources/profiles/Snapmaker.json @@ -1,6 +1,6 @@ { "name": "Snapmaker", - "version": "02.04.00.15", + "version": "02.04.00.16", "force_update": "0", "description": "Snapmaker configurations", "machine_model_list": [ diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json index 44125a8381..79305ab57e 100644 --- a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite Dual PLA @0.2 nozzle.json @@ -2,9 +2,9 @@ "type": "filament", "name": "PolyLite Dual PLA @0.2 nozzle", "inherits": "PolyLite PLA @0.2 nozzle", - "filament_id": "OFYGbPHX", "from": "system", "setting_id": "jhmy4YHi9MuL0DWu", + "filament_id": "OFYGbPHX", "instantiation": "true", "compatible_printers": [ "Snapmaker A250 Dual (0.2 nozzle)", diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json index 8e4075ccf7..f826452d55 100644 --- a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA @0.2 nozzle.json @@ -2,9 +2,9 @@ "type": "filament", "name": "PolyLite J1 PLA @0.2 nozzle", "inherits": "PolyLite PLA @0.2 nozzle", - "filament_id": "OF7SliVn", "from": "system", "setting_id": "jFlRSxx0KvN3BOUu", + "filament_id": "OF7SliVn", "instantiation": "true", "compatible_printers": [ "Snapmaker J1 (0.2 nozzle)" diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json index 0bbce7eec8..14a97da12f 100644 --- a/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json +++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyLite J1 PLA.json @@ -2,9 +2,9 @@ "type": "filament", "name": "PolyLite J1 PLA", "inherits": "PolyLite PLA @base", - "filament_id": "OF7SliVn", "from": "system", "setting_id": "wcpOTTMyZNPFKyXr", + "filament_id": "OF7SliVn", "instantiation": "true", "compatible_printers": [ "Snapmaker J1 (0.4 nozzle)", diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json index 1f28bcfac6..b8796ad051 100644 --- a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra Dual PLA @0.2 nozzle.json @@ -2,9 +2,9 @@ "type": "filament", "name": "PolyTerra Dual PLA @0.2 nozzle", "inherits": "PolyTerra PLA @0.2 nozzle", - "filament_id": "OFCccVrQ", "from": "system", "setting_id": "UQYgjH1uVxf3d2Nv", + "filament_id": "OFCccVrQ", "instantiation": "true", "compatible_printers": [ "Snapmaker A250 Dual (0.2 nozzle)", diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json index 6e424a84d3..4493bd50f6 100644 --- a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA @0.2 nozzle.json @@ -2,9 +2,9 @@ "type": "filament", "name": "PolyTerra J1 PLA @0.2 nozzle", "inherits": "PolyTerra PLA @0.2 nozzle", - "filament_id": "OF43Raws", "from": "system", "setting_id": "mxKHxGmBZzPLS82O", + "filament_id": "OF43Raws", "instantiation": "true", "compatible_printers": [ "Snapmaker J1 (0.2 nozzle)" diff --git a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json index 55fb74f4f7..58e6989223 100644 --- a/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json +++ b/resources/profiles/Snapmaker/filament/Polymaker/PolyTerra J1 PLA.json @@ -2,9 +2,9 @@ "type": "filament", "name": "PolyTerra J1 PLA", "inherits": "PolyTerra PLA @base", - "filament_id": "OF43Raws", "from": "system", "setting_id": "4MZWZX7QPBzxdEGj", + "filament_id": "OF43Raws", "instantiation": "true", "compatible_printers": [ "Snapmaker J1 (0.4 nozzle)", diff --git a/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.2 nozzle.json b/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.2 nozzle.json index f1c3aa30a1..9d9e3918cf 100644 --- a/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.2 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.2 nozzle.json @@ -5,20 +5,19 @@ "from": "system", "setting_id": "Ujul2YTBwfldFiFd", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ - "1", "1" ], "filament_ramming_travel_time": [ - "0", "0" ], "long_retractions_when_ec": [ - "0", "0" ], "retraction_distances_when_ec": [ - "0", "0" ], "compatible_printers": [ diff --git a/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.6 nozzle.json b/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.6 nozzle.json index 66a535b7fb..985505a027 100644 --- a/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.6 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.6 nozzle.json @@ -5,16 +5,16 @@ "from": "system", "setting_id": "2FfQZdp5xunngnF0", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_ramming_travel_time": [ - "0", "0" ], "long_retractions_when_ec": [ - "0", "0" ], "retraction_distances_when_ec": [ - "0", "0" ], "compatible_printers": [ diff --git a/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.8 nozzle.json b/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.8 nozzle.json index 04446a623e..83c1b17971 100644 --- a/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.8 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Snapmaker PETG HF @U1 0.8 nozzle.json @@ -5,16 +5,16 @@ "from": "system", "setting_id": "ebANa67V4B2nwUaX", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_ramming_travel_time": [ - "0", "0" ], "long_retractions_when_ec": [ - "0", "0" ], "retraction_distances_when_ec": [ - "0", "0" ], "compatible_printers": [ diff --git a/resources/profiles/Snapmaker/filament/Snapmaker PLA-CF @U1 0.4 nozzle.json b/resources/profiles/Snapmaker/filament/Snapmaker PLA-CF @U1 0.4 nozzle.json index 9ce38a9782..357c5de50a 100644 --- a/resources/profiles/Snapmaker/filament/Snapmaker PLA-CF @U1 0.4 nozzle.json +++ b/resources/profiles/Snapmaker/filament/Snapmaker PLA-CF @U1 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "Snapmaker PLA-CF @U1 0.4 nozzle", + "renamed_from": "Snapmaker PLA-CF @U1", "inherits": "fdm_filament_pla", "from": "system", - "renamed_from": "Snapmaker PLA-CF @U1", "setting_id": "2INwruC3ZVkBTdUT", "filament_id": "OFhQf8ou", "instantiation": "true", diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json index 183e125c73..674b82930c 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.2 nozzle).json @@ -36,14 +36,32 @@ ], "machine_end_gcode": ";===== date: 20260605 =====================\n; layer [layer_num]\n; max_layer_z [max_layer_z]\n; print_sequence [print_sequence]\n\n{if print_sequence == \"by object\"}\n{\nlocal move_z = max_print_height;\n\nif max_layer_z < ((max_print_height - z_offset) - 2) then\n move_z = z_offset + min(((max_layer_z - z_offset) + 2), max_print_height);\nendif\n}\n\nG91\nG1 X2 Y2 Z1 F24000\nG90\nG1 Z{move_z} F600\n{endif}\n\nPRINT_END\nTIMELAPSE_STOP\n", "machine_max_jerk_z": [ + "3", + "0.4", + "3", + "0.4", + "3", + "0.4", "3", "0.4" ], "machine_max_speed_e": [ + "30", + "25", + "30", + "25", + "30", + "25", "30", "25" ], "machine_max_speed_z": [ + "20", + "12", + "20", + "12", + "20", + "12", "20", "12" ], @@ -67,7 +85,12 @@ "0.2", "0.2" ], - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], "printable_area": [ "0.5x1", "270.5x1", @@ -185,7 +208,12 @@ "machine_unload_filament_time": "0", "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME\nDEFECT_DETECTION_DETECT", "machine_pause_gcode": "M600", - "nozzle_volume": "143", + "nozzle_volume": [ + "143", + "143", + "143", + "143" + ], "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", "default_print_profile": "0.10 Standard @Snapmaker U1 (0.2 nozzle)" } diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json index 6d2ec2cfe6..3acd21c2dd 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json @@ -36,14 +36,32 @@ ], "machine_end_gcode": ";===== date: 20260605 =====================\n; layer [layer_num]\n; max_layer_z [max_layer_z]\n; print_sequence [print_sequence]\n\n{if print_sequence == \"by object\"}\n{\nlocal move_z = max_print_height;\n\nif max_layer_z < ((max_print_height - z_offset) - 2) then\n move_z = z_offset + min(((max_layer_z - z_offset) + 2), max_print_height);\nendif\n}\n\nG91\nG1 X2 Y2 Z1 F24000\nG90\nG1 Z{move_z} F600\n{endif}\n\nPRINT_END\nTIMELAPSE_STOP\n", "machine_max_jerk_z": [ + "3", + "0.4", + "3", + "0.4", + "3", + "0.4", "3", "0.4" ], "machine_max_speed_e": [ + "30", + "25", + "30", + "25", + "30", + "25", "30", "25" ], "machine_max_speed_z": [ + "20", + "12", + "20", + "12", + "20", + "12", "20", "12" ], @@ -67,7 +85,12 @@ "0.4", "0.4" ], - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], "printable_area": [ "0.5x1", "270.5x1", @@ -187,7 +210,12 @@ "default_print_profile": "0.20 Standard @Snapmaker U1 (0.4 nozzle)", "machine_pause_gcode": "M600", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", - "nozzle_volume": "143", + "nozzle_volume": [ + "143", + "143", + "143", + "143" + ], "resonance_avoidance": "1", "min_resonance_avoidance_speed": "40", "max_resonance_avoidance_speed": "90" diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4+0.6 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4+0.6 nozzle).json index c9866329bd..cc4e7a0515 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4+0.6 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4+0.6 nozzle).json @@ -26,5 +26,10 @@ "0.6", "0.6" ], - "nozzle_type": "stainless_steel" + "nozzle_type": [ + "stainless_steel", + "stainless_steel", + "stainless_steel", + "stainless_steel" + ] } diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json index a6cb0d0bd3..98b6f7e683 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.6 nozzle).json @@ -36,14 +36,32 @@ ], "machine_end_gcode": ";===== date: 20260605 =====================\n; layer [layer_num]\n; max_layer_z [max_layer_z]\n; print_sequence [print_sequence]\n\n{if print_sequence == \"by object\"}\n{\nlocal move_z = max_print_height;\n\nif max_layer_z < ((max_print_height - z_offset) - 2) then\n move_z = z_offset + min(((max_layer_z - z_offset) + 2), max_print_height);\nendif\n}\n\nG91\nG1 X2 Y2 Z1 F24000\nG90\nG1 Z{move_z} F600\n{endif}\n\nPRINT_END\nTIMELAPSE_STOP\n", "machine_max_jerk_z": [ + "3", + "0.4", + "3", + "0.4", + "3", + "0.4", "3", "0.4" ], "machine_max_speed_e": [ + "30", + "25", + "30", + "25", + "30", + "25", "30", "25" ], "machine_max_speed_z": [ + "20", + "12", + "20", + "12", + "20", + "12", "20", "12" ], @@ -67,7 +85,12 @@ "0.6", "0.6" ], - "nozzle_type": "stainless_steel", + "nozzle_type": [ + "stainless_steel", + "stainless_steel", + "stainless_steel", + "stainless_steel" + ], "printable_area": [ "0.5x1", "270.5x1", @@ -186,6 +209,11 @@ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME\nDEFECT_DETECTION_DETECT", "machine_pause_gcode": "M600", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", - "nozzle_volume": "143", + "nozzle_volume": [ + "143", + "143", + "143", + "143" + ], "default_print_profile": "0.30 Standard @Snapmaker U1 (0.6 nozzle)" } diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json index ef4da1a516..6ab566e0aa 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.8 nozzle).json @@ -36,14 +36,32 @@ ], "machine_end_gcode": ";===== date: 20260605 =====================\n; layer [layer_num]\n; max_layer_z [max_layer_z]\n; print_sequence [print_sequence]\n\n{if print_sequence == \"by object\"}\n{\nlocal move_z = max_print_height;\n\nif max_layer_z < ((max_print_height - z_offset) - 2) then\n move_z = z_offset + min(((max_layer_z - z_offset) + 2), max_print_height);\nendif\n}\n\nG91\nG1 X2 Y2 Z1 F24000\nG90\nG1 Z{move_z} F600\n{endif}\n\nPRINT_END\nTIMELAPSE_STOP\n", "machine_max_jerk_z": [ + "3", + "0.4", + "3", + "0.4", + "3", + "0.4", "3", "0.4" ], "machine_max_speed_e": [ + "30", + "25", + "30", + "25", + "30", + "25", "30", "25" ], "machine_max_speed_z": [ + "20", + "12", + "20", + "12", + "20", + "12", "20", "12" ], @@ -67,7 +85,12 @@ "0.8", "0.8" ], - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], "printable_area": [ "0.5x1", "270.5x1", @@ -186,6 +209,11 @@ "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME\nDEFECT_DETECTION_DETECT", "machine_pause_gcode": "M600", "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER={layer_num+1}", - "nozzle_volume": "143", + "nozzle_volume": [ + "143", + "143", + "143", + "143" + ], "default_print_profile": "0.40 Standard @Snapmaker U1 (0.8 nozzle)" } diff --git a/resources/profiles/Sovol.json b/resources/profiles/Sovol.json index 81dab20239..1b30ae4143 100644 --- a/resources/profiles/Sovol.json +++ b/resources/profiles/Sovol.json @@ -1,7 +1,7 @@ { "name": "Sovol", "url": "", - "version": "02.04.00.07", + "version": "02.04.00.08", "force_update": "0", "description": "Sovol configurations", "machine_model_list": [ diff --git a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 ACE.json b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 ACE.json index 49b26d498a..67e7edc5b0 100644 --- a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 ACE.json +++ b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic ABS @Sovol SV06 ACE", - "inherits": "Generic ABS @System", "renamed_from": "Sovol SV06 ACE ABS", + "inherits": "Generic ABS @System", "from": "system", "setting_id": "exjBdPPCgk53gipu", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 Plus ACE.json b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 Plus ACE.json index 905ee2bda0..2ea4473855 100644 --- a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 Plus ACE.json +++ b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV06 Plus ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic ABS @Sovol SV06 Plus ACE", - "inherits": "Generic ABS @System", "renamed_from": "Sovol SV06 Plus ACE ABS", + "inherits": "Generic ABS @System", "from": "system", "setting_id": "sg9HXvKEoKD4pw7v", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08 MAX.json index 8532e5bee0..5c5e0353dd 100644 --- a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08 MAX.json @@ -1,10 +1,13 @@ { "type": "filament", - "setting_id": "7julgReKEcp5tg0d", "name": "Generic ABS @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic ABS @System", + "from": "system", + "setting_id": "7julgReKEcp5tg0d", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08.json b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08.json index e690ee88e5..204288affc 100644 --- a/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08.json +++ b/resources/profiles/Sovol/filament/Generic ABS @Sovol SV08.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic ABS @Sovol SV08", - "inherits": "Generic ABS @System", "renamed_from": "Sovol SV08 ABS", + "inherits": "Generic ABS @System", "from": "system", "setting_id": "aZx3ePr3Id1jPJG9", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PC @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Generic PC @Sovol SV08 MAX.json index 242c320a7d..4df49482b1 100644 --- a/resources/profiles/Sovol/filament/Generic PC @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Generic PC @Sovol SV08 MAX.json @@ -1,10 +1,13 @@ { "type": "filament", - "setting_id": "UPoqjanrvN173sVS", "name": "Generic PC @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic PC @System", + "from": "system", + "setting_id": "UPoqjanrvN173sVS", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PC @Sovol Zero.json b/resources/profiles/Sovol/filament/Generic PC @Sovol Zero.json index 832deb1368..ad8e26864c 100644 --- a/resources/profiles/Sovol/filament/Generic PC @Sovol Zero.json +++ b/resources/profiles/Sovol/filament/Generic PC @Sovol Zero.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFLakOUI", - "setting_id": "yRKCiPMN6fxibcyg", "name": "Generic PC @Sovol Zero", "renamed_from": "Sovol Zero PC", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pc", + "from": "system", + "setting_id": "yRKCiPMN6fxibcyg", + "filament_id": "OFLakOUI", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 ACE.json b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 ACE.json index acb2c90316..31097dc51f 100644 --- a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 ACE.json +++ b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PETG @Sovol SV06 ACE", - "inherits": "Generic PETG @System", "renamed_from": "Sovol SV06 ACE PETG", + "inherits": "Generic PETG @System", "from": "system", "setting_id": "p8fGWNVkT6n5Dv9P", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 Plus ACE.json b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 Plus ACE.json index 5c2dfeff98..11188b88a4 100644 --- a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 Plus ACE.json +++ b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV06 Plus ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PETG @Sovol SV06 Plus ACE", - "inherits": "Generic PETG @System", "renamed_from": "Sovol SV06 Plus ACE PETG", + "inherits": "Generic PETG @System", "from": "system", "setting_id": "I7IzLMYw7iDUUJwc", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08 MAX.json index 550d30ccf5..08de72fcce 100644 --- a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08 MAX.json @@ -1,10 +1,13 @@ { "type": "filament", - "setting_id": "ib7AtR3tQ2dSrFNP", "name": "Generic PETG @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG @System", + "from": "system", + "setting_id": "ib7AtR3tQ2dSrFNP", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08.json b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08.json index c637897b10..4e9335e97b 100644 --- a/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08.json +++ b/resources/profiles/Sovol/filament/Generic PETG @Sovol SV08.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PETG @Sovol SV08", - "inherits": "Generic PETG @System", "renamed_from": "Sovol SV08 PETG", + "inherits": "Generic PETG @System", "from": "system", "setting_id": "7vDZKIKJW5fy1EGG", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero Hardened Steel nozzle.json b/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero Hardened Steel nozzle.json index ef6a6324e3..1ea9ae00e6 100644 --- a/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero Hardened Steel nozzle.json +++ b/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero Hardened Steel nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFYPdQJh", - "setting_id": "d9QbCESNz3ZLU6eu", "name": "Generic PETG @Sovol Zero Hardened Steel nozzle", "renamed_from": "Sovol Zero PETG HS Nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "d9QbCESNz3ZLU6eu", + "filament_id": "OFYPdQJh", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero.json b/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero.json index b9632637ad..5972184f6c 100644 --- a/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero.json +++ b/resources/profiles/Sovol/filament/Generic PETG @Sovol Zero.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFYPdQJh", - "setting_id": "i4OW2eAtXOKdtVNj", "name": "Generic PETG @Sovol Zero", "renamed_from": "Sovol Zero PETG", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "i4OW2eAtXOKdtVNj", + "filament_id": "OFYPdQJh", + "instantiation": "true", "filament_flow_ratio": [ "1.0348" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 ACE.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 ACE.json index de9e7cde47..41751ee0ad 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 ACE.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA @Sovol SV06 ACE", - "inherits": "Generic PLA @System", "renamed_from": "Sovol SV06 ACE PLA", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "UEEwpetmmxpxM4vV", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 Plus ACE.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 Plus ACE.json index 8dcb4a6d2d..8b08b7ad57 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 Plus ACE.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV06 Plus ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA @Sovol SV06 Plus ACE", - "inherits": "Generic PLA @System", "renamed_from": "Sovol SV06 Plus ACE PLA", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "yzv5Kwe3OivHxNUI", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV07.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV07.json index 42210ef9c0..934a9efe2d 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV07.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV07.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA @Sovol SV07", - "inherits": "Generic PLA @System", "renamed_from": "Sovol SV07 PLA", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "sNGno8XCSsgmwjvH", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 0.2 nozzle.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 0.2 nozzle.json index be23b183ab..4a28282063 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 0.2 nozzle.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 0.2 nozzle.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA @Sovol SV08 0.2 nozzle", - "inherits": "Generic PLA @System", "renamed_from": "Sovol SV08 PLA @SV08 0.2 nozzle;Sovol SV08 PLA SV08 0.2 nozzle", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "W7oQNGWqiPMUlzhw", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 MAX.json index b29bc1b069..d0428319af 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08 MAX.json @@ -1,10 +1,13 @@ { "type": "filament", - "setting_id": "kcFykpuuxMy7KwNu", "name": "Generic PLA @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA @System", + "from": "system", + "setting_id": "kcFykpuuxMy7KwNu", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08.json index c124edee31..12668251e9 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol SV08.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic PLA @Sovol SV08", - "inherits": "Generic PLA @System", "renamed_from": "Sovol SV08 PLA", + "inherits": "Generic PLA @System", "from": "system", "setting_id": "4fSYcvbFXNRHnlEw", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero Hardened Steel nozzle.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero Hardened Steel nozzle.json index bba0cbfb51..776452aed8 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero Hardened Steel nozzle.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero Hardened Steel nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFDSrzZ8", - "setting_id": "nZgETe4CTpicEjQX", "name": "Generic PLA @Sovol Zero Hardened Steel nozzle", "renamed_from": "Sovol Zero PLA Basic HS Nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "nZgETe4CTpicEjQX", + "filament_id": "OFDSrzZ8", + "instantiation": "true", "filament_flow_ratio": [ "1.0348" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero.json b/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero.json index c8424af4f4..e3f4b92ac9 100644 --- a/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero.json +++ b/resources/profiles/Sovol/filament/Generic PLA @Sovol Zero.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFDSrzZ8", - "setting_id": "NNDerIjh7qtuh1I3", "name": "Generic PLA @Sovol Zero", "renamed_from": "Sovol Zero PLA Basic", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "NNDerIjh7qtuh1I3", + "filament_id": "OFDSrzZ8", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA SPEEDBENCHY @Sovol Zero.json b/resources/profiles/Sovol/filament/Generic PLA SPEEDBENCHY @Sovol Zero.json index a9aefc6bd2..c55bf2516d 100644 --- a/resources/profiles/Sovol/filament/Generic PLA SPEEDBENCHY @Sovol Zero.json +++ b/resources/profiles/Sovol/filament/Generic PLA SPEEDBENCHY @Sovol Zero.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFIUkWYN", - "setting_id": "MC2InZ7iKDjIGike", "name": "Generic PLA SPEEDBENCHY @Sovol Zero", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "MC2InZ7iKDjIGike", + "filament_id": "OFIUkWYN", + "instantiation": "true", "filament_flow_ratio": [ "1" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol SV08 MAX.json index ac456a82ee..f3e1e1cd82 100644 --- a/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol SV08 MAX.json @@ -1,11 +1,14 @@ { "type": "filament", - "filament_id": "OFesA6rF", - "setting_id": "WAHQZmwHoS4WjoTx", "name": "Generic PLA Silk @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic PLA @System", + "from": "system", + "setting_id": "WAHQZmwHoS4WjoTx", + "filament_id": "OFesA6rF", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero Hardened Steel nozzle.json b/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero Hardened Steel nozzle.json index 7347fa08de..52ecbd08de 100644 --- a/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero Hardened Steel nozzle.json +++ b/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero Hardened Steel nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFesA6rF", - "setting_id": "LA8X1RsMdV2xNT1o", "name": "Generic PLA Silk @Sovol Zero Hardened Steel nozzle", "renamed_from": "Sovol Zero PLA Silk HS Nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "LA8X1RsMdV2xNT1o", + "filament_id": "OFesA6rF", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero.json b/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero.json index 6c9c27a00a..ecbebcfc40 100644 --- a/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero.json +++ b/resources/profiles/Sovol/filament/Generic PLA Silk @Sovol Zero.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFesA6rF", - "setting_id": "Se2yKerHRStYtWf5", "name": "Generic PLA Silk @Sovol Zero", "renamed_from": "Sovol Zero PLA Silk", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "Se2yKerHRStYtWf5", + "filament_id": "OFesA6rF", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 ACE.json b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 ACE.json index ba653af37d..e588e91bc2 100644 --- a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 ACE.json +++ b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic TPU @Sovol SV06 ACE", - "inherits": "Generic TPU @System", "renamed_from": "Sovol SV06 ACE TPU", + "inherits": "Generic TPU @System", "from": "system", "setting_id": "jBAo7stLaaQxKFsp", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 Plus ACE.json b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 Plus ACE.json index 9c9490b863..311724601e 100644 --- a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 Plus ACE.json +++ b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV06 Plus ACE.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic TPU @Sovol SV06 Plus ACE", - "inherits": "Generic TPU @System", "renamed_from": "Sovol SV06 Plus ACE TPU", + "inherits": "Generic TPU @System", "from": "system", "setting_id": "MUXz0JSHdT66Mti1", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08 MAX.json index a65978a50e..fd3891ff9c 100644 --- a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08 MAX.json @@ -1,10 +1,13 @@ { "type": "filament", - "setting_id": "hQByQ7FIhAiytli8", "name": "Generic TPU @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic TPU @System", + "from": "system", + "setting_id": "hQByQ7FIhAiytli8", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08.json b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08.json index bf412d77d8..d8cbcf07b7 100644 --- a/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08.json +++ b/resources/profiles/Sovol/filament/Generic TPU @Sovol SV08.json @@ -1,11 +1,14 @@ { "type": "filament", "name": "Generic TPU @Sovol SV08", - "inherits": "Generic TPU @System", "renamed_from": "Sovol SV08 TPU", + "inherits": "Generic TPU @System", "from": "system", "setting_id": "vFPYMoNvgjn1aSKA", "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Generic TPU @Sovol Zero.json b/resources/profiles/Sovol/filament/Generic TPU @Sovol Zero.json index 8624043cf9..fb21ee721b 100644 --- a/resources/profiles/Sovol/filament/Generic TPU @Sovol Zero.json +++ b/resources/profiles/Sovol/filament/Generic TPU @Sovol Zero.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFgbpcy9", - "setting_id": "MlY6WQ41FE8zDPSV", "name": "Generic TPU @Sovol Zero", "renamed_from": "Sovol Zero TPU", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "MlY6WQ41FE8zDPSV", + "filament_id": "OFgbpcy9", + "instantiation": "true", "filament_flow_ratio": [ "0.98" ], diff --git a/resources/profiles/Sovol/filament/Polymaker PETG @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/Polymaker PETG @Sovol SV08 MAX.json index f56ca13525..f45ddf38f5 100644 --- a/resources/profiles/Sovol/filament/Polymaker PETG @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/Polymaker PETG @Sovol SV08 MAX.json @@ -1,11 +1,14 @@ { "type": "filament", - "filament_id": "OF6H51Xx", - "setting_id": "JBFKMaFtd7kO8Ksq", "name": "Polymaker PETG @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG @System", + "from": "system", + "setting_id": "JBFKMaFtd7kO8Ksq", + "filament_id": "OF6H51Xx", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "Polymaker" ], diff --git a/resources/profiles/Sovol/filament/SUNLU PETG @Sovol SV08 MAX.json b/resources/profiles/Sovol/filament/SUNLU PETG @Sovol SV08 MAX.json index 1ff8f57fac..6512adc3b8 100644 --- a/resources/profiles/Sovol/filament/SUNLU PETG @Sovol SV08 MAX.json +++ b/resources/profiles/Sovol/filament/SUNLU PETG @Sovol SV08 MAX.json @@ -1,11 +1,14 @@ { "type": "filament", - "filament_id": "OF2GCW1l", - "setting_id": "x68SPQCqVacBSGd5", "name": "SUNLU PETG @Sovol SV08 MAX", - "from": "system", - "instantiation": "true", "inherits": "Generic PETG @System", + "from": "system", + "setting_id": "x68SPQCqVacBSGd5", + "filament_id": "OF2GCW1l", + "instantiation": "true", + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_vendor": [ "SUNLU" ], diff --git a/resources/profiles/Sovol/machine/Sovol SV01 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV01 0.4 nozzle.json index fe6d0dcd96..234b872dc3 100644 --- a/resources/profiles/Sovol/machine/Sovol SV01 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV01 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "OrYBz2bwPIXQ0QZa", "name": "Sovol SV01 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "OrYBz2bwPIXQ0QZa", + "instantiation": "true", "printer_model": "Sovol SV01", "default_print_profile": "0.20mm Standard @Sovol SV01", "nozzle_diameter": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV02 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV02 0.4 nozzle.json index 65f382b90e..50197d701e 100644 --- a/resources/profiles/Sovol/machine/Sovol SV02 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV02 0.4 nozzle.json @@ -26,65 +26,98 @@ "0x240" ], "printable_height": "300", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "machine_max_acceleration_extruding": [ + "500", + "500", "500", "500" ], "machine_max_acceleration_retracting": [ + "1000", + "1000", "1000", "1000" ], "machine_max_acceleration_travel": [ + "1500", + "1250", "1500", "1250" ], "machine_max_acceleration_x": [ + "500", + "500", "500", "500" ], "machine_max_acceleration_y": [ + "500", + "500", "500", "500" ], "machine_max_acceleration_z": [ + "100", + "100", "100", "100" ], "machine_max_speed_e": [ + "60", + "60", "60", "60" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "10", + "10", "10", "10" ], "machine_max_jerk_e": [ + "5", + "5", "5", "5" ], "machine_max_jerk_x": [ + "8", + "8", "8", "8" ], "machine_max_jerk_y": [ + "8", + "8", "8", "8" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], "machine_max_junction_deviation": [ + "0.06", + "0", "0.06", "0" ], diff --git a/resources/profiles/Sovol/machine/Sovol SV06 0.4 High-Speed nozzle.json b/resources/profiles/Sovol/machine/Sovol SV06 0.4 High-Speed nozzle.json index 32726c753f..90d6ceb677 100644 --- a/resources/profiles/Sovol/machine/Sovol SV06 0.4 High-Speed nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV06 0.4 High-Speed nozzle.json @@ -69,7 +69,6 @@ "10" ], "z_hop": [ - "0.4", "0.4" ], "max_layer_height": [ @@ -77,35 +76,34 @@ "0.32" ], "retract_lift_below": [ - "248", "248" ], "retraction_speed": [ - "35", "35" ], "deretraction_speed": [ - "35", "35" ], "wipe_distance": [ - "2", "2" ], "retract_length_toolchange": [ - "1", "1" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "5", "5" ], "machine_max_jerk_y": [ + "5", "5" ], "machine_max_jerk_z": [ + "0.4", "0.4" ], "before_layer_change_gcode": "TIMELAPSE_TAKE_FRAME\nG92 E0", diff --git a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.2 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.2 nozzle.json index 329a91b001..da36449a58 100644 --- a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.2 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.2 nozzle.json @@ -85,15 +85,12 @@ "0.16" ], "retract_lift_below": [ - "248", "248" ], "retraction_speed": [ - "35", "35" ], "deretraction_speed": [ - "35", "35" ], "wipe_distance": [ @@ -103,19 +100,22 @@ "100%" ], "retract_length_toolchange": [ - "2", "2" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "gcode_flavor": "klipper", diff --git a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.4 nozzle.json index c9f054af98..7cb3e5e232 100644 --- a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.4 nozzle.json @@ -85,15 +85,12 @@ "0.32" ], "retract_lift_below": [ - "248", "248" ], "retraction_speed": [ - "40", "40" ], "deretraction_speed": [ - "40", "40" ], "wipe_distance": [ @@ -103,19 +100,22 @@ "100%" ], "retract_length_toolchange": [ - "2", "2" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "gcode_flavor": "klipper", diff --git a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.6 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.6 nozzle.json index e7bc84ee1a..53068f8999 100644 --- a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.6 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.6 nozzle.json @@ -85,15 +85,12 @@ "0.48" ], "retract_lift_below": [ - "248", "248" ], "retraction_speed": [ - "45", "45" ], "deretraction_speed": [ - "45", "45" ], "wipe_distance": [ @@ -103,19 +100,22 @@ "100%" ], "retract_length_toolchange": [ - "2", "2" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "gcode_flavor": "klipper", diff --git a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.8 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.8 nozzle.json index 6c555ef1d5..49c6077ee8 100644 --- a/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.8 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV06 ACE 0.8 nozzle.json @@ -85,15 +85,12 @@ "0.64" ], "retract_lift_below": [ - "248", "248" ], "retraction_speed": [ - "45", "45" ], "deretraction_speed": [ - "45", "45" ], "wipe_distance": [ @@ -103,19 +100,22 @@ "100%" ], "retract_length_toolchange": [ - "2", "2" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "gcode_flavor": "klipper", diff --git a/resources/profiles/Sovol/machine/Sovol SV06 Plus ACE 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV06 Plus ACE 0.4 nozzle.json index 5624a3c07f..80053de960 100644 --- a/resources/profiles/Sovol/machine/Sovol SV06 Plus ACE 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV06 Plus ACE 0.4 nozzle.json @@ -83,15 +83,12 @@ "0.32" ], "retract_lift_below": [ - "343", "343" ], "retraction_speed": [ - "40", "40" ], "deretraction_speed": [ - "40", "40" ], "wipe_distance": [ @@ -101,19 +98,22 @@ "100%" ], "retract_length_toolchange": [ - "2", "2" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "gcode_flavor": "klipper", diff --git a/resources/profiles/Sovol/machine/Sovol SV07 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV07 0.4 nozzle.json index 513c7a3bca..dc8d999f2e 100644 --- a/resources/profiles/Sovol/machine/Sovol SV07 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV07 0.4 nozzle.json @@ -25,45 +25,59 @@ "0.8" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_x": [ + "12000", "12000" ], "machine_max_acceleration_y": [ + "12000", "12000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_jerk_x": [ + "9", "9" ], "machine_max_jerk_y": [ + "9", "9" ], "machine_max_jerk_z": [ + "0.25", "0.25" ], "machine_max_jerk_e": [ + "3", "3" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV07 Plus 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV07 Plus 0.4 nozzle.json index ef7b6f4986..7981ef6055 100644 --- a/resources/profiles/Sovol/machine/Sovol SV07 Plus 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV07 Plus 0.4 nozzle.json @@ -20,6 +20,7 @@ "nozzle_type": "undefine", "auxiliary_fan": "0", "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 0.2 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 0.2 nozzle.json index 441616c542..c28b90b27f 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 0.2 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 0.2 nozzle.json @@ -32,48 +32,63 @@ "0.5" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "700", "700" ], "machine_max_speed_y": [ + "700", "700" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 0.4 nozzle.json index 7defca131b..8997656a21 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 0.4 nozzle.json @@ -26,48 +26,63 @@ "0.5" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "700", "700" ], "machine_max_speed_y": [ + "700", "700" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 0.6 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 0.6 nozzle.json index d49594b4af..1cdf784b99 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 0.6 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 0.6 nozzle.json @@ -32,48 +32,63 @@ "0.5" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "700", "700" ], "machine_max_speed_y": [ + "700", "700" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 0.8 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 0.8 nozzle.json index 576ca16076..e79d65fb55 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 0.8 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 0.8 nozzle.json @@ -32,48 +32,63 @@ "0.5" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "700", "700" ], "machine_max_speed_y": [ + "700", "700" ], "machine_max_speed_z": [ + "20", "20" ], "machine_max_acceleration_e": [ + "5000", "5000" ], "machine_max_acceleration_extruding": [ + "20000", "20000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.4 nozzle.json index d71e6b448b..4c90815729 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "MIHp3VCfT1e6gMjs", "name": "Sovol SV08 MAX 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "MIHp3VCfT1e6gMjs", + "instantiation": "true", "printer_model": "Sovol SV08 MAX", "default_print_profile": "0.20mm Standard @Sovol SV08 MAX 0.4 nozzle", "printer_variant": "0.4", @@ -27,48 +27,63 @@ "0.8" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "800", "800" ], "machine_max_speed_y": [ + "800", "800" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "2.5", "2.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.6 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.6 nozzle.json index 4972eee589..53e2873472 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.6 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "HR1xTYrAmc07KHs0", "name": "Sovol SV08 MAX 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "HR1xTYrAmc07KHs0", + "instantiation": "true", "printer_model": "Sovol SV08 MAX", "default_print_profile": "0.30mm Standard @Sovol SV08 MAX 0.6 nozzle", "printer_variant": "0.6", @@ -36,48 +36,63 @@ "0.1" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "800", "800" ], "machine_max_speed_y": [ + "800", "800" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "2.5", "2.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.8 nozzle.json b/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.8 nozzle.json index 32511e52ca..764eb801d2 100644 --- a/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.8 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol SV08 MAX 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "8WhF31wX3mBoOqpx", "name": "Sovol SV08 MAX 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "8WhF31wX3mBoOqpx", + "instantiation": "true", "printer_model": "Sovol SV08 MAX", "default_print_profile": "0.40mm Standard @Sovol SV08 MAX 0.8 nozzle", "printer_variant": "0.8", @@ -36,48 +36,63 @@ "0.1" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "800", "800" ], "machine_max_speed_y": [ + "800", "800" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "20", "20" ], "machine_max_jerk_y": [ + "20", "20" ], "machine_max_jerk_z": [ + "2.5", "2.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol Zero 0.2 nozzle.json b/resources/profiles/Sovol/machine/Sovol Zero 0.2 nozzle.json index 33fb16508a..8b31824f86 100644 --- a/resources/profiles/Sovol/machine/Sovol Zero 0.2 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol Zero 0.2 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "MAF2n6b8uoY92qVH", "name": "Sovol Zero 0.2 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "MAF2n6b8uoY92qVH", + "instantiation": "true", "printer_model": "Sovol Zero", "default_print_profile": "0.10mm Standard @Sovol Zero 0.2 nozzle", "printer_variant": "0.2", @@ -32,48 +32,63 @@ "1.8" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "1200", "1200" ], "machine_max_speed_y": [ + "1200", "1200" ], "machine_max_speed_z": [ + "30", "30" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "20000", "20000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "1000", "1000" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "5", "5" ], "machine_max_jerk_y": [ + "5", "5" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol Zero 0.4 nozzle.json b/resources/profiles/Sovol/machine/Sovol Zero 0.4 nozzle.json index 932c5b9121..5ff3a25bb5 100644 --- a/resources/profiles/Sovol/machine/Sovol Zero 0.4 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol Zero 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "QclEa2nmpBiii6Y0", "name": "Sovol Zero 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "QclEa2nmpBiii6Y0", + "instantiation": "true", "printer_model": "Sovol Zero", "default_print_profile": "0.20mm Standard @Sovol Zero 0.4 nozzle", "printer_variant": "0.4", @@ -32,48 +32,63 @@ "1.8" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "1200", "1200" ], "machine_max_speed_y": [ + "1200", "1200" ], "machine_max_speed_z": [ + "30", "30" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "20000", "20000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "1000", "1000" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "5", "5" ], "machine_max_jerk_y": [ + "5", "5" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol Zero 0.6 nozzle.json b/resources/profiles/Sovol/machine/Sovol Zero 0.6 nozzle.json index e2cfc7ccc5..6fe78791d5 100644 --- a/resources/profiles/Sovol/machine/Sovol Zero 0.6 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol Zero 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "BlngL0WExXTeyrXg", "name": "Sovol Zero 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "BlngL0WExXTeyrXg", + "instantiation": "true", "printer_model": "Sovol Zero", "default_print_profile": "0.30mm Standard @Sovol Zero 0.6 nozzle", "printer_variant": "0.6", @@ -32,48 +32,63 @@ "3.0" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "1200", "1200" ], "machine_max_speed_y": [ + "1200", "1200" ], "machine_max_speed_z": [ + "30", "30" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "20000", "20000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "1000", "1000" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "5", "5" ], "machine_max_jerk_y": [ + "5", "5" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol Zero 0.8 nozzle.json b/resources/profiles/Sovol/machine/Sovol Zero 0.8 nozzle.json index bc67a64ce5..5fb9f267c7 100644 --- a/resources/profiles/Sovol/machine/Sovol Zero 0.8 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol Zero 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "DDpJMY1A2r4k1Cho", "name": "Sovol Zero 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "DDpJMY1A2r4k1Cho", + "instantiation": "true", "printer_model": "Sovol Zero", "default_print_profile": "0.40mm Standard @Sovol Zero 0.8 nozzle", "printer_variant": "0.8", @@ -32,48 +32,63 @@ "3.0" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "1200", "1200" ], "machine_max_speed_y": [ + "1200", "1200" ], "machine_max_speed_z": [ + "30", "30" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "20000", "20000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "1000", "1000" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "5", "5" ], "machine_max_jerk_y": [ + "5", "5" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/machine/Sovol Zero 1.0 nozzle.json b/resources/profiles/Sovol/machine/Sovol Zero 1.0 nozzle.json index beb6db80bd..fd87dafdaf 100644 --- a/resources/profiles/Sovol/machine/Sovol Zero 1.0 nozzle.json +++ b/resources/profiles/Sovol/machine/Sovol Zero 1.0 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "CGunT3KHnCqEAlrN", "name": "Sovol Zero 1.0 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_machine_common", + "from": "system", + "setting_id": "CGunT3KHnCqEAlrN", + "instantiation": "true", "printer_model": "Sovol Zero", "default_print_profile": "0.50mm Standard @Sovol Zero 1.0 nozzle", "printer_variant": "1.0", @@ -32,48 +32,63 @@ "3.0" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "1200", "1200" ], "machine_max_speed_y": [ + "1200", "1200" ], "machine_max_speed_z": [ + "30", "30" ], "machine_max_acceleration_e": [ + "20000", "20000" ], "machine_max_acceleration_extruding": [ + "40000", "40000" ], "machine_max_acceleration_retracting": [ + "20000", "20000" ], "machine_max_acceleration_travel": [ + "40000", "40000" ], "machine_max_acceleration_x": [ + "40000", "40000" ], "machine_max_acceleration_y": [ + "40000", "40000" ], "machine_max_acceleration_z": [ + "1000", "1000" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "5", "5" ], "machine_max_jerk_y": [ + "5", "5" ], "machine_max_jerk_z": [ + "0.5", "0.5" ], "z_hop": [ diff --git a/resources/profiles/Sovol/process/0.12mm Quality @Sovol Zero 0.4 nozzle.json b/resources/profiles/Sovol/process/0.12mm Quality @Sovol Zero 0.4 nozzle.json index c1cc06a737..642c136c55 100644 --- a/resources/profiles/Sovol/process/0.12mm Quality @Sovol Zero 0.4 nozzle.json +++ b/resources/profiles/Sovol/process/0.12mm Quality @Sovol Zero 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "CaEopiv2Wg6pQJjH", "name": "0.12mm Quality @Sovol Zero 0.4 nozzle", - "from": "system", "inherits": "fdm_process_zero", + "from": "system", + "setting_id": "CaEopiv2Wg6pQJjH", "instantiation": "true", "layer_height": "0.12", "bottom_shell_layers": "8", diff --git a/resources/profiles/Sovol/process/0.15mm Quality @Sovol Zero 0.6 nozzle.json b/resources/profiles/Sovol/process/0.15mm Quality @Sovol Zero 0.6 nozzle.json index f532985258..75b3e3bc9f 100644 --- a/resources/profiles/Sovol/process/0.15mm Quality @Sovol Zero 0.6 nozzle.json +++ b/resources/profiles/Sovol/process/0.15mm Quality @Sovol Zero 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "IfDpa3vM99D4ytny", "name": "0.15mm Quality @Sovol Zero 0.6 nozzle", - "from": "system", "inherits": "fdm_process_zero", + "from": "system", + "setting_id": "IfDpa3vM99D4ytny", "instantiation": "true", "layer_height": "0.15", "bottom_shell_layers": "5", diff --git a/resources/profiles/Sovol/process/0.20mm Standard @Sovol Zero 0.4 nozzle.json b/resources/profiles/Sovol/process/0.20mm Standard @Sovol Zero 0.4 nozzle.json index d8820163d6..0e05d5c232 100644 --- a/resources/profiles/Sovol/process/0.20mm Standard @Sovol Zero 0.4 nozzle.json +++ b/resources/profiles/Sovol/process/0.20mm Standard @Sovol Zero 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ShJTVnJ492No1j2j", "name": "0.20mm Standard @Sovol Zero 0.4 nozzle", - "from": "system", "inherits": "fdm_process_zero", + "from": "system", + "setting_id": "ShJTVnJ492No1j2j", "instantiation": "true", "layer_height": "0.20", "bottom_shell_layers": "4", diff --git a/resources/profiles/Sovol/process/0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle.json b/resources/profiles/Sovol/process/0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle.json index 89e248b223..ade76267af 100644 --- a/resources/profiles/Sovol/process/0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle.json +++ b/resources/profiles/Sovol/process/0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "oFrWcSxmad1b6sD4", "name": "0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle", - "from": "system", "inherits": "fdm_process_zero", + "from": "system", + "setting_id": "oFrWcSxmad1b6sD4", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Sovol/process/0.30mm Standard @Sovol Zero 0.6 nozzle.json b/resources/profiles/Sovol/process/0.30mm Standard @Sovol Zero 0.6 nozzle.json index 4f1f487bdf..930c0c14b0 100644 --- a/resources/profiles/Sovol/process/0.30mm Standard @Sovol Zero 0.6 nozzle.json +++ b/resources/profiles/Sovol/process/0.30mm Standard @Sovol Zero 0.6 nozzle.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "lTAs2USEP8D749K7", "name": "0.30mm Standard @Sovol Zero 0.6 nozzle", - "from": "system", "inherits": "fdm_process_zero", + "from": "system", + "setting_id": "lTAs2USEP8D749K7", "instantiation": "true", "layer_height": "0.30", "bottom_shell_layers": "4", diff --git a/resources/profiles/Tiertime.json b/resources/profiles/Tiertime.json index a7efecf420..a48691dd23 100644 --- a/resources/profiles/Tiertime.json +++ b/resources/profiles/Tiertime.json @@ -1,6 +1,6 @@ { "name": "Tiertime", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "Tiertime configurations", "machine_model_list": [ diff --git a/resources/profiles/Tiertime/filament/Generic ABS @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic ABS @Tiertime 300HS.json index e9d7aca6fc..d668d84e4e 100644 --- a/resources/profiles/Tiertime/filament/Generic ABS @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic ABS @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Tiertime 300HS", - "inherits": "fdm_filament_abs", "renamed_from": "Tiertime Generic ABS@300HS;Tiertime Generic ABS300HS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "CDku986CRCZQpwu4", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Tiertime/filament/Generic ABS @Tiertime.json b/resources/profiles/Tiertime/filament/Generic ABS @Tiertime.json index 7e8f606a6e..31fd71a17a 100644 --- a/resources/profiles/Tiertime/filament/Generic ABS @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic ABS @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Tiertime", - "inherits": "fdm_filament_abs", "renamed_from": "Tiertime Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "mDRlI9biZBn9sNlS", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Tiertime/filament/Generic ASA @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic ASA @Tiertime 300HS.json index adffa21725..8187f650a3 100644 --- a/resources/profiles/Tiertime/filament/Generic ASA @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic ASA @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Tiertime 300HS", - "inherits": "fdm_filament_asa", "renamed_from": "Tiertime Generic ASA@300HS;Tiertime Generic ASA300HS", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "HLh2XxQuVOa86efy", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Tiertime/filament/Generic ASA @Tiertime.json b/resources/profiles/Tiertime/filament/Generic ASA @Tiertime.json index 1529e0f702..b49082c269 100644 --- a/resources/profiles/Tiertime/filament/Generic ASA @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic ASA @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Tiertime", - "inherits": "fdm_filament_asa", "renamed_from": "Tiertime Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "kGrTR0sC37w9Qi3b", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime 300HS.json index 9db52386cb..40024ebb71 100644 --- a/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic BVOH @Tiertime 300HS", - "inherits": "fdm_filament_bvoh", "renamed_from": "Tiertime Generic BVOH@300HS;Tiertime Generic BVOH300HS", + "inherits": "fdm_filament_bvoh", "from": "system", "setting_id": "aCtg07TUbh6I9XPo", "filament_id": "OFo2UF2C", diff --git a/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime.json b/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime.json index fd6e2a529f..0e8188e36e 100644 --- a/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic BVOH @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic BVOH @Tiertime", - "inherits": "fdm_filament_bvoh", "renamed_from": "Tiertime Generic BVOH", + "inherits": "fdm_filament_bvoh", "from": "system", "setting_id": "b642QISGuDZ18fQ8", "filament_id": "OFo2UF2C", diff --git a/resources/profiles/Tiertime/filament/Generic EVA @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic EVA @Tiertime 300HS.json index f066563e4c..22bfc30c35 100644 --- a/resources/profiles/Tiertime/filament/Generic EVA @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic EVA @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic EVA @Tiertime 300HS", - "inherits": "fdm_filament_eva", "renamed_from": "Tiertime Generic EVA@300HS;Tiertime Generic EVA300HS", + "inherits": "fdm_filament_eva", "from": "system", "setting_id": "q5f3UKuj7KOtiNkH", "filament_id": "OFCD8qiU", diff --git a/resources/profiles/Tiertime/filament/Generic EVA @Tiertime.json b/resources/profiles/Tiertime/filament/Generic EVA @Tiertime.json index ec49722cae..e5fdbfa8a4 100644 --- a/resources/profiles/Tiertime/filament/Generic EVA @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic EVA @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic EVA @Tiertime", - "inherits": "fdm_filament_eva", "renamed_from": "Tiertime Generic EVA", + "inherits": "fdm_filament_eva", "from": "system", "setting_id": "NTY4MeZtxt16HNAV", "filament_id": "OFCD8qiU", diff --git a/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime 300HS.json index 8eaa300930..6b624d8c67 100644 --- a/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic HIPS @Tiertime 300HS", - "inherits": "fdm_filament_hips", "renamed_from": "Tiertime Generic HIPS@300HS;Tiertime Generic HIPS300HS", + "inherits": "fdm_filament_hips", "from": "system", "setting_id": "ee157A7VEkDzMh61", "filament_id": "OFsFon5l", diff --git a/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime.json b/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime.json index 519e690ed6..f53f9155e6 100644 --- a/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic HIPS @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic HIPS @Tiertime", - "inherits": "fdm_filament_hips", "renamed_from": "Tiertime Generic HIPS", + "inherits": "fdm_filament_hips", "from": "system", "setting_id": "3Vm99hmTMTFPKNGk", "filament_id": "OFsFon5l", diff --git a/resources/profiles/Tiertime/filament/Generic PA @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PA @Tiertime 300HS.json index 3c97aa11a7..39aa5ad463 100644 --- a/resources/profiles/Tiertime/filament/Generic PA @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PA @Tiertime 300HS.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Generic PA @Tiertime 300HS", - "inherits": "fdm_filament_pa", "renamed_from": "Tiertime Generic PA@300HS;Tiertime Generic PA300HS", + "inherits": "fdm_filament_pa", "from": "system", - "filament_id": "OFg8ndtj", "setting_id": "yGD1puWjH2QFacXJ", + "filament_id": "OFg8ndtj", "instantiation": "true", "chamber_temperatures": [ "60" diff --git a/resources/profiles/Tiertime/filament/Generic PA @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PA @Tiertime.json index 1ff338b317..4a73b6c27d 100644 --- a/resources/profiles/Tiertime/filament/Generic PA @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PA @Tiertime.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Generic PA @Tiertime", - "inherits": "fdm_filament_pa", "renamed_from": "Tiertime Generic PA", + "inherits": "fdm_filament_pa", "from": "system", - "filament_id": "OFg8ndtj", "setting_id": "u37BwUzY2vt6zqjd", + "filament_id": "OFg8ndtj", "instantiation": "true", "chamber_temperatures": [ "60" diff --git a/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime 300HS.json index 3feade702d..d6981a6ecf 100644 --- a/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime 300HS.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Generic PA-CF @Tiertime 300HS", - "inherits": "fdm_filament_pa", "renamed_from": "Tiertime Generic PA-CF@300HS;Tiertime Generic PA-CF300HS", + "inherits": "fdm_filament_pa", "from": "system", - "filament_id": "OFQLcbps", "setting_id": "nZprcLHiLIAKvqtu", + "filament_id": "OFQLcbps", "instantiation": "true", "fan_cooling_layer_time": [ "5" diff --git a/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime.json index fe57cb7806..c1c6963425 100644 --- a/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PA-CF @Tiertime.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Generic PA-CF @Tiertime", - "inherits": "fdm_filament_pa", "renamed_from": "Tiertime Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", - "filament_id": "OFQLcbps", "setting_id": "1oq9XQtCUcV9wGYV", + "filament_id": "OFQLcbps", "instantiation": "true", "fan_cooling_layer_time": [ "5" diff --git a/resources/profiles/Tiertime/filament/Generic PC @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PC @Tiertime 300HS.json index 591d1c9208..b2d1961c4e 100644 --- a/resources/profiles/Tiertime/filament/Generic PC @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PC @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Tiertime 300HS", - "inherits": "fdm_filament_pc", "renamed_from": "Tiertime Generic PC@300HS;Tiertime Generic PC300HS", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "cqm5YuWHhzXdvE0M", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Tiertime/filament/Generic PC @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PC @Tiertime.json index 8c36c18828..af1160e509 100644 --- a/resources/profiles/Tiertime/filament/Generic PC @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PC @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Tiertime", - "inherits": "fdm_filament_pc", "renamed_from": "Tiertime Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "ILOqHUkf5W9fcRic", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime 300HS.json index 25eb1b1b76..0c82dafed0 100644 --- a/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PCTG @Tiertime 300HS", - "inherits": "fdm_filament_pctg", "renamed_from": "Tiertime Generic PCTG@300HS;Tiertime Generic PCTG300HS", + "inherits": "fdm_filament_pctg", "from": "system", "setting_id": "1VNFGuUO3KSO6Yfr", "filament_id": "OFu1evlr", diff --git a/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime.json index 4d091cde32..d0945c92ba 100644 --- a/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PCTG @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PCTG @Tiertime", - "inherits": "fdm_filament_pctg", "renamed_from": "Tiertime Generic PCTG", + "inherits": "fdm_filament_pctg", "from": "system", "setting_id": "tJIMGMxg0hRSfL95", "filament_id": "OFu1evlr", diff --git a/resources/profiles/Tiertime/filament/Generic PE @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PE @Tiertime 300HS.json index a1fa9c5859..4743e2dd64 100644 --- a/resources/profiles/Tiertime/filament/Generic PE @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PE @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PE @Tiertime 300HS", - "inherits": "fdm_filament_pe", "renamed_from": "Tiertime Generic PE@300HS;Tiertime Generic PE300HS", + "inherits": "fdm_filament_pe", "from": "system", "setting_id": "CO9KWZrfkTYBnB4X", "filament_id": "OFPklMI1", diff --git a/resources/profiles/Tiertime/filament/Generic PE @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PE @Tiertime.json index 0684af67d8..4e96edfc00 100644 --- a/resources/profiles/Tiertime/filament/Generic PE @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PE @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PE @Tiertime", - "inherits": "fdm_filament_pe", "renamed_from": "Tiertime Generic PE", + "inherits": "fdm_filament_pe", "from": "system", "setting_id": "2U06Qrlxin8nLr9s", "filament_id": "OFPklMI1", diff --git a/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime 300HS.json index 11a6680550..59c94fe9c2 100644 --- a/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PE-CF @Tiertime 300HS", - "inherits": "fdm_filament_pe", "renamed_from": "Tiertime Generic PE-CF@300HS;Tiertime Generic PE-CF300HS", + "inherits": "fdm_filament_pe", "from": "system", "setting_id": "512vfRIxs8uwOBpP", "filament_id": "OFd0Fv0k", diff --git a/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime.json index ecc5a74d8c..6f2fd9fb2e 100644 --- a/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PE-CF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PE-CF @Tiertime", - "inherits": "fdm_filament_pe", "renamed_from": "Tiertime Generic PE-CF", + "inherits": "fdm_filament_pe", "from": "system", "setting_id": "QWIMNxCCZ9URxMjo", "filament_id": "OFd0Fv0k", diff --git a/resources/profiles/Tiertime/filament/Generic PETG @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PETG @Tiertime 300HS.json index e65d53bc71..2eb489ac68 100644 --- a/resources/profiles/Tiertime/filament/Generic PETG @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PETG @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Tiertime 300HS", - "inherits": "fdm_filament_pet", "renamed_from": "Tiertime Generic PETG@300HS;Tiertime Generic PETG300HS", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "btlSAAZFdFgnfIqh", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Tiertime/filament/Generic PETG @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PETG @Tiertime.json index cdf4a2ba88..2fe87a8ce8 100644 --- a/resources/profiles/Tiertime/filament/Generic PETG @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PETG @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Tiertime", - "inherits": "fdm_filament_pet", "renamed_from": "Tiertime Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "JwdH78YQ3v5XxsIq", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime 300HS.json index 2193ee85fe..f10abb4950 100644 --- a/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Tiertime 300HS", - "inherits": "fdm_filament_pet", "renamed_from": "Tiertime Generic PETG-CF@300HS;Tiertime Generic PETG-CF300HS", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "pnBek08LG30iqOmr", "filament_id": "OFoYSJKi", diff --git a/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime.json index 42b67f2c6d..b39dab2a80 100644 --- a/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PETG-CF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG-CF @Tiertime", - "inherits": "fdm_filament_pet", "renamed_from": "Tiertime Generic PETG-CF", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "97ZKNZS7uHaNzgLJ", "filament_id": "OFoYSJKi", diff --git a/resources/profiles/Tiertime/filament/Generic PHA @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PHA @Tiertime 300HS.json index d7d10eedfc..8f9d28e4bf 100644 --- a/resources/profiles/Tiertime/filament/Generic PHA @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PHA @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PHA @Tiertime 300HS", - "inherits": "fdm_filament_pha", "renamed_from": "Tiertime Generic PHA@300HS;Tiertime Generic PHA300HS", + "inherits": "fdm_filament_pha", "from": "system", "setting_id": "cdIDNHr9YR5p1gQx", "filament_id": "OF74KeQR", diff --git a/resources/profiles/Tiertime/filament/Generic PHA @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PHA @Tiertime.json index f0565e38a2..e75fdf606f 100644 --- a/resources/profiles/Tiertime/filament/Generic PHA @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PHA @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PHA @Tiertime", - "inherits": "fdm_filament_pha", "renamed_from": "Tiertime Generic PHA", + "inherits": "fdm_filament_pha", "from": "system", "setting_id": "GvzA9Y6mP5a767Qb", "filament_id": "OF74KeQR", diff --git a/resources/profiles/Tiertime/filament/Generic PLA @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PLA @Tiertime 300HS.json index 58c56fee5d..b4ea8b127a 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PLA @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Tiertime 300HS", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA@300HS;Tiertime Generic PLA300HS", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "VdXotPCaBzW0DswJ", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Tiertime/filament/Generic PLA @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PLA @Tiertime.json index 5f8aaf4229..32deff2d0a 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PLA @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Tiertime", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "RuyaWPyP41WHbU7p", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime 300HS.json index 779cc6ca4e..ff349c9461 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Tiertime 300HS", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA High Speed@300HS;Tiertime Generic PLA High Speed300HS", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "cDQTrE11kyvmtj6l", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime.json index c88496b0e6..a943b78c86 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PLA High Speed @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA High Speed @Tiertime", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA High Speed", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "HFwoDRXx0L72uTKc", "filament_id": "OFmpMwxS", diff --git a/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime 300HS.json index ba4745b50c..e74c192e6a 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Tiertime 300HS", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA Silk@300HS;Tiertime Generic PLA Silk300HS", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "pXFxVcPY3aVixOKU", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime.json index a2cbb3f4c4..755816a520 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PLA Silk @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA Silk @Tiertime", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA Silk", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "5R7nTGblzuEWfdog", "filament_id": "OFesA6rF", diff --git a/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime 300HS.json index d4ceebf2db..a23c9b9fa2 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Tiertime 300HS", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA-CF@300HS;Tiertime Generic PLA-CF300HS", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "CVks3a5cABQw38Ia", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime.json index 306ff427aa..f6fef07e95 100644 --- a/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PLA-CF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Tiertime", - "inherits": "fdm_filament_pla", "renamed_from": "Tiertime Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "SSHFL8Wbk46BaTYF", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Tiertime/filament/Generic PP @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PP @Tiertime 300HS.json index b79c34b466..52cfc3e370 100644 --- a/resources/profiles/Tiertime/filament/Generic PP @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PP @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PP @Tiertime 300HS", - "inherits": "fdm_filament_pp", "renamed_from": "Tiertime Generic PP@300HS;Tiertime Generic PP300HS", + "inherits": "fdm_filament_pp", "from": "system", "setting_id": "BmIuSlyYKMw76mqs", "filament_id": "OF1UNk9P", diff --git a/resources/profiles/Tiertime/filament/Generic PP @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PP @Tiertime.json index 0b7361dc78..84876ea951 100644 --- a/resources/profiles/Tiertime/filament/Generic PP @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PP @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PP @Tiertime", - "inherits": "fdm_filament_pp", "renamed_from": "Tiertime Generic PP", + "inherits": "fdm_filament_pp", "from": "system", "setting_id": "hbt3RXCxomod1cBQ", "filament_id": "OF1UNk9P", diff --git a/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime 300HS.json index e5a08307fa..4ca3b1f67a 100644 --- a/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PP-CF @Tiertime 300HS", - "inherits": "fdm_filament_pp", "renamed_from": "Tiertime Generic PP-CF@300HS;Tiertime Generic PP-CF300HS", + "inherits": "fdm_filament_pp", "from": "system", "setting_id": "u1Sqh9bCLFQvJxoS", "filament_id": "OFXkm8q1", diff --git a/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime.json index 4c8abaa8ce..39f9d257c4 100644 --- a/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PP-CF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PP-CF @Tiertime", - "inherits": "fdm_filament_pp", "renamed_from": "Tiertime Generic PP-CF", + "inherits": "fdm_filament_pp", "from": "system", "setting_id": "2giqoHCbRKiAuTyB", "filament_id": "OFXkm8q1", diff --git a/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime 300HS.json index 820f415b25..16eadd4a3c 100644 --- a/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PP-GF @Tiertime 300HS", - "inherits": "fdm_filament_pp", "renamed_from": "Tiertime Generic PP-GF@300HS;Tiertime Generic PP-GF300HS", + "inherits": "fdm_filament_pp", "from": "system", "setting_id": "Aiw0kkL0EFLNZ0zB", "filament_id": "OFsijjtH", diff --git a/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime.json index 930f2d7870..3648000b42 100644 --- a/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PP-GF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PP-GF @Tiertime", - "inherits": "fdm_filament_pp", "renamed_from": "Tiertime Generic PP-GF", + "inherits": "fdm_filament_pp", "from": "system", "setting_id": "HQaX19e4JViPTQn0", "filament_id": "OFsijjtH", diff --git a/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime 300HS.json index 6402b8a7c9..4dba9a28d4 100644 --- a/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPA-CF @Tiertime 300HS", - "inherits": "fdm_filament_ppa", "renamed_from": "Tiertime Generic PPA-CF@300HS;Tiertime Generic PPA-CF300HS", + "inherits": "fdm_filament_ppa", "from": "system", "setting_id": "yEjRoG6UAmEBAsTg", "filament_id": "OF8tPByX", diff --git a/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime.json index 845cd1f1f3..a509513732 100644 --- a/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PPA-CF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPA-CF @Tiertime", - "inherits": "fdm_filament_ppa", "renamed_from": "Tiertime Generic PPA-CF", + "inherits": "fdm_filament_ppa", "from": "system", "setting_id": "C3VjtPXIQ9CikaQH", "filament_id": "OF8tPByX", diff --git a/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime 300HS.json index 75a81d0aff..5e3602b1a2 100644 --- a/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPA-GF @Tiertime 300HS", - "inherits": "fdm_filament_ppa", "renamed_from": "Tiertime Generic PPA-GF@300HS;Tiertime Generic PPA-GF300HS", + "inherits": "fdm_filament_ppa", "from": "system", "setting_id": "9088HrpGRDIqqxTs", "filament_id": "OF8Tlg47", diff --git a/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime.json index 7ec50bd2f4..cbcd2dfc93 100644 --- a/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PPA-GF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPA-GF @Tiertime", - "inherits": "fdm_filament_ppa", "renamed_from": "Tiertime Generic PPA-GF", + "inherits": "fdm_filament_ppa", "from": "system", "setting_id": "jGP0en9vTFNmj5AJ", "filament_id": "OF8Tlg47", diff --git a/resources/profiles/Tiertime/filament/Generic PPS @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PPS @Tiertime 300HS.json index bd804b9ffc..75d249dfaa 100644 --- a/resources/profiles/Tiertime/filament/Generic PPS @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PPS @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPS @Tiertime 300HS", - "inherits": "fdm_filament_pps", "renamed_from": "Tiertime Generic PPS@300HS;Tiertime Generic PPS300HS", + "inherits": "fdm_filament_pps", "from": "system", "setting_id": "KIspUdArMQzvDtcX", "filament_id": "OFq9svOz", diff --git a/resources/profiles/Tiertime/filament/Generic PPS @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PPS @Tiertime.json index dbb381012e..f0f1980545 100644 --- a/resources/profiles/Tiertime/filament/Generic PPS @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PPS @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPS @Tiertime", - "inherits": "fdm_filament_pps", "renamed_from": "Tiertime Generic PPS", + "inherits": "fdm_filament_pps", "from": "system", "setting_id": "NCTW11dGCzTxasjU", "filament_id": "OFq9svOz", diff --git a/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime 300HS.json index f53a77c9c6..ce5102519b 100644 --- a/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPS-CF @Tiertime 300HS", - "inherits": "fdm_filament_pps", "renamed_from": "Tiertime Generic PPS-CF@300HS;Tiertime Generic PPS-CF300HS", + "inherits": "fdm_filament_pps", "from": "system", "setting_id": "E7mVBEFECdf1mhXE", "filament_id": "OF6rdQ6M", diff --git a/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime.json index 3e4e15da7d..0cf6dad6d3 100644 --- a/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PPS-CF @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PPS-CF @Tiertime", - "inherits": "fdm_filament_pps", "renamed_from": "Tiertime Generic PPS-CF", + "inherits": "fdm_filament_pps", "from": "system", "setting_id": "QUPOb7dBkg6bPul2", "filament_id": "OF6rdQ6M", diff --git a/resources/profiles/Tiertime/filament/Generic PVA @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic PVA @Tiertime 300HS.json index 2efe590fb6..ab6e0df772 100644 --- a/resources/profiles/Tiertime/filament/Generic PVA @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic PVA @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Tiertime 300HS", - "inherits": "fdm_filament_pva", "renamed_from": "Tiertime Generic PVA@300HS;Tiertime Generic PVA300HS", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "E8fgXFvjTnIpqdrg", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Tiertime/filament/Generic PVA @Tiertime.json b/resources/profiles/Tiertime/filament/Generic PVA @Tiertime.json index 588648b8b0..d4d0492e25 100644 --- a/resources/profiles/Tiertime/filament/Generic PVA @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic PVA @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Tiertime", - "inherits": "fdm_filament_pva", "renamed_from": "Tiertime Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "6R2BduAh4ASmGbDd", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Tiertime/filament/Generic SBS @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic SBS @Tiertime 300HS.json index f3860b4e64..a25e559f84 100644 --- a/resources/profiles/Tiertime/filament/Generic SBS @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic SBS @Tiertime 300HS.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic SBS @Tiertime 300HS", - "inherits": "fdm_filament_sbs", "renamed_from": "Tiertime Generic SBS@300HS;Tiertime Generic SBS300HS", + "inherits": "fdm_filament_sbs", "from": "system", "setting_id": "nS6aGQgepNoAjumo", "filament_id": "OFhQfUQY", diff --git a/resources/profiles/Tiertime/filament/Generic SBS @Tiertime.json b/resources/profiles/Tiertime/filament/Generic SBS @Tiertime.json index 7c4751aa34..76ecfb07df 100644 --- a/resources/profiles/Tiertime/filament/Generic SBS @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic SBS @Tiertime.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic SBS @Tiertime", - "inherits": "fdm_filament_sbs", "renamed_from": "Tiertime Generic SBS", + "inherits": "fdm_filament_sbs", "from": "system", "setting_id": "nyv523sDXK9fDbtb", "filament_id": "OFhQfUQY", diff --git a/resources/profiles/Tiertime/filament/Generic TPU @Tiertime 300HS.json b/resources/profiles/Tiertime/filament/Generic TPU @Tiertime 300HS.json index 2d52d479d3..5d8121ea22 100644 --- a/resources/profiles/Tiertime/filament/Generic TPU @Tiertime 300HS.json +++ b/resources/profiles/Tiertime/filament/Generic TPU @Tiertime 300HS.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Generic TPU @Tiertime 300HS", - "inherits": "fdm_filament_tpu", "renamed_from": "Tiertime Generic TPU@300HS;Tiertime Generic TPU300HS", + "inherits": "fdm_filament_tpu", "from": "system", - "filament_id": "OFgbpcy9", "setting_id": "99UYNDy3zV3bChRG", + "filament_id": "OFgbpcy9", "instantiation": "true", "filament_max_volumetric_speed": [ "3.2" diff --git a/resources/profiles/Tiertime/filament/Generic TPU @Tiertime.json b/resources/profiles/Tiertime/filament/Generic TPU @Tiertime.json index a32f1173dc..24db1ff710 100644 --- a/resources/profiles/Tiertime/filament/Generic TPU @Tiertime.json +++ b/resources/profiles/Tiertime/filament/Generic TPU @Tiertime.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "Generic TPU @Tiertime", - "inherits": "fdm_filament_tpu", "renamed_from": "Tiertime Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", - "filament_id": "OFgbpcy9", "setting_id": "UCowa7X5TZwXBJWe", + "filament_id": "OFgbpcy9", "instantiation": "true", "filament_max_volumetric_speed": [ "3.2" diff --git a/resources/profiles/Tiertime/filament/Tiertime ABS.json b/resources/profiles/Tiertime/filament/Tiertime ABS.json index 4ff6b5c8fd..2821a27abe 100644 --- a/resources/profiles/Tiertime/filament/Tiertime ABS.json +++ b/resources/profiles/Tiertime/filament/Tiertime ABS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFNQKF0M", - "setting_id": "uAtyf2jCQEcv7D2r", "name": "Tiertime ABS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "uAtyf2jCQEcv7D2r", + "filament_id": "OFNQKF0M", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Tiertime/filament/Tiertime ABS@300HS.json b/resources/profiles/Tiertime/filament/Tiertime ABS@300HS.json index 7014efe177..440ef41f48 100644 --- a/resources/profiles/Tiertime/filament/Tiertime ABS@300HS.json +++ b/resources/profiles/Tiertime/filament/Tiertime ABS@300HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFNQKF0M", - "setting_id": "x1XBGyOHIgrD7PVs", "name": "Tiertime ABS@300HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "x1XBGyOHIgrD7PVs", + "filament_id": "OFNQKF0M", + "instantiation": "true", "filament_flow_ratio": [ "0.95" ], diff --git a/resources/profiles/Tiertime/filament/Tiertime PLA.json b/resources/profiles/Tiertime/filament/Tiertime PLA.json index d0a030184a..72eba01283 100644 --- a/resources/profiles/Tiertime/filament/Tiertime PLA.json +++ b/resources/profiles/Tiertime/filament/Tiertime PLA.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFNGTH3w", - "setting_id": "dlXQZNrJfvkJ3kWs", "name": "Tiertime PLA", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "dlXQZNrJfvkJ3kWs", + "filament_id": "OFNGTH3w", + "instantiation": "true", "filament_cost": [ "24.99" ], diff --git a/resources/profiles/Tiertime/filament/Tiertime PLA@300HS.json b/resources/profiles/Tiertime/filament/Tiertime PLA@300HS.json index 48073d5c76..6707898c2b 100644 --- a/resources/profiles/Tiertime/filament/Tiertime PLA@300HS.json +++ b/resources/profiles/Tiertime/filament/Tiertime PLA@300HS.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFNGTH3w", - "setting_id": "bqWrzfz6CXHohbpL", "name": "Tiertime PLA@300HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "bqWrzfz6CXHohbpL", + "filament_id": "OFNGTH3w", + "instantiation": "true", "filament_cost": [ "24.99" ], diff --git a/resources/profiles/Tiertime/machine/Tiertime UP300 HS 0.4 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP300 HS 0.4 nozzle.json index 63c5e51e50..f4e621c1ca 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP300 HS 0.4 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP300 HS 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "lgltuIatOQ6w6QbU", "name": "Tiertime UP300 HS 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_tiertime_common", + "from": "system", + "setting_id": "lgltuIatOQ6w6QbU", + "instantiation": "true", "printer_model": "Tiertime UP300 HS", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP310 Pro 0.4 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP310 Pro 0.4 nozzle.json index 8baee541a6..7dae9872c8 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP310 Pro 0.4 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP310 Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "HMZ8IXHF9SCYY794", "name": "Tiertime UP310 Pro 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_tiertime_common", + "from": "system", + "setting_id": "HMZ8IXHF9SCYY794", + "instantiation": "true", "printer_model": "Tiertime UP310 Pro", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.4 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.4 nozzle.json index ce65946a41..c7c4473c55 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.4 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "92AYB3s93gFz7ZPX", "name": "Tiertime UP400 Pro 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_tiertime_common", + "from": "system", + "setting_id": "92AYB3s93gFz7ZPX", + "instantiation": "true", "printer_model": "Tiertime UP400 Pro", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.6 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.6 nozzle.json index 272017038f..ac5ce33f63 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.6 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "6NLuMd5QTEV7Dz7y", "name": "Tiertime UP400 Pro 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Tiertime UP400 Pro 0.4 nozzle", + "from": "system", + "setting_id": "6NLuMd5QTEV7Dz7y", + "instantiation": "true", "printer_model": "Tiertime UP400 Pro", "nozzle_diameter": [ "0.6" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.8 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.8 nozzle.json index f43bda57a8..ed5c96f834 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.8 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP400 Pro 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "MieJsq4OcDXSPeYE", "name": "Tiertime UP400 Pro 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Tiertime UP400 Pro 0.4 nozzle", + "from": "system", + "setting_id": "MieJsq4OcDXSPeYE", + "instantiation": "true", "printer_model": "Tiertime UP400 Pro", "nozzle_diameter": [ "0.8" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.4 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.4 nozzle.json index a18c2a938f..2691e807ae 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.4 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.4 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "6aAsuPmotiaU41L4", "name": "Tiertime UP600 HS 0.4 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_tiertime_common", + "from": "system", + "setting_id": "6aAsuPmotiaU41L4", + "instantiation": "true", "printer_model": "Tiertime UP600 HS", "nozzle_diameter": [ "0.4" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.6 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.6 nozzle.json index ea706dede8..1deed12abb 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.6 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.6 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "4xd2mlCoTuJoXmOf", "name": "Tiertime UP600 HS 0.6 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Tiertime UP600 HS 0.4 nozzle", + "from": "system", + "setting_id": "4xd2mlCoTuJoXmOf", + "instantiation": "true", "printer_model": "Tiertime UP600 HS", "nozzle_diameter": [ "0.6" diff --git a/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.8 nozzle.json b/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.8 nozzle.json index d114741fb9..ed010446c0 100644 --- a/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.8 nozzle.json +++ b/resources/profiles/Tiertime/machine/Tiertime UP600 HS 0.8 nozzle.json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "tqKPATsUnwQWjXso", "name": "Tiertime UP600 HS 0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "Tiertime UP600 HS 0.4 nozzle", + "from": "system", + "setting_id": "tqKPATsUnwQWjXso", + "instantiation": "true", "printer_model": "Tiertime UP600 HS", "nozzle_diameter": [ "0.8" diff --git a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP300 HS.json b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP300 HS.json index 68d60b1e2c..eb94220c60 100644 --- a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP300 HS.json +++ b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP300 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "kJslDhHisZSqoNLu", "name": "0.12mm Fine @Tiertime UP300 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "kJslDhHisZSqoNLu", + "instantiation": "true", "layer_height": "0.12", "bottom_shell_layers": "5", "elefant_foot_compensation": "0.15", diff --git a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP310 Pro.json b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP310 Pro.json index 0b3375f656..8791d34371 100644 --- a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP310 Pro.json +++ b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP310 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "u1Hfo84e0ffI39MP", "name": "0.12mm Fine @Tiertime UP310 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "u1Hfo84e0ffI39MP", + "instantiation": "true", "layer_height": "0.12", "bottom_shell_layers": "5", "elefant_foot_compensation": "0.15", diff --git a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP400 Pro.json b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP400 Pro.json index 019d4617af..b6f1519ac9 100644 --- a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP400 Pro.json +++ b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP400 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "LiT2jc5HHSsxdPOY", "name": "0.12mm Fine @Tiertime UP400 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "LiT2jc5HHSsxdPOY", + "instantiation": "true", "layer_height": "0.12", "bottom_shell_layers": "5", "elefant_foot_compensation": "0.15", diff --git a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP600 HS.json b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP600 HS.json index 63f7b269d1..6777672d93 100644 --- a/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP600 HS.json +++ b/resources/profiles/Tiertime/process/0.12mm Fine @Tiertime UP600 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "LwKN2IKIgniQAUbc", "name": "0.12mm Fine @Tiertime UP600 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "LwKN2IKIgniQAUbc", + "instantiation": "true", "layer_height": "0.12", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "5", diff --git a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP300 HS.json b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP300 HS.json index ed678b16bd..c9b9295809 100644 --- a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP300 HS.json +++ b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP300 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "deEyVahMnJBIUh5W", "name": "0.16mm Optimal @Tiertime UP300 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "deEyVahMnJBIUh5W", + "instantiation": "true", "layer_height": "0.16", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "4", diff --git a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP310 Pro.json b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP310 Pro.json index 189ac439e2..51355d03ec 100644 --- a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP310 Pro.json +++ b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP310 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "89hv0us5IMmhpDol", "name": "0.16mm Optimal @Tiertime UP310 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "89hv0us5IMmhpDol", + "instantiation": "true", "layer_height": "0.16", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "4", diff --git a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP400 Pro.json b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP400 Pro.json index 7a4b5943a5..2d3abf48f1 100644 --- a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP400 Pro.json +++ b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP400 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "yZBSB83IptM1eMzO", "name": "0.16mm Optimal @Tiertime UP400 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "yZBSB83IptM1eMzO", + "instantiation": "true", "layer_height": "0.16", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "4", diff --git a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP600 HS.json b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP600 HS.json index b172f23ca4..36a7232b91 100644 --- a/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP600 HS.json +++ b/resources/profiles/Tiertime/process/0.16mm Optimal @Tiertime UP600 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "BfOJljkGUCnVJ0zM", "name": "0.16mm Optimal @Tiertime UP600 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "BfOJljkGUCnVJ0zM", + "instantiation": "true", "layer_height": "0.16", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "4", diff --git a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP300 HS.json b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP300 HS.json index 8d9947736b..9fc8e95fee 100644 --- a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP300 HS.json +++ b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP300 HS.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "4a1IpFohcCPCxI1I", "name": "0.20mm Standard @Tiertime UP300 HS", - "from": "system", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "4a1IpFohcCPCxI1I", "instantiation": "true", "elefant_foot_compensation": "0.15", "top_shell_thickness": "1.0", diff --git a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP310 Pro.json b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP310 Pro.json index 834b645e2e..b03937aa1c 100644 --- a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP310 Pro.json +++ b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP310 Pro.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "48QrtoSmDHWLbuck", "name": "0.20mm Standard @Tiertime UP310 Pro", - "from": "system", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "48QrtoSmDHWLbuck", "instantiation": "true", "elefant_foot_compensation": "0.15", "top_shell_thickness": "1.0", diff --git a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP400 Pro.json b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP400 Pro.json index d196edc5ca..0013fe4e77 100644 --- a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP400 Pro.json +++ b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP400 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "QotYAumKUh7h5cBH", "name": "0.20mm Standard @Tiertime UP400 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "QotYAumKUh7h5cBH", + "instantiation": "true", "layer_height": "0.2", "initial_layer_speed": "50", "initial_layer_infill_speed": "105", diff --git a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP600 HS.json b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP600 HS.json index 3db84cce38..7df15ed346 100644 --- a/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP600 HS.json +++ b/resources/profiles/Tiertime/process/0.20mm Standard @Tiertime UP600 HS.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "FKDS8Ql5ApZdlsH8", "name": "0.20mm Standard @Tiertime UP600 HS", - "from": "system", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "FKDS8Ql5ApZdlsH8", "instantiation": "true", "elefant_foot_compensation": "0.15", "top_shell_thickness": "1.0", diff --git a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP300 HS.json b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP300 HS.json index a209d85d93..ec71aa67b9 100644 --- a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP300 HS.json +++ b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP300 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "clvHKafqg81lxC4s", "name": "0.24mm Draft @Tiertime UP300 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "clvHKafqg81lxC4s", + "instantiation": "true", "layer_height": "0.24", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP310 Pro.json b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP310 Pro.json index bb2d11bcf5..ab2c2fc69a 100644 --- a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP310 Pro.json +++ b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP310 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "zr1zPgeqxJog1iO6", "name": "0.24mm Draft @Tiertime UP310 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "zr1zPgeqxJog1iO6", + "instantiation": "true", "layer_height": "0.24", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP400 Pro.json b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP400 Pro.json index 8ad2181ba3..49e7f95c99 100644 --- a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP400 Pro.json +++ b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP400 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "L84Tpur6DqX0WI9U", "name": "0.24mm Draft @Tiertime UP400 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "L84Tpur6DqX0WI9U", + "instantiation": "true", "layer_height": "0.24", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP600 HS.json b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP600 HS.json index 730b3fdb91..43705dd6d3 100644 --- a/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP600 HS.json +++ b/resources/profiles/Tiertime/process/0.24mm Draft @Tiertime UP600 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "D7fl6dZLCLa5n8Es", "name": "0.24mm Draft @Tiertime UP600 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "D7fl6dZLCLa5n8Es", + "instantiation": "true", "layer_height": "0.24", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "3", diff --git a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP300 HS.json b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP300 HS.json index 34f7f7221a..0dc2af9312 100644 --- a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP300 HS.json +++ b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP300 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "CBOtpFjUICGttrgV", "name": "0.28mm Extra Draft @Tiertime UP300 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "CBOtpFjUICGttrgV", + "instantiation": "true", "layer_height": "0.28", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP310 Pro.json b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP310 Pro.json index 0b6617941f..f822d31bc5 100644 --- a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP310 Pro.json +++ b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP310 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "ODXIraViN4sdzaKe", "name": "0.28mm Extra Draft @Tiertime UP310 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "ODXIraViN4sdzaKe", + "instantiation": "true", "layer_height": "0.28", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP400 Pro.json b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP400 Pro.json index 5c11562a22..5d5f598ae9 100644 --- a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP400 Pro.json +++ b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP400 Pro.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "bfRd7zHG5JoOWdXb", "name": "0.28mm Extra Draft @Tiertime UP400 Pro", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_common", + "from": "system", + "setting_id": "bfRd7zHG5JoOWdXb", + "instantiation": "true", "layer_height": "0.28", "elefant_foot_compensation": "0.15", "top_surface_line_width": "0.45", diff --git a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP600 HS.json b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP600 HS.json index 60b1b484ee..646ad3cab9 100644 --- a/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP600 HS.json +++ b/resources/profiles/Tiertime/process/0.28mm Extra Draft @Tiertime UP600 HS.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "gl1nKSyprhumL6ci", "name": "0.28mm Extra Draft @Tiertime UP600 HS", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_tiertime_HS_common", + "from": "system", + "setting_id": "gl1nKSyprhumL6ci", + "instantiation": "true", "layer_height": "0.28", "elefant_foot_compensation": "0.15", "bottom_shell_layers": "3", diff --git a/resources/profiles/TwoTrees.json b/resources/profiles/TwoTrees.json index 5d97581ffc..3735f19d98 100644 --- a/resources/profiles/TwoTrees.json +++ b/resources/profiles/TwoTrees.json @@ -1,6 +1,6 @@ { "name": "TwoTrees", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "1", "description": "TwoTrees configurations", "machine_model_list": [ diff --git a/resources/profiles/TwoTrees/filament/Generic HS PLA @TwoTrees SK1.json b/resources/profiles/TwoTrees/filament/Generic HS PLA @TwoTrees SK1.json index fd22e6417a..fae333784c 100644 --- a/resources/profiles/TwoTrees/filament/Generic HS PLA @TwoTrees SK1.json +++ b/resources/profiles/TwoTrees/filament/Generic HS PLA @TwoTrees SK1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic HS PLA @TwoTrees SK1", - "inherits": "fdm_filament_pla", "renamed_from": "TwoTrees Generic HS PLA @SK1;TwoTrees Generic HS PLA SK1", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "uRS2QA3xad1lBZJR", "filament_id": "OFvxghTE", diff --git a/resources/profiles/TwoTrees/filament/Generic TPU 95A @TwoTrees SK1.json b/resources/profiles/TwoTrees/filament/Generic TPU 95A @TwoTrees SK1.json index 6f0221b92c..e6580e78f9 100644 --- a/resources/profiles/TwoTrees/filament/Generic TPU 95A @TwoTrees SK1.json +++ b/resources/profiles/TwoTrees/filament/Generic TPU 95A @TwoTrees SK1.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU 95A @TwoTrees SK1", - "inherits": "fdm_filament_tpu", "renamed_from": "TwoTrees Generic 95A TPU @SK1;TwoTrees Generic 95A TPU SK1", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "hAqaYYR7xzkcr2xC", "filament_id": "OFjiXpyf", diff --git a/resources/profiles/UltiMaker.json b/resources/profiles/UltiMaker.json index 5d55de2c8d..14bce7c6da 100644 --- a/resources/profiles/UltiMaker.json +++ b/resources/profiles/UltiMaker.json @@ -1,7 +1,7 @@ { "name": "UltiMaker", "url": "", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "0", "description": "UltiMaker configurations", "machine_model_list": [ diff --git a/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.4 nozzle.json b/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.4 nozzle.json index 2d35c6e350..a0047cf733 100644 --- a/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.4 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.4 nozzle.json @@ -1,6 +1,6 @@ { "type": "filament", - "name": "Generic ABS @UltiMaker 2 0.4 nozzle", + "name": "Generic ABS @UltiMaker 2 0.4 nozzle", "inherits": "Generic ABS @System", "from": "system", "setting_id": "z65YPRPvIareA5TJ", @@ -9,6 +9,9 @@ "filament_diameter": [ "2.85" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "6" ], @@ -37,6 +40,6 @@ "1" ], "compatible_printers": [ - "UltiMaker 2 0.4 nozzle" + "UltiMaker 2 0.4 nozzle" ] } diff --git a/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.6 nozzle.json b/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.6 nozzle.json index 3f10cf2170..6c748cb3b9 100644 --- a/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.6 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.6 nozzle.json @@ -1,18 +1,21 @@ { - "type": "filament", - "name": "Generic ABS @UltiMaker 2 0.6 nozzle", - "inherits": "Generic ABS @UltiMaker 2 0.4 nozzle", - "from": "system", - "setting_id": "eo9lcJAw8yrGBWr8", - "filament_id": "OFY9muEs", - "instantiation": "true", - "filament_diameter": [ - "2.85" - ], - "filament_max_volumetric_speed": [ - "6" - ], - "compatible_printers": [ - "UltiMaker 2 0.6 nozzle" - ] + "type": "filament", + "name": "Generic ABS @UltiMaker 2 0.6 nozzle", + "inherits": "Generic ABS @UltiMaker 2 0.4 nozzle", + "from": "system", + "setting_id": "eo9lcJAw8yrGBWr8", + "filament_id": "OFY9muEs", + "instantiation": "true", + "filament_diameter": [ + "2.85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_max_volumetric_speed": [ + "6" + ], + "compatible_printers": [ + "UltiMaker 2 0.6 nozzle" + ] } diff --git a/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.8 nozzle.json b/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.8 nozzle.json index e445d8afd2..9449b0790f 100644 --- a/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.8 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic ABS @UltiMaker 2 0.8 nozzle.json @@ -1,18 +1,21 @@ { - "type": "filament", - "name": "Generic ABS @UltiMaker 2 0.8 nozzle", - "inherits": "Generic ABS @UltiMaker 2 0.4 nozzle", - "from": "system", - "setting_id": "1VE4ie9s2gYKUx7r", - "filament_id": "OFY9muEs", - "instantiation": "true", - "filament_diameter": [ - "2.85" - ], - "filament_max_volumetric_speed": [ - "6" - ], - "compatible_printers": [ - "UltiMaker 2 0.8 nozzle" - ] + "type": "filament", + "name": "Generic ABS @UltiMaker 2 0.8 nozzle", + "inherits": "Generic ABS @UltiMaker 2 0.4 nozzle", + "from": "system", + "setting_id": "1VE4ie9s2gYKUx7r", + "filament_id": "OFY9muEs", + "instantiation": "true", + "filament_diameter": [ + "2.85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_max_volumetric_speed": [ + "6" + ], + "compatible_printers": [ + "UltiMaker 2 0.8 nozzle" + ] } diff --git a/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.4 nozzle.json b/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.4 nozzle.json index ff74b46449..e1d143a97d 100644 --- a/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.4 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.4 nozzle.json @@ -1,6 +1,6 @@ { "type": "filament", - "name": "Generic PETG @UltiMaker 2 0.4 nozzle", + "name": "Generic PETG @UltiMaker 2 0.4 nozzle", "inherits": "Generic PETG @System", "from": "system", "setting_id": "WR3y0y8gmWH40llb", @@ -9,6 +9,9 @@ "filament_diameter": [ "2.85" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "6" ], @@ -28,6 +31,6 @@ "0" ], "compatible_printers": [ - "UltiMaker 2 0.4 nozzle" + "UltiMaker 2 0.4 nozzle" ] } diff --git a/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.6 nozzle.json b/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.6 nozzle.json index a0a8efb1e3..11a9702bd2 100644 --- a/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.6 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.6 nozzle.json @@ -1,18 +1,21 @@ { - "type": "filament", - "name": "Generic PETG @UltiMaker 2 0.6 nozzle", - "inherits": "Generic PETG @UltiMaker 2 0.4 nozzle", - "from": "system", - "setting_id": "koLquuN6eQo8Zn5V", - "filament_id": "OFYPdQJh", - "instantiation": "true", - "filament_diameter": [ - "2.85" - ], - "filament_max_volumetric_speed": [ - "6" - ], - "compatible_printers": [ - "UltiMaker 2 0.6 nozzle" - ] + "type": "filament", + "name": "Generic PETG @UltiMaker 2 0.6 nozzle", + "inherits": "Generic PETG @UltiMaker 2 0.4 nozzle", + "from": "system", + "setting_id": "koLquuN6eQo8Zn5V", + "filament_id": "OFYPdQJh", + "instantiation": "true", + "filament_diameter": [ + "2.85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_max_volumetric_speed": [ + "6" + ], + "compatible_printers": [ + "UltiMaker 2 0.6 nozzle" + ] } diff --git a/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.8 nozzle.json b/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.8 nozzle.json index 10590aa46a..32fa6828ca 100644 --- a/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.8 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic PETG @UltiMaker 2 0.8 nozzle.json @@ -1,18 +1,21 @@ { - "type": "filament", - "name": "Generic PETG @UltiMaker 2 0.8 nozzle", - "inherits": "Generic PETG @UltiMaker 2 0.4 nozzle", - "from": "system", - "setting_id": "ZtVG7edcUktSNI0P", - "filament_id": "OFYPdQJh", - "instantiation": "true", - "filament_diameter": [ - "2.85" - ], - "filament_max_volumetric_speed": [ - "6" - ], - "compatible_printers": [ - "UltiMaker 2 0.8 nozzle" - ] + "type": "filament", + "name": "Generic PETG @UltiMaker 2 0.8 nozzle", + "inherits": "Generic PETG @UltiMaker 2 0.4 nozzle", + "from": "system", + "setting_id": "ZtVG7edcUktSNI0P", + "filament_id": "OFYPdQJh", + "instantiation": "true", + "filament_diameter": [ + "2.85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_max_volumetric_speed": [ + "6" + ], + "compatible_printers": [ + "UltiMaker 2 0.8 nozzle" + ] } diff --git a/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.4 nozzle.json b/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.4 nozzle.json index c2c9b67fb9..0e78193ab5 100644 --- a/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.4 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.4 nozzle.json @@ -1,6 +1,6 @@ { "type": "filament", - "name": "Generic PLA @UltiMaker 2 0.4 nozzle", + "name": "Generic PLA @UltiMaker 2 0.4 nozzle", "inherits": "Generic PLA @System", "from": "system", "setting_id": "3i42yTge4Nm6R2Yo", @@ -9,6 +9,9 @@ "filament_diameter": [ "2.85" ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], "filament_max_volumetric_speed": [ "8" ], @@ -25,6 +28,6 @@ "200" ], "compatible_printers": [ - "UltiMaker 2 0.4 nozzle" + "UltiMaker 2 0.4 nozzle" ] } diff --git a/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.6 nozzle.json b/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.6 nozzle.json index 3f4c74f8ab..7882b5ad40 100644 --- a/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.6 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.6 nozzle.json @@ -1,18 +1,21 @@ { - "type": "filament", - "name": "Generic PLA @UltiMaker 2 0.6 nozzle", - "inherits": "Generic PLA @UltiMaker 2 0.4 nozzle", - "from": "system", - "setting_id": "yvWYFuY9SPIwwSVG", - "filament_id": "OFDSrzZ8", - "instantiation": "true", - "filament_diameter": [ - "2.85" - ], - "filament_max_volumetric_speed": [ - "8" - ], - "compatible_printers": [ - "UltiMaker 2 0.6 nozzle" - ] + "type": "filament", + "name": "Generic PLA @UltiMaker 2 0.6 nozzle", + "inherits": "Generic PLA @UltiMaker 2 0.4 nozzle", + "from": "system", + "setting_id": "yvWYFuY9SPIwwSVG", + "filament_id": "OFDSrzZ8", + "instantiation": "true", + "filament_diameter": [ + "2.85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "compatible_printers": [ + "UltiMaker 2 0.6 nozzle" + ] } diff --git a/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.8 nozzle.json b/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.8 nozzle.json index 91aaf5f1dc..1c83931279 100644 --- a/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.8 nozzle.json +++ b/resources/profiles/UltiMaker/filament/Generic PLA @UltiMaker 2 0.8 nozzle.json @@ -1,18 +1,21 @@ { - "type": "filament", - "name": "Generic PLA @UltiMaker 2 0.8 nozzle", - "inherits": "Generic PLA @UltiMaker 2 0.4 nozzle", - "from": "system", - "setting_id": "4yvMTmMYkCvggt0f", - "filament_id": "OFDSrzZ8", - "instantiation": "true", - "filament_diameter": [ - "2.85" - ], - "filament_max_volumetric_speed": [ - "8" - ], - "compatible_printers": [ - "UltiMaker 2 0.8 nozzle" - ] + "type": "filament", + "name": "Generic PLA @UltiMaker 2 0.8 nozzle", + "inherits": "Generic PLA @UltiMaker 2 0.4 nozzle", + "from": "system", + "setting_id": "4yvMTmMYkCvggt0f", + "filament_id": "OFDSrzZ8", + "instantiation": "true", + "filament_diameter": [ + "2.85" + ], + "filament_extruder_variant": [ + "Direct Drive Standard" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "compatible_printers": [ + "UltiMaker 2 0.8 nozzle" + ] } diff --git a/resources/profiles/UltiMaker/machine/UltiMaker S5 0.4 nozzle.json b/resources/profiles/UltiMaker/machine/UltiMaker S5 0.4 nozzle.json index 5c212070b7..7ed7c97f40 100644 --- a/resources/profiles/UltiMaker/machine/UltiMaker S5 0.4 nozzle.json +++ b/resources/profiles/UltiMaker/machine/UltiMaker S5 0.4 nozzle.json @@ -20,62 +20,93 @@ "printable_height": "300", "extruder_clearance_height_to_rod": "60", "extruder_clearance_radius": "61", - "nozzle_type": "brass", + "nozzle_type": [ + "brass", + "brass" + ], "auxiliary_fan": "0", "use_relative_e_distances": "0", "machine_max_acceleration_extruding": [ + "3500", + "3500", "3500", "3500" ], "machine_max_acceleration_retracting": [ + "3500", + "3500", "3500", "3500" ], "machine_max_acceleration_travel": [ + "3500", + "3500", "3500", "3500" ], "machine_max_acceleration_x": [ + "3500", + "3500", "3500", "3500" ], "machine_max_acceleration_y": [ + "3500", + "3500", "3500", "3500" ], "machine_max_acceleration_z": [ + "500", + "500", "500", "500" ], "machine_max_speed_e": [ + "120", + "120", "120", "120" ], "machine_max_speed_x": [ + "500", + "500", "500", "500" ], "machine_max_speed_y": [ + "500", + "500", "500", "500" ], "machine_max_speed_z": [ + "12", + "12", "12", "12" ], "machine_max_jerk_e": [ + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "20", + "20", "20", "20" ], "machine_max_jerk_y": [ + "20", + "20", "20", "20" ], "machine_max_jerk_z": [ + "0.4", + "0.4", "0.4", "0.4" ], @@ -89,24 +120,31 @@ ], "printer_settings_id": "Qidi", "retraction_minimum_travel": [ + "5", "5" ], "retract_before_wipe": [ + "70%", "70%" ], "retraction_length": [ + "4.5", "4.5" ], "retract_length_toolchange": [ + "11", "11" ], "retraction_speed": [ + "45", "45" ], "deretraction_speed": [ + "0", "0" ], "wipe_distance": [ + "0.2", "0.2" ], "single_extruder_multi_material": "0", @@ -116,9 +154,11 @@ "Generic PLA @System" ], "z_hop": [ + "1", "1" ], "z_hop_types": [ + "Normal Lift", "Normal Lift" ], "extruder_type": [ diff --git a/resources/profiles/Volumic.json b/resources/profiles/Volumic.json index 7923f2d92f..a287eaadb9 100644 --- a/resources/profiles/Volumic.json +++ b/resources/profiles/Volumic.json @@ -1,6 +1,6 @@ { "name": "Volumic", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "1", "description": "VOLUMIC configurations", "machine_model_list": [ diff --git a/resources/profiles/Volumic/filament/PA6 CF20 (Performance).json b/resources/profiles/Volumic/filament/PA6 CF20 (Performance).json index 6b67c28f15..a05855a0be 100644 --- a/resources/profiles/Volumic/filament/PA6 CF20 (Performance).json +++ b/resources/profiles/Volumic/filament/PA6 CF20 (Performance).json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFcKtw8W", - "setting_id": "wuZ0EvlbcJ8GxajY", "name": "PA6 CF20 (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pa", + "from": "system", + "setting_id": "wuZ0EvlbcJ8GxajY", + "filament_id": "OFcKtw8W", + "instantiation": "true", "filament_flow_ratio": [ "0.96" ], diff --git a/resources/profiles/Volumic/filament/PETG ESD (Performance).json b/resources/profiles/Volumic/filament/PETG ESD (Performance).json index 06814b64ad..bcf98c14cf 100644 --- a/resources/profiles/Volumic/filament/PETG ESD (Performance).json +++ b/resources/profiles/Volumic/filament/PETG ESD (Performance).json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFiwEbze", - "setting_id": "May8rNEMOOs1qtae", "name": "PETG ESD (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "May8rNEMOOs1qtae", + "filament_id": "OFiwEbze", + "instantiation": "true", "filament_type": [ "PETG-ESD" ], diff --git a/resources/profiles/Volumic/filament/PPS Carbone (Performance).json b/resources/profiles/Volumic/filament/PPS Carbone (Performance).json index 4708f912c4..4c1b5008d1 100644 --- a/resources/profiles/Volumic/filament/PPS Carbone (Performance).json +++ b/resources/profiles/Volumic/filament/PPS Carbone (Performance).json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFEZpel7", - "setting_id": "HE0yILdkhbiXbH1j", "name": "PPS Carbone (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pa", + "from": "system", + "setting_id": "HE0yILdkhbiXbH1j", + "filament_id": "OFEZpel7", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic ABS Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic ABS Ultra Performance.json index 865f03155e..d4034d948d 100644 --- a/resources/profiles/Volumic/filament/Volumic ABS Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic ABS Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFyQwdaM", - "setting_id": "466ggy6ydgaZOrSx", "name": "Volumic ABS Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "466ggy6ydgaZOrSx", + "filament_id": "OFyQwdaM", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic ABS Ultra.json b/resources/profiles/Volumic/filament/Volumic ABS Ultra.json index f538936b5a..e14dc59a63 100644 --- a/resources/profiles/Volumic/filament/Volumic ABS Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic ABS Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFyUJI3q", - "setting_id": "omHiTINFPThooUqk", "name": "Volumic ABS Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_abs", + "from": "system", + "setting_id": "omHiTINFPThooUqk", + "filament_id": "OFyUJI3q", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic ASA Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic ASA Ultra Performance.json index 519387adf5..dd695adfa9 100644 --- a/resources/profiles/Volumic/filament/Volumic ASA Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic ASA Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFU7CKZt", - "setting_id": "uE5jxeOBISvO5o7L", "name": "Volumic ASA Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_asa", + "from": "system", + "setting_id": "uE5jxeOBISvO5o7L", + "filament_id": "OFU7CKZt", + "instantiation": "true", "filament_flow_ratio": [ "0.96" ], diff --git a/resources/profiles/Volumic/filament/Volumic ASA Ultra.json b/resources/profiles/Volumic/filament/Volumic ASA Ultra.json index 2225125c3c..c7ddf544e6 100644 --- a/resources/profiles/Volumic/filament/Volumic ASA Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic ASA Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OF2EB9Iz", - "setting_id": "LOAp2zgQWqg1lQQ4", "name": "Volumic ASA Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_asa", + "from": "system", + "setting_id": "LOAp2zgQWqg1lQQ4", + "filament_id": "OF2EB9Iz", + "instantiation": "true", "filament_flow_ratio": [ "0.96" ], diff --git a/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra Performance.json index 54d0f89bb3..29b67af7be 100644 --- a/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFUH1aee", - "setting_id": "k5V3bjZrtr7t8zl0", "name": "Volumic FLEX93 Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "k5V3bjZrtr7t8zl0", + "filament_id": "OFUH1aee", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra.json b/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra.json index 84ccdc6d19..0dc1dd1f25 100644 --- a/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic FLEX93 Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFuxH0Uz", - "setting_id": "DXZ4Gp5XP5VCJTXY", "name": "Volumic FLEX93 Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_tpu", + "from": "system", + "setting_id": "DXZ4Gp5XP5VCJTXY", + "filament_id": "OFuxH0Uz", + "instantiation": "true", "filament_flow_ratio": [ "1.20" ], diff --git a/resources/profiles/Volumic/filament/Volumic NYLON Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic NYLON Ultra Performance.json index 8a4b44f59b..7e7c77f261 100644 --- a/resources/profiles/Volumic/filament/Volumic NYLON Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic NYLON Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFi90KlM", - "setting_id": "RC5gFyIejXWDJuHH", "name": "Volumic NYLON Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pa", + "from": "system", + "setting_id": "RC5gFyIejXWDJuHH", + "filament_id": "OFi90KlM", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic NYLON Ultra.json b/resources/profiles/Volumic/filament/Volumic NYLON Ultra.json index 95c5f81a6a..9d1d5a868b 100644 --- a/resources/profiles/Volumic/filament/Volumic NYLON Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic NYLON Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFWa0NiB", - "setting_id": "AL4xDgN8EIYb3UrL", "name": "Volumic NYLON Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pa", + "from": "system", + "setting_id": "AL4xDgN8EIYb3UrL", + "filament_id": "OFWa0NiB", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PC Performance.json b/resources/profiles/Volumic/filament/Volumic PC Performance.json index d454de5688..3e36b87207 100644 --- a/resources/profiles/Volumic/filament/Volumic PC Performance.json +++ b/resources/profiles/Volumic/filament/Volumic PC Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFgSbX7E", - "setting_id": "ht6Ar3ilCkPT7geN", "name": "Volumic PC (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pc", + "from": "system", + "setting_id": "ht6Ar3ilCkPT7geN", + "filament_id": "OFgSbX7E", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PC.json b/resources/profiles/Volumic/filament/Volumic PC.json index 12ea420585..46f1d63eb8 100644 --- a/resources/profiles/Volumic/filament/Volumic PC.json +++ b/resources/profiles/Volumic/filament/Volumic PC.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFaHjk1V", - "setting_id": "3pUnwXise3J77Qmc", "name": "Volumic PC", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pc", + "from": "system", + "setting_id": "3pUnwXise3J77Qmc", + "filament_id": "OFaHjk1V", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PCTG Ultra (Performance).json b/resources/profiles/Volumic/filament/Volumic PCTG Ultra (Performance).json index 5e20cb2922..2000a1e00b 100644 --- a/resources/profiles/Volumic/filament/Volumic PCTG Ultra (Performance).json +++ b/resources/profiles/Volumic/filament/Volumic PCTG Ultra (Performance).json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFTdauIq", - "setting_id": "NdegYSDVrQ4Rawtp", "name": "Volumic PCTG Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "NdegYSDVrQ4Rawtp", + "filament_id": "OFTdauIq", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PETG Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic PETG Ultra Performance.json index 6b98fc49d2..710dfb07f1 100644 --- a/resources/profiles/Volumic/filament/Volumic PETG Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic PETG Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFsD974q", - "setting_id": "bNcC5kGe9jOm7Ltu", "name": "Volumic PETG Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "bNcC5kGe9jOm7Ltu", + "filament_id": "OFsD974q", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone Performance.json b/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone Performance.json index 91827ebe80..9b08425013 100644 --- a/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone Performance.json +++ b/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFY0F5qA", - "setting_id": "IIFtCkVvHoLtxPxj", "name": "Volumic PETG Ultra carbone (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "IIFtCkVvHoLtxPxj", + "filament_id": "OFY0F5qA", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone.json b/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone.json index 137bad9d53..77753061a9 100644 --- a/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone.json +++ b/resources/profiles/Volumic/filament/Volumic PETG Ultra carbone.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFu08yGN", - "setting_id": "nOKT0adoQi3O7Tge", "name": "Volumic PETG Ultra carbone", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "nOKT0adoQi3O7Tge", + "filament_id": "OFu08yGN", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PETG Ultra.json b/resources/profiles/Volumic/filament/Volumic PETG Ultra.json index 8db07d0bab..b89510318e 100644 --- a/resources/profiles/Volumic/filament/Volumic PETG Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic PETG Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFG0kOKX", - "setting_id": "CuBXW7SqUeJOcxPP", "name": "Volumic PETG Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "CuBXW7SqUeJOcxPP", + "filament_id": "OFG0kOKX", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PLA Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic PLA Ultra Performance.json index 2a02fe7c88..38011bd086 100644 --- a/resources/profiles/Volumic/filament/Volumic PLA Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic PLA Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OF3dJf4E", - "setting_id": "8J2ZIz8ByFNEB9PC", "name": "Volumic PLA Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "8J2ZIz8ByFNEB9PC", + "filament_id": "OF3dJf4E", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PLA Ultra.json b/resources/profiles/Volumic/filament/Volumic PLA Ultra.json index 2e5f762d39..a3bb2d5ade 100644 --- a/resources/profiles/Volumic/filament/Volumic PLA Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic PLA Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFXuGxvQ", - "setting_id": "3BeQ60i4cOs3BfZn", "name": "Volumic PLA Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "3BeQ60i4cOs3BfZn", + "filament_id": "OFXuGxvQ", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PP Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic PP Ultra Performance.json index 3fafb8aac0..6033de8045 100644 --- a/resources/profiles/Volumic/filament/Volumic PP Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic PP Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFNSYu5h", - "setting_id": "nsiOJ8ExySR1RksQ", "name": "Volumic PP Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pp", + "from": "system", + "setting_id": "nsiOJ8ExySR1RksQ", + "filament_id": "OFNSYu5h", + "instantiation": "true", "filament_flow_ratio": [ "1.0" ], diff --git a/resources/profiles/Volumic/filament/Volumic PP Ultra.json b/resources/profiles/Volumic/filament/Volumic PP Ultra.json index eba78219bc..b0b4d675fb 100644 --- a/resources/profiles/Volumic/filament/Volumic PP Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic PP Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFsFo7ms", - "setting_id": "UA91pv54dzbBRkFe", "name": "Volumic PP Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pp", + "from": "system", + "setting_id": "UA91pv54dzbBRkFe", + "filament_id": "OFsFo7ms", + "instantiation": "true", "filament_flow_ratio": [ "1.24" ], diff --git a/resources/profiles/Volumic/filament/Volumic PVA Performance.json b/resources/profiles/Volumic/filament/Volumic PVA Performance.json index 199d33ed62..f4e7617cad 100644 --- a/resources/profiles/Volumic/filament/Volumic PVA Performance.json +++ b/resources/profiles/Volumic/filament/Volumic PVA Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFRkjhxK", - "setting_id": "L9ZTGhwNpVWT6E5j", "name": "Volumic PVA-BVOH (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pva", + "from": "system", + "setting_id": "L9ZTGhwNpVWT6E5j", + "filament_id": "OFRkjhxK", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic PVA.json b/resources/profiles/Volumic/filament/Volumic PVA.json index 24c28a89a5..87c5c0eda3 100644 --- a/resources/profiles/Volumic/filament/Volumic PVA.json +++ b/resources/profiles/Volumic/filament/Volumic PVA.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFGdP6Na", - "setting_id": "rw4bB5gYM6YF8v9e", "name": "Volumic PVA", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pva", + "from": "system", + "setting_id": "rw4bB5gYM6YF8v9e", + "filament_id": "OFGdP6Na", + "instantiation": "true", "filament_flow_ratio": [ "1.00" ], diff --git a/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra Performance.json b/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra Performance.json index 90562ebba2..00d3cb5470 100644 --- a/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra Performance.json +++ b/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra Performance.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFkGp50Y", - "setting_id": "rxVkBvMZYgHOoFW6", "name": "Volumic UNIVERSAL Ultra (Performance)", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "rxVkBvMZYgHOoFW6", + "filament_id": "OFkGp50Y", + "instantiation": "true", "filament_type": [ "UNIV" ], diff --git a/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra.json b/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra.json index ee50a25ffd..dde1298f20 100644 --- a/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra.json +++ b/resources/profiles/Volumic/filament/Volumic UNIVERSAL Ultra.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFpumhCM", - "setting_id": "6iOFERN4x6xBbtuT", "name": "Volumic UNIVERSAL Ultra", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "6iOFERN4x6xBbtuT", + "filament_id": "OFpumhCM", + "instantiation": "true", "filament_type": [ "UNIV" ], diff --git a/resources/profiles/Volumic/filament/desactive.json b/resources/profiles/Volumic/filament/desactive.json index 1c490c957e..0089e61965 100644 --- a/resources/profiles/Volumic/filament/desactive.json +++ b/resources/profiles/Volumic/filament/desactive.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFCuaCer", - "setting_id": "Sphn4hoDMpH2uy86", "name": "Désactivé", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", + "from": "system", + "setting_id": "Sphn4hoDMpH2uy86", + "filament_id": "OFCuaCer", + "instantiation": "true", "filament_flow_ratio": [ "0.1" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_abs.json b/resources/profiles/Volumic/filament/fdm_filament_abs.json index c959efccf7..02d839f175 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_abs.json +++ b/resources/profiles/Volumic/filament/fdm_filament_abs.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_abs", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "90" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_asa.json b/resources/profiles/Volumic/filament/fdm_filament_asa.json index 250673c190..d009bac400 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_asa.json +++ b/resources/profiles/Volumic/filament/fdm_filament_asa.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_asa", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_pa.json b/resources/profiles/Volumic/filament/fdm_filament_pa.json index f2b3db1bfd..9c86cca422 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_pa.json +++ b/resources/profiles/Volumic/filament/fdm_filament_pa.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pa", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "65" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_pc.json b/resources/profiles/Volumic/filament/fdm_filament_pc.json index 72cbc789dc..6bebbfecf4 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_pc.json +++ b/resources/profiles/Volumic/filament/fdm_filament_pc.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pc", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "0" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_pet.json b/resources/profiles/Volumic/filament/fdm_filament_pet.json index 14ab033789..5214dff875 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_pet.json +++ b/resources/profiles/Volumic/filament/fdm_filament_pet.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pet", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "60" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_pla.json b/resources/profiles/Volumic/filament/fdm_filament_pla.json index 2fc9a8ef1d..51e8fd14a8 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_pla.json +++ b/resources/profiles/Volumic/filament/fdm_filament_pla.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pla", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "fan_cooling_layer_time": [ "100" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_pp.json b/resources/profiles/Volumic/filament/fdm_filament_pp.json index 9c0f879608..0c654aa06f 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_pp.json +++ b/resources/profiles/Volumic/filament/fdm_filament_pp.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pp", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "90" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_pva.json b/resources/profiles/Volumic/filament/fdm_filament_pva.json index 549dd8bcc8..1c8b0ffc48 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_pva.json +++ b/resources/profiles/Volumic/filament/fdm_filament_pva.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_pva", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "60" ], diff --git a/resources/profiles/Volumic/filament/fdm_filament_tpu.json b/resources/profiles/Volumic/filament/fdm_filament_tpu.json index be647956f6..aba5d3fd64 100644 --- a/resources/profiles/Volumic/filament/fdm_filament_tpu.json +++ b/resources/profiles/Volumic/filament/fdm_filament_tpu.json @@ -1,9 +1,9 @@ { "type": "filament", "name": "fdm_filament_tpu", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "cool_plate_temp": [ "45" ], diff --git a/resources/profiles/Volumic/machine/EXO42 (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO42 (0.4 nozzle).json index 2a9fad874e..b16c9969cc 100644 --- a/resources/profiles/Volumic/machine/EXO42 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO42 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "38SnDDmFg2mCRcFt", "name": "EXO42 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "38SnDDmFg2mCRcFt", + "instantiation": "true", "printer_model": "EXO42", "default_print_profile": "Normal speed - 0.15mm", "host_type": "esp3d", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y419 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/EXO42 IDRE (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO42 IDRE (0.4 nozzle).json index e1b362df83..3c4e6f6ef4 100644 --- a/resources/profiles/Volumic/machine/EXO42 IDRE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO42 IDRE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "15K6j1YDiO2ubyZq", "name": "EXO42 IDRE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "15K6j1YDiO2ubyZq", + "instantiation": "true", "printer_model": "EXO42 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x420" ], "printable_height": "400", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/EXO42 IDRE COPY MODE (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO42 IDRE COPY MODE (0.4 nozzle).json index 0f6303fd19..77c44ae3de 100644 --- a/resources/profiles/Volumic/machine/EXO42 IDRE COPY MODE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO42 IDRE COPY MODE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "cNF164YBrD1xcG2h", "name": "EXO42 IDRE COPY MODE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "cNF164YBrD1xcG2h", + "instantiation": "true", "printer_model": "EXO42 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x420" ], "printable_height": "400", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/EXO42 IDRE MIRROR MODE (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO42 IDRE MIRROR MODE (0.4 nozzle).json index 1c5f5d1700..b3188dbbc4 100644 --- a/resources/profiles/Volumic/machine/EXO42 IDRE MIRROR MODE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO42 IDRE MIRROR MODE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "OMdv9AS4d4HDXYB7", "name": "EXO42 IDRE MIRROR MODE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "OMdv9AS4d4HDXYB7", + "instantiation": "true", "printer_model": "EXO42 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x420" ], "printable_height": "400", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/EXO42 Performance (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO42 Performance (0.4 nozzle).json index fbece162b5..4066c6e917 100644 --- a/resources/profiles/Volumic/machine/EXO42 Performance (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO42 Performance (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "uSgdeLwfwMCIF8jJ", "name": "EXO42 Performance (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "uSgdeLwfwMCIF8jJ", + "instantiation": "true", "printer_model": "EXO42 Performance", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/EXO42 Stage 2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO42 Stage 2 (0.4 nozzle).json index 978af519f6..0ae74783f7 100644 --- a/resources/profiles/Volumic/machine/EXO42 Stage 2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO42 Stage 2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "nFLSTPErGjQw6XnS", "name": "EXO42 Stage 2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "nFLSTPErGjQw6XnS", + "instantiation": "true", "printer_model": "EXO42 Stage 2", "default_print_profile": "Normal speed (Stage 2) - 0.20mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/EXO65 (0.6 nozzle).json b/resources/profiles/Volumic/machine/EXO65 (0.6 nozzle).json index 8ca2438da9..75ed1f5a42 100644 --- a/resources/profiles/Volumic/machine/EXO65 (0.6 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 (0.6 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "N5hPPEyrF6WFPO8r", "name": "EXO65 (0.6 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "N5hPPEyrF6WFPO8r", + "instantiation": "true", "printer_model": "EXO65", "default_print_profile": "Normal speed - 0.15mm", "host_type": "esp3d", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y649 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/EXO65 IDRE (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO65 IDRE (0.4 nozzle).json index 8d67f7fa06..2f528e297c 100644 --- a/resources/profiles/Volumic/machine/EXO65 IDRE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 IDRE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "eInlnTPT9RXNQe0H", "name": "EXO65 IDRE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "eInlnTPT9RXNQe0H", + "instantiation": "true", "printer_model": "EXO65 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x650" ], "printable_height": "630", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/EXO65 IDRE COPY MODE (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO65 IDRE COPY MODE (0.4 nozzle).json index 6609ff57cc..5f3d3b2a40 100644 --- a/resources/profiles/Volumic/machine/EXO65 IDRE COPY MODE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 IDRE COPY MODE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "qTCFDCqFaq5Cr2MK", "name": "EXO65 IDRE COPY MODE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "qTCFDCqFaq5Cr2MK", + "instantiation": "true", "printer_model": "EXO65 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x650" ], "printable_height": "630", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/EXO65 IDRE MIRROR MODE (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO65 IDRE MIRROR MODE (0.4 nozzle).json index e331184117..3a3fe5d234 100644 --- a/resources/profiles/Volumic/machine/EXO65 IDRE MIRROR MODE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 IDRE MIRROR MODE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "CRmhnf8ONHFpDZ9p", "name": "EXO65 IDRE MIRROR MODE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "CRmhnf8ONHFpDZ9p", + "instantiation": "true", "printer_model": "EXO65 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x650" ], "printable_height": "630", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/EXO65 Performance (0.4 nozzle).json b/resources/profiles/Volumic/machine/EXO65 Performance (0.4 nozzle).json index 54c15d80b0..1e24b85f67 100644 --- a/resources/profiles/Volumic/machine/EXO65 Performance (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 Performance (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "Iokq2oBwJVaEwT9A", "name": "EXO65 Performance (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "Iokq2oBwJVaEwT9A", + "instantiation": "true", "printer_model": "EXO65 Performance", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/EXO65 Performance (0.6 nozzle).json b/resources/profiles/Volumic/machine/EXO65 Performance (0.6 nozzle).json index 8bbc66ef38..2f63efbec5 100644 --- a/resources/profiles/Volumic/machine/EXO65 Performance (0.6 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 Performance (0.6 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "WWrVx8eGg8rm1saw", "name": "EXO65 Performance (0.6 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "WWrVx8eGg8rm1saw", + "instantiation": "true", "printer_model": "EXO65 Performance", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/EXO65 Performance (0.8 nozzle).json b/resources/profiles/Volumic/machine/EXO65 Performance (0.8 nozzle).json index cb2b91161b..65a5b685a5 100644 --- a/resources/profiles/Volumic/machine/EXO65 Performance (0.8 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 Performance (0.8 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "4LGJDuCA7yAKGml3", "name": "EXO65 Performance (0.8 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "4LGJDuCA7yAKGml3", + "instantiation": "true", "printer_model": "EXO65 Performance", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/EXO65 Stage 2 (0.6 nozzle).json b/resources/profiles/Volumic/machine/EXO65 Stage 2 (0.6 nozzle).json index 735e1843bc..f3d7d90d76 100644 --- a/resources/profiles/Volumic/machine/EXO65 Stage 2 (0.6 nozzle).json +++ b/resources/profiles/Volumic/machine/EXO65 Stage 2 (0.6 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "jsBm1DhY7qw63SSI", "name": "EXO65 Stage 2 (0.6 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "jsBm1DhY7qw63SSI", + "instantiation": "true", "printer_model": "EXO65 Stage 2", "default_print_profile": "Normal speed (Stage 2) - 0.20mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/SH65 (0.4 nozzle).json b/resources/profiles/Volumic/machine/SH65 (0.4 nozzle).json index a49591a421..944e773cc3 100644 --- a/resources/profiles/Volumic/machine/SH65 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/SH65 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "EeJsStZPNfCT7WkW", "name": "SH65 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "EeJsStZPNfCT7WkW", + "instantiation": "true", "printer_model": "SH65", "default_print_profile": "Normal speed - 0.15mm", "host_type": "esp3d", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y299 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/SH65 IDRE (0.4 nozzle).json b/resources/profiles/Volumic/machine/SH65 IDRE (0.4 nozzle).json index a316163582..c695d8bc72 100644 --- a/resources/profiles/Volumic/machine/SH65 IDRE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/SH65 IDRE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "aKBeUSXzBU2qQIEE", "name": "SH65 IDRE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "aKBeUSXzBU2qQIEE", + "instantiation": "true", "printer_model": "SH65 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x300" ], "printable_height": "280", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/SH65 IDRE COPY MODE (0.4 nozzle).json b/resources/profiles/Volumic/machine/SH65 IDRE COPY MODE (0.4 nozzle).json index bcd01d002f..a2006840fd 100644 --- a/resources/profiles/Volumic/machine/SH65 IDRE COPY MODE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/SH65 IDRE COPY MODE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "abcf94SvavkMYyFU", "name": "SH65 IDRE COPY MODE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "abcf94SvavkMYyFU", + "instantiation": "true", "printer_model": "SH65 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x300" ], "printable_height": "280", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/SH65 IDRE MIRROR MODE (0.4 nozzle).json b/resources/profiles/Volumic/machine/SH65 IDRE MIRROR MODE (0.4 nozzle).json index 72c8ab938d..0b28b9287b 100644 --- a/resources/profiles/Volumic/machine/SH65 IDRE MIRROR MODE (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/SH65 IDRE MIRROR MODE (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "xBbVrJNCzJO4egUE", "name": "SH65 IDRE MIRROR MODE (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "xBbVrJNCzJO4egUE", + "instantiation": "true", "printer_model": "SH65 IDRE", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -20,7 +20,10 @@ "11x300" ], "printable_height": "280", - "nozzle_type": "undefine", + "nozzle_type": [ + "undefine", + "undefine" + ], "auxiliary_fan": "0", "gcode_flavor": "klipper", "max_layer_height": [ @@ -31,24 +34,37 @@ ], "printer_variant": "0.4", "retraction_minimum_travel": [ + "1", "1" ], "retraction_length": [ + "2.4", "2.4" ], "retraction_speed": [ + "30", "30" ], "deretraction_speed": [ + "30", "30" ], "machine_max_acceleration_x": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", + "4500", + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", + "50", + "50", "50" ], "single_extruder_multi_material": [ diff --git a/resources/profiles/Volumic/machine/SH65 Performance (0.4 nozzle).json b/resources/profiles/Volumic/machine/SH65 Performance (0.4 nozzle).json index 0163a27d65..e138bb5623 100644 --- a/resources/profiles/Volumic/machine/SH65 Performance (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/SH65 Performance (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "lmlG4rGxYKYkydUM", "name": "SH65 Performance (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "lmlG4rGxYKYkydUM", + "instantiation": "true", "printer_model": "SH65 Performance", "default_print_profile": "Performance 150 - 0.15mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/SH65 Stage 2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/SH65 Stage 2 (0.4 nozzle).json index 09c3802d10..7000359300 100644 --- a/resources/profiles/Volumic/machine/SH65 Stage 2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/SH65 Stage 2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "e3rpbhqZmSzuW5kA", "name": "SH65 Stage 2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "e3rpbhqZmSzuW5kA", + "instantiation": "true", "printer_model": "SH65 Stage 2", "default_print_profile": "Normal speed (Stage 2) - 0.20mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/VS20MK2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS20MK2 (0.4 nozzle).json index 18f800df15..a7e9fa1e0e 100644 --- a/resources/profiles/Volumic/machine/VS20MK2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS20MK2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "xV2JznZ0imfZku62", "name": "VS20MK2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "xV2JznZ0imfZku62", + "instantiation": "true", "printer_model": "VS20MK2", "default_print_profile": "Compatible speed - 0.15mm", "nozzle_diameter": [ @@ -40,12 +40,15 @@ "25" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y199 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/VS30MK2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30MK2 (0.4 nozzle).json index e0c5195a1d..d3a905761f 100644 --- a/resources/profiles/Volumic/machine/VS30MK2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30MK2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "MnCC2SAgstB2WR50", "name": "VS30MK2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "MnCC2SAgstB2WR50", + "instantiation": "true", "printer_model": "VS30MK2", "default_print_profile": "Compatible speed - 0.15mm", "nozzle_diameter": [ @@ -40,12 +40,15 @@ "25" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y299 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/VS30MK3 (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30MK3 (0.4 nozzle).json index 72924347a3..53caa7025d 100644 --- a/resources/profiles/Volumic/machine/VS30MK3 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30MK3 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "KFPbLwO3vQqIuJ34", "name": "VS30MK3 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "KFPbLwO3vQqIuJ34", + "instantiation": "true", "printer_model": "VS30MK3", "default_print_profile": "Normal speed - 0.15mm", "host_type": "esp3d", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y299 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/VS30MK3 Stage 2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30MK3 Stage 2 (0.4 nozzle).json index d45f2a6b6b..9c4b1cac73 100644 --- a/resources/profiles/Volumic/machine/VS30MK3 Stage 2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30MK3 Stage 2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "XW58eNI9Y25FmAMR", "name": "VS30MK3 Stage 2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "XW58eNI9Y25FmAMR", + "instantiation": "true", "printer_model": "VS30MK3 Stage 2", "default_print_profile": "Normal speed (Stage 2) - 0.20mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4000", "4000" ], "machine_max_acceleration_y": [ + "4000", "4000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/VS30SC (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30SC (0.4 nozzle).json index af49da615d..35d3c95fb8 100644 --- a/resources/profiles/Volumic/machine/VS30SC (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30SC (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "8HxzSP6HW9nOPphc", "name": "VS30SC (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "8HxzSP6HW9nOPphc", + "instantiation": "true", "printer_model": "VS30SC", "default_print_profile": "Normal speed - 0.15mm", "host_type": "esp3d", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y199 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/VS30SC2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30SC2 (0.4 nozzle).json index 2e67106b5c..91a2619c97 100644 --- a/resources/profiles/Volumic/machine/VS30SC2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30SC2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "D9xXWUeeAAWmesfa", "name": "VS30SC2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "D9xXWUeeAAWmesfa", + "instantiation": "true", "printer_model": "VS30SC2", "default_print_profile": "Normal speed - 0.15mm", "host_type": "esp3d", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y199 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/machine/VS30SC2 Performance (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30SC2 Performance (0.4 nozzle).json index b2e9318337..ece1ffc74b 100644 --- a/resources/profiles/Volumic/machine/VS30SC2 Performance (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30SC2 Performance (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "PKKfRBEEc0CGbh45", "name": "VS30SC2 Performance (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "PKKfRBEEc0CGbh45", + "instantiation": "true", "printer_model": "VS30SC2 Performance", "default_print_profile": "Normal performance VS30 - 0.20mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4500", "4500" ], "machine_max_acceleration_y": [ + "4500", "4500" ], "machine_max_acceleration_z": [ + "150", "150" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/VS30SC2 Stage 2 (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30SC2 Stage 2 (0.4 nozzle).json index 4d5fe68f1d..27ffffb74c 100644 --- a/resources/profiles/Volumic/machine/VS30SC2 Stage 2 (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30SC2 Stage 2 (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "2RWMRzJILLpB2W3V", "name": "VS30SC2 Stage 2 (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "2RWMRzJILLpB2W3V", + "instantiation": "true", "printer_model": "VS30SC2 Stage 2", "default_print_profile": "Normal speed (Stage 2) - 0.20mm", "host_type": "octoprint", @@ -42,12 +42,15 @@ "30" ], "machine_max_acceleration_x": [ + "4000", "4000" ], "machine_max_acceleration_y": [ + "4000", "4000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "START_PRINT BED=[first_layer_bed_temperature] EXTRUDER=[first_layer_temperature]", diff --git a/resources/profiles/Volumic/machine/VS30ULTRA (0.4 nozzle).json b/resources/profiles/Volumic/machine/VS30ULTRA (0.4 nozzle).json index a7ed6be9ac..b0d0774360 100644 --- a/resources/profiles/Volumic/machine/VS30ULTRA (0.4 nozzle).json +++ b/resources/profiles/Volumic/machine/VS30ULTRA (0.4 nozzle).json @@ -1,10 +1,10 @@ { "type": "machine", - "setting_id": "IZzmiYZXK5UBri4z", "name": "VS30ULTRA (0.4 nozzle)", - "from": "system", - "instantiation": "true", "inherits": "fdm_volumic_common", + "from": "system", + "setting_id": "IZzmiYZXK5UBri4z", + "instantiation": "true", "printer_model": "VS30ULTRA", "default_print_profile": "Normal speed - 0.15mm", "nozzle_diameter": [ @@ -40,12 +40,15 @@ "30" ], "machine_max_acceleration_x": [ + "2000", "2000" ], "machine_max_acceleration_y": [ + "2000", "2000" ], "machine_max_acceleration_z": [ + "50", "50" ], "machine_start_gcode": "M117 Demarrage\nM106 S0\nM140 S[first_layer_bed_temperature]\nM104 T0 S[first_layer_temperature]\nG28\nG90\nM82\nG92 E0\nG1 Z5 F600\nG1 X1 Y199 F6000\nM109 T0 S[first_layer_temperature]\nM300 P350\nG92 E0\nM117 Impression", diff --git a/resources/profiles/Volumic/process/Compatible speed - 0.10mm.json b/resources/profiles/Volumic/process/Compatible speed - 0.10mm.json index 0dfce3935f..0412c8baa0 100644 --- a/resources/profiles/Volumic/process/Compatible speed - 0.10mm.json +++ b/resources/profiles/Volumic/process/Compatible speed - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "0Gwgv9G1arp0ufdp", "name": "Compatible speed - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "0Gwgv9G1arp0ufdp", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Compatible speed - 0.15mm.json b/resources/profiles/Volumic/process/Compatible speed - 0.15mm.json index e8745de20f..ae7529e735 100644 --- a/resources/profiles/Volumic/process/Compatible speed - 0.15mm.json +++ b/resources/profiles/Volumic/process/Compatible speed - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Tp9t0BQZKkxCA8qZ", "name": "Compatible speed - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Tp9t0BQZKkxCA8qZ", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Compatible speed - 0.20mm.json b/resources/profiles/Volumic/process/Compatible speed - 0.20mm.json index 0e8644aa73..51faa259dd 100644 --- a/resources/profiles/Volumic/process/Compatible speed - 0.20mm.json +++ b/resources/profiles/Volumic/process/Compatible speed - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "z3fSJ5Y0JuhRQhOU", "name": "Compatible speed - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "z3fSJ5Y0JuhRQhOU", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Compatible speed - 0.25mm.json b/resources/profiles/Volumic/process/Compatible speed - 0.25mm.json index 28f94dda2c..3c90d17bf3 100644 --- a/resources/profiles/Volumic/process/Compatible speed - 0.25mm.json +++ b/resources/profiles/Volumic/process/Compatible speed - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "hfNxq9KnwJlS0gcr", "name": "Compatible speed - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "hfNxq9KnwJlS0gcr", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Compatible speed - 0.30mm.json b/resources/profiles/Volumic/process/Compatible speed - 0.30mm.json index 9f6d1ecb48..82334c0c28 100644 --- a/resources/profiles/Volumic/process/Compatible speed - 0.30mm.json +++ b/resources/profiles/Volumic/process/Compatible speed - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Pdg0wxAaJS0SR8AF", "name": "Compatible speed - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Pdg0wxAaJS0SR8AF", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Full performance - 0.10mm.json b/resources/profiles/Volumic/process/Full performance - 0.10mm.json index e672435e53..815eba6e85 100644 --- a/resources/profiles/Volumic/process/Full performance - 0.10mm.json +++ b/resources/profiles/Volumic/process/Full performance - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "BdckjC9G0PLHCMgf", "name": "Full performance - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "BdckjC9G0PLHCMgf", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Full performance - 0.15mm.json b/resources/profiles/Volumic/process/Full performance - 0.15mm.json index 71ca39fbab..654ca1a8e4 100644 --- a/resources/profiles/Volumic/process/Full performance - 0.15mm.json +++ b/resources/profiles/Volumic/process/Full performance - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "fx3iCV7mYY4FYrci", "name": "Full performance - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "fx3iCV7mYY4FYrci", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Full performance - 0.20mm.json b/resources/profiles/Volumic/process/Full performance - 0.20mm.json index 8834a822f0..d483ff14a7 100644 --- a/resources/profiles/Volumic/process/Full performance - 0.20mm.json +++ b/resources/profiles/Volumic/process/Full performance - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "vjm5CwY9lx6DOJZy", "name": "Full performance - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "vjm5CwY9lx6DOJZy", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Full performance - 0.25mm.json b/resources/profiles/Volumic/process/Full performance - 0.25mm.json index e977f22c25..67960e7751 100644 --- a/resources/profiles/Volumic/process/Full performance - 0.25mm.json +++ b/resources/profiles/Volumic/process/Full performance - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "q3EqyOZ87HZpBzvO", "name": "Full performance - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "q3EqyOZ87HZpBzvO", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Full performance - 0.30mm.json b/resources/profiles/Volumic/process/Full performance - 0.30mm.json index 8df0793a6a..e1fb5b97c2 100644 --- a/resources/profiles/Volumic/process/Full performance - 0.30mm.json +++ b/resources/profiles/Volumic/process/Full performance - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "EG1g0ef96ojgMo8K", "name": "Full performance - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "EG1g0ef96ojgMo8K", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Full performance DUAL - 0.10mm.json b/resources/profiles/Volumic/process/Full performance DUAL - 0.10mm.json index f58e4f6d66..3260c8d11c 100644 --- a/resources/profiles/Volumic/process/Full performance DUAL - 0.10mm.json +++ b/resources/profiles/Volumic/process/Full performance DUAL - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "WtBzcQwLoYPoNDbM", "name": "Full performance DUAL - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "WtBzcQwLoYPoNDbM", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Full performance DUAL - 0.15mm.json b/resources/profiles/Volumic/process/Full performance DUAL - 0.15mm.json index 90eceadcdb..a28a086055 100644 --- a/resources/profiles/Volumic/process/Full performance DUAL - 0.15mm.json +++ b/resources/profiles/Volumic/process/Full performance DUAL - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "QwgTvSeq1hLKGILo", "name": "Full performance DUAL - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "QwgTvSeq1hLKGILo", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Full performance DUAL - 0.20mm.json b/resources/profiles/Volumic/process/Full performance DUAL - 0.20mm.json index 8d674fa854..12b5e40946 100644 --- a/resources/profiles/Volumic/process/Full performance DUAL - 0.20mm.json +++ b/resources/profiles/Volumic/process/Full performance DUAL - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "BKpizWAIMDwwSaTu", "name": "Full performance DUAL - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "BKpizWAIMDwwSaTu", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Full performance DUAL - 0.25mm.json b/resources/profiles/Volumic/process/Full performance DUAL - 0.25mm.json index 586bc7220c..bfefd96ad8 100644 --- a/resources/profiles/Volumic/process/Full performance DUAL - 0.25mm.json +++ b/resources/profiles/Volumic/process/Full performance DUAL - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Oua2iEIMKavdJVHY", "name": "Full performance DUAL - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Oua2iEIMKavdJVHY", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Full performance DUAL - 0.30mm.json b/resources/profiles/Volumic/process/Full performance DUAL - 0.30mm.json index 915ac0527e..a90ed43159 100644 --- a/resources/profiles/Volumic/process/Full performance DUAL - 0.30mm.json +++ b/resources/profiles/Volumic/process/Full performance DUAL - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "W8bDRq0EMAasHC0C", "name": "Full performance DUAL - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "W8bDRq0EMAasHC0C", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Full performance VS30 - 0.10mm.json b/resources/profiles/Volumic/process/Full performance VS30 - 0.10mm.json index 4d6bba2889..ed305c1bf2 100644 --- a/resources/profiles/Volumic/process/Full performance VS30 - 0.10mm.json +++ b/resources/profiles/Volumic/process/Full performance VS30 - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "n3LCfOd6MlXqSaFM", "name": "Full performance VS30 - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "n3LCfOd6MlXqSaFM", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Full performance VS30 - 0.15mm.json b/resources/profiles/Volumic/process/Full performance VS30 - 0.15mm.json index f745a7d476..200ed5392d 100644 --- a/resources/profiles/Volumic/process/Full performance VS30 - 0.15mm.json +++ b/resources/profiles/Volumic/process/Full performance VS30 - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "WJxmd7QtAlD99oWO", "name": "Full performance VS30 - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "WJxmd7QtAlD99oWO", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Full performance VS30 - 0.20mm.json b/resources/profiles/Volumic/process/Full performance VS30 - 0.20mm.json index 9f6e156e04..701e10a173 100644 --- a/resources/profiles/Volumic/process/Full performance VS30 - 0.20mm.json +++ b/resources/profiles/Volumic/process/Full performance VS30 - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "6O8V3laqfmS31DpL", "name": "Full performance VS30 - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "6O8V3laqfmS31DpL", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Full performance VS30 - 0.25mm.json b/resources/profiles/Volumic/process/Full performance VS30 - 0.25mm.json index a10387ee11..213b48ff7a 100644 --- a/resources/profiles/Volumic/process/Full performance VS30 - 0.25mm.json +++ b/resources/profiles/Volumic/process/Full performance VS30 - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "q5Df9Zk0bBsl6tgn", "name": "Full performance VS30 - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "q5Df9Zk0bBsl6tgn", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Full performance VS30 - 0.30mm.json b/resources/profiles/Volumic/process/Full performance VS30 - 0.30mm.json index b642805e57..25ed597749 100644 --- a/resources/profiles/Volumic/process/Full performance VS30 - 0.30mm.json +++ b/resources/profiles/Volumic/process/Full performance VS30 - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "4xhjCaz0oSdj4dmz", "name": "Full performance VS30 - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "4xhjCaz0oSdj4dmz", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/High performance - 0.10mm.json b/resources/profiles/Volumic/process/High performance - 0.10mm.json index 5897a066ec..904fdafe90 100644 --- a/resources/profiles/Volumic/process/High performance - 0.10mm.json +++ b/resources/profiles/Volumic/process/High performance - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "gkRJ4aBb8nYiWWkQ", "name": "High performance - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "gkRJ4aBb8nYiWWkQ", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/High performance - 0.15mm.json b/resources/profiles/Volumic/process/High performance - 0.15mm.json index a0d2b72904..bd69845550 100644 --- a/resources/profiles/Volumic/process/High performance - 0.15mm.json +++ b/resources/profiles/Volumic/process/High performance - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "tZ9EVpNMRCnEh4QD", "name": "High performance - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "tZ9EVpNMRCnEh4QD", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/High performance - 0.20mm.json b/resources/profiles/Volumic/process/High performance - 0.20mm.json index d021e40286..d54872d1e0 100644 --- a/resources/profiles/Volumic/process/High performance - 0.20mm.json +++ b/resources/profiles/Volumic/process/High performance - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "yCDzVcIWjVgIyIRH", "name": "High performance - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "yCDzVcIWjVgIyIRH", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/High performance - 0.25mm.json b/resources/profiles/Volumic/process/High performance - 0.25mm.json index 87b210962c..3afdc4d88e 100644 --- a/resources/profiles/Volumic/process/High performance - 0.25mm.json +++ b/resources/profiles/Volumic/process/High performance - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "x0Q3hHsXoY33V4Df", "name": "High performance - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "x0Q3hHsXoY33V4Df", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/High performance - 0.30mm.json b/resources/profiles/Volumic/process/High performance - 0.30mm.json index 2a9f73d564..37f878eaa0 100644 --- a/resources/profiles/Volumic/process/High performance - 0.30mm.json +++ b/resources/profiles/Volumic/process/High performance - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "wtWZKy5RUZxBEKiA", "name": "High performance - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "wtWZKy5RUZxBEKiA", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/High performance DUAL - 0.10mm.json b/resources/profiles/Volumic/process/High performance DUAL - 0.10mm.json index b8615a5a79..0df99510d2 100644 --- a/resources/profiles/Volumic/process/High performance DUAL - 0.10mm.json +++ b/resources/profiles/Volumic/process/High performance DUAL - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "AQxzb91WKNnqyR4m", "name": "High performance DUAL - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "AQxzb91WKNnqyR4m", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/High performance DUAL - 0.15mm.json b/resources/profiles/Volumic/process/High performance DUAL - 0.15mm.json index aac928ed9e..91e8ac1d00 100644 --- a/resources/profiles/Volumic/process/High performance DUAL - 0.15mm.json +++ b/resources/profiles/Volumic/process/High performance DUAL - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "L4Ok3bi0ZUYayKei", "name": "High performance DUAL - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "L4Ok3bi0ZUYayKei", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/High performance DUAL - 0.20mm.json b/resources/profiles/Volumic/process/High performance DUAL - 0.20mm.json index 820c72f251..75b896c99b 100644 --- a/resources/profiles/Volumic/process/High performance DUAL - 0.20mm.json +++ b/resources/profiles/Volumic/process/High performance DUAL - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "VzveNihkhzpEd8YX", "name": "High performance DUAL - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "VzveNihkhzpEd8YX", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/High performance DUAL - 0.25mm.json b/resources/profiles/Volumic/process/High performance DUAL - 0.25mm.json index 48f0784784..fa0cb751ac 100644 --- a/resources/profiles/Volumic/process/High performance DUAL - 0.25mm.json +++ b/resources/profiles/Volumic/process/High performance DUAL - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "SH11Eth4ecxaSafR", "name": "High performance DUAL - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "SH11Eth4ecxaSafR", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/High performance DUAL - 0.30mm.json b/resources/profiles/Volumic/process/High performance DUAL - 0.30mm.json index 9129a45457..5cce5309cd 100644 --- a/resources/profiles/Volumic/process/High performance DUAL - 0.30mm.json +++ b/resources/profiles/Volumic/process/High performance DUAL - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Rheh3fgJfFugxKZL", "name": "High performance DUAL - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Rheh3fgJfFugxKZL", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/High performance VS30 - 0.10mm.json b/resources/profiles/Volumic/process/High performance VS30 - 0.10mm.json index 3b458847e5..590a01dc87 100644 --- a/resources/profiles/Volumic/process/High performance VS30 - 0.10mm.json +++ b/resources/profiles/Volumic/process/High performance VS30 - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "nfaAKkhQ6yt2AC7o", "name": "High performance VS30 - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "nfaAKkhQ6yt2AC7o", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/High performance VS30 - 0.15mm.json b/resources/profiles/Volumic/process/High performance VS30 - 0.15mm.json index fd5e05ef6f..d4c32db171 100644 --- a/resources/profiles/Volumic/process/High performance VS30 - 0.15mm.json +++ b/resources/profiles/Volumic/process/High performance VS30 - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Eb3wJrmzg2nzEwAm", "name": "High performance VS30 - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Eb3wJrmzg2nzEwAm", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/High performance VS30 - 0.20mm.json b/resources/profiles/Volumic/process/High performance VS30 - 0.20mm.json index 34369239bc..4832e76664 100644 --- a/resources/profiles/Volumic/process/High performance VS30 - 0.20mm.json +++ b/resources/profiles/Volumic/process/High performance VS30 - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "qWEOT65KoPG51AJW", "name": "High performance VS30 - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "qWEOT65KoPG51AJW", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/High performance VS30 - 0.25mm.json b/resources/profiles/Volumic/process/High performance VS30 - 0.25mm.json index 969f1daa28..12412183e9 100644 --- a/resources/profiles/Volumic/process/High performance VS30 - 0.25mm.json +++ b/resources/profiles/Volumic/process/High performance VS30 - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Co6sQp00KLUD50WN", "name": "High performance VS30 - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Co6sQp00KLUD50WN", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/High performance VS30 - 0.30mm.json b/resources/profiles/Volumic/process/High performance VS30 - 0.30mm.json index 147e0cd217..82052d7055 100644 --- a/resources/profiles/Volumic/process/High performance VS30 - 0.30mm.json +++ b/resources/profiles/Volumic/process/High performance VS30 - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "3qVuLHagvoHBu2yP", "name": "High performance VS30 - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "3qVuLHagvoHBu2yP", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.10mm.json b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.10mm.json index 3fbe07956d..f0b2f6883d 100644 --- a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.10mm.json +++ b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "3vksM99YF7pwEP3G", "name": "High speed (Stage 2) - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "3vksM99YF7pwEP3G", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.15mm.json b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.15mm.json index 7a4313160a..816c6a4db1 100644 --- a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.15mm.json +++ b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "9k0mROwMyk1hxZm1", "name": "High speed (Stage 2) - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "9k0mROwMyk1hxZm1", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.20mm.json b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.20mm.json index 91d998c170..78b4f5304c 100644 --- a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.20mm.json +++ b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "s7GVelf1PDb0Qy9g", "name": "High speed (Stage 2) - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "s7GVelf1PDb0Qy9g", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.25mm.json b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.25mm.json index a3277f67a7..d4f6bb4fcf 100644 --- a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.25mm.json +++ b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Kxk9C4GtJ5tiwqes", "name": "High speed (Stage 2) - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Kxk9C4GtJ5tiwqes", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.30mm.json b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.30mm.json index 76bfe21286..5f92ab82ab 100644 --- a/resources/profiles/Volumic/process/High speed (Stage 2) - 0.30mm.json +++ b/resources/profiles/Volumic/process/High speed (Stage 2) - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ireCZVAGHWDUN03m", "name": "High speed (Stage 2) - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "ireCZVAGHWDUN03m", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/High speed - 0.10mm.json b/resources/profiles/Volumic/process/High speed - 0.10mm.json index c86d7535c0..23af87c00a 100644 --- a/resources/profiles/Volumic/process/High speed - 0.10mm.json +++ b/resources/profiles/Volumic/process/High speed - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ClExqnoYEdZmnnOX", "name": "High speed - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "ClExqnoYEdZmnnOX", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/High speed - 0.15mm.json b/resources/profiles/Volumic/process/High speed - 0.15mm.json index 0e3da3a700..5591b5ce93 100644 --- a/resources/profiles/Volumic/process/High speed - 0.15mm.json +++ b/resources/profiles/Volumic/process/High speed - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Wk6UnqxF8mQm9sE6", "name": "High speed - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Wk6UnqxF8mQm9sE6", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/High speed - 0.20mm.json b/resources/profiles/Volumic/process/High speed - 0.20mm.json index c37503c724..73bd79c338 100644 --- a/resources/profiles/Volumic/process/High speed - 0.20mm.json +++ b/resources/profiles/Volumic/process/High speed - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "72tWDDDqVKtRwBFH", "name": "High speed - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "72tWDDDqVKtRwBFH", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/High speed - 0.25mm.json b/resources/profiles/Volumic/process/High speed - 0.25mm.json index 10286f7196..9013811c1a 100644 --- a/resources/profiles/Volumic/process/High speed - 0.25mm.json +++ b/resources/profiles/Volumic/process/High speed - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Qx4TTWaVVzXqRCJ4", "name": "High speed - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Qx4TTWaVVzXqRCJ4", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/High speed - 0.30mm.json b/resources/profiles/Volumic/process/High speed - 0.30mm.json index abc18e3fc1..ddd88376d5 100644 --- a/resources/profiles/Volumic/process/High speed - 0.30mm.json +++ b/resources/profiles/Volumic/process/High speed - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "6h7mK5XKws51vPov", "name": "High speed - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "6h7mK5XKws51vPov", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Normal performance - 0.10mm.json b/resources/profiles/Volumic/process/Normal performance - 0.10mm.json index 7bc3240b5e..82c8f70bbf 100644 --- a/resources/profiles/Volumic/process/Normal performance - 0.10mm.json +++ b/resources/profiles/Volumic/process/Normal performance - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "FTqjZjQPPR7L9pO1", "name": "Normal performance - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "FTqjZjQPPR7L9pO1", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Normal performance - 0.15mm.json b/resources/profiles/Volumic/process/Normal performance - 0.15mm.json index a274e1263a..9dc7c991a2 100644 --- a/resources/profiles/Volumic/process/Normal performance - 0.15mm.json +++ b/resources/profiles/Volumic/process/Normal performance - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "JY670KAkuqNKq1pD", "name": "Normal performance - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "JY670KAkuqNKq1pD", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Normal performance - 0.20mm.json b/resources/profiles/Volumic/process/Normal performance - 0.20mm.json index e03c5bdafd..db61c2882a 100644 --- a/resources/profiles/Volumic/process/Normal performance - 0.20mm.json +++ b/resources/profiles/Volumic/process/Normal performance - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "6xUkj1ATyvZ9n69E", "name": "Normal performance - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "6xUkj1ATyvZ9n69E", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Normal performance - 0.25mm.json b/resources/profiles/Volumic/process/Normal performance - 0.25mm.json index 3b1db4b002..6c23dde43c 100644 --- a/resources/profiles/Volumic/process/Normal performance - 0.25mm.json +++ b/resources/profiles/Volumic/process/Normal performance - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "J2ZwCE8TcdUDJy9u", "name": "Normal performance - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "J2ZwCE8TcdUDJy9u", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Normal performance - 0.30mm.json b/resources/profiles/Volumic/process/Normal performance - 0.30mm.json index b75c0433c3..5e1d299bfd 100644 --- a/resources/profiles/Volumic/process/Normal performance - 0.30mm.json +++ b/resources/profiles/Volumic/process/Normal performance - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "TikIASel3dJuzlIC", "name": "Normal performance - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "TikIASel3dJuzlIC", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Normal performance DUAL - 0.10mm.json b/resources/profiles/Volumic/process/Normal performance DUAL - 0.10mm.json index 2fdfb80a54..b5d4a6e280 100644 --- a/resources/profiles/Volumic/process/Normal performance DUAL - 0.10mm.json +++ b/resources/profiles/Volumic/process/Normal performance DUAL - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "CPvAoewpDOyAUZzz", "name": "Normal performance DUAL - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "CPvAoewpDOyAUZzz", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Normal performance DUAL - 0.15mm.json b/resources/profiles/Volumic/process/Normal performance DUAL - 0.15mm.json index b231cbe91b..0e9afca6d9 100644 --- a/resources/profiles/Volumic/process/Normal performance DUAL - 0.15mm.json +++ b/resources/profiles/Volumic/process/Normal performance DUAL - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "lxzarnB1H22cOqIl", "name": "Normal performance DUAL - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "lxzarnB1H22cOqIl", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Normal performance DUAL - 0.20mm.json b/resources/profiles/Volumic/process/Normal performance DUAL - 0.20mm.json index bed3e748ab..5155807f9c 100644 --- a/resources/profiles/Volumic/process/Normal performance DUAL - 0.20mm.json +++ b/resources/profiles/Volumic/process/Normal performance DUAL - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "GNPkW4cAsenc06Qj", "name": "Normal performance DUAL - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "GNPkW4cAsenc06Qj", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Normal performance DUAL - 0.25mm.json b/resources/profiles/Volumic/process/Normal performance DUAL - 0.25mm.json index 87596fc890..680cce596f 100644 --- a/resources/profiles/Volumic/process/Normal performance DUAL - 0.25mm.json +++ b/resources/profiles/Volumic/process/Normal performance DUAL - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "VvM6yKMGis2PyNHn", "name": "Normal performance DUAL - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "VvM6yKMGis2PyNHn", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Normal performance DUAL - 0.30mm.json b/resources/profiles/Volumic/process/Normal performance DUAL - 0.30mm.json index a389180199..b57cddff40 100644 --- a/resources/profiles/Volumic/process/Normal performance DUAL - 0.30mm.json +++ b/resources/profiles/Volumic/process/Normal performance DUAL - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ouPv4ZnFRqBIZTUQ", "name": "Normal performance DUAL - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "ouPv4ZnFRqBIZTUQ", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Normal performance VS30 - 0.10mm.json b/resources/profiles/Volumic/process/Normal performance VS30 - 0.10mm.json index fb120c03a5..6ad5f4ee3c 100644 --- a/resources/profiles/Volumic/process/Normal performance VS30 - 0.10mm.json +++ b/resources/profiles/Volumic/process/Normal performance VS30 - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "A1MeH5DTrbaapIvs", "name": "Normal performance VS30 - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "A1MeH5DTrbaapIvs", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Normal performance VS30 - 0.15mm.json b/resources/profiles/Volumic/process/Normal performance VS30 - 0.15mm.json index b95abd904f..c98275fcdc 100644 --- a/resources/profiles/Volumic/process/Normal performance VS30 - 0.15mm.json +++ b/resources/profiles/Volumic/process/Normal performance VS30 - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "RN31YrQ3X4sAgRji", "name": "Normal performance VS30 - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "RN31YrQ3X4sAgRji", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Normal performance VS30 - 0.20mm.json b/resources/profiles/Volumic/process/Normal performance VS30 - 0.20mm.json index 0657825c7b..067e282f0b 100644 --- a/resources/profiles/Volumic/process/Normal performance VS30 - 0.20mm.json +++ b/resources/profiles/Volumic/process/Normal performance VS30 - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "pW9nom8pyi48XeOB", "name": "Normal performance VS30 - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "pW9nom8pyi48XeOB", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Normal performance VS30 - 0.25mm.json b/resources/profiles/Volumic/process/Normal performance VS30 - 0.25mm.json index 0197bc775d..993043650d 100644 --- a/resources/profiles/Volumic/process/Normal performance VS30 - 0.25mm.json +++ b/resources/profiles/Volumic/process/Normal performance VS30 - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "O4mCyYEDLcYs9ksp", "name": "Normal performance VS30 - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "O4mCyYEDLcYs9ksp", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Normal performance VS30 - 0.30mm.json b/resources/profiles/Volumic/process/Normal performance VS30 - 0.30mm.json index 5f8a81f236..adf0a49d37 100644 --- a/resources/profiles/Volumic/process/Normal performance VS30 - 0.30mm.json +++ b/resources/profiles/Volumic/process/Normal performance VS30 - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Wl53R1wiaRjXyP4m", "name": "Normal performance VS30 - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Wl53R1wiaRjXyP4m", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.10mm.json b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.10mm.json index 7a4cca2086..fe50dbb494 100644 --- a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.10mm.json +++ b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "tc9ZLzQlKlARHNGw", "name": "Normal speed (Stage 2) - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "tc9ZLzQlKlARHNGw", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.15mm.json b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.15mm.json index 1b3bdfd473..832a7c9fde 100644 --- a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.15mm.json +++ b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "SIjHUj1PwWkFFffa", "name": "Normal speed (Stage 2) - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "SIjHUj1PwWkFFffa", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.20mm.json b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.20mm.json index 789a59c8e7..19e23678d4 100644 --- a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.20mm.json +++ b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "M0E4QeWLUVdWUHfJ", "name": "Normal speed (Stage 2) - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "M0E4QeWLUVdWUHfJ", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.25mm.json b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.25mm.json index 6b1a0c5fe3..98598db38c 100644 --- a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.25mm.json +++ b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "7RRVQg0tShBy6Xuj", "name": "Normal speed (Stage 2) - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "7RRVQg0tShBy6Xuj", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.30mm.json b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.30mm.json index 0243eff1b9..eb41b3f307 100644 --- a/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.30mm.json +++ b/resources/profiles/Volumic/process/Normal speed (Stage 2) - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "VeLRxlpx80B0fAVO", "name": "Normal speed (Stage 2) - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "VeLRxlpx80B0fAVO", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Normal speed - 0.10mm.json b/resources/profiles/Volumic/process/Normal speed - 0.10mm.json index 475b8436ca..4340058a3c 100644 --- a/resources/profiles/Volumic/process/Normal speed - 0.10mm.json +++ b/resources/profiles/Volumic/process/Normal speed - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "KYuX2erMe0Qnjqig", "name": "Normal speed - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "KYuX2erMe0Qnjqig", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Normal speed - 0.15mm.json b/resources/profiles/Volumic/process/Normal speed - 0.15mm.json index 5ee0b65a91..d66b440c70 100644 --- a/resources/profiles/Volumic/process/Normal speed - 0.15mm.json +++ b/resources/profiles/Volumic/process/Normal speed - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ulLTG505AlCQyOVT", "name": "Normal speed - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "ulLTG505AlCQyOVT", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Normal speed - 0.20mm.json b/resources/profiles/Volumic/process/Normal speed - 0.20mm.json index 18f07ba295..338f88e5ec 100644 --- a/resources/profiles/Volumic/process/Normal speed - 0.20mm.json +++ b/resources/profiles/Volumic/process/Normal speed - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "5VK09EV5nZFZ8tDX", "name": "Normal speed - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "5VK09EV5nZFZ8tDX", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Normal speed - 0.25mm.json b/resources/profiles/Volumic/process/Normal speed - 0.25mm.json index a0400b22e5..fa82c4e443 100644 --- a/resources/profiles/Volumic/process/Normal speed - 0.25mm.json +++ b/resources/profiles/Volumic/process/Normal speed - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "sKsaHEmeYNos7Ap3", "name": "Normal speed - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "sKsaHEmeYNos7Ap3", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Normal speed - 0.30mm.json b/resources/profiles/Volumic/process/Normal speed - 0.30mm.json index 227cda5c1e..755f8d5297 100644 --- a/resources/profiles/Volumic/process/Normal speed - 0.30mm.json +++ b/resources/profiles/Volumic/process/Normal speed - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "fLtovREOpasPunPM", "name": "Normal speed - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "fLtovREOpasPunPM", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.10mm.json b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.10mm.json index d80d3230e4..89c5d317b7 100644 --- a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.10mm.json +++ b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "v29Kc1X5AEVhYRk8", "name": "Very high speed (Stage 2) - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "v29Kc1X5AEVhYRk8", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.15mm.json b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.15mm.json index fea250b867..b7e8ef3198 100644 --- a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.15mm.json +++ b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "IFk4SdxdsDe9XHA7", "name": "Very high speed (Stage 2) - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "IFk4SdxdsDe9XHA7", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.20mm.json b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.20mm.json index b308dbbf7e..b72013724a 100644 --- a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.20mm.json +++ b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "rnRfy0wN7TWGyq6y", "name": "Very high speed (Stage 2) - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "rnRfy0wN7TWGyq6y", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.25mm.json b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.25mm.json index 004cc14719..230c508040 100644 --- a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.25mm.json +++ b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Trb33VeRJfEhjvyw", "name": "Very high speed (Stage 2) - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Trb33VeRJfEhjvyw", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.30mm.json b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.30mm.json index b5225c859e..fa1030d684 100644 --- a/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.30mm.json +++ b/resources/profiles/Volumic/process/Very high speed (Stage 2) - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "A7yh9LBPEQ0kX3w4", "name": "Very high speed (Stage 2) - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "A7yh9LBPEQ0kX3w4", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Volumic/process/Very high speed - 0.10mm.json b/resources/profiles/Volumic/process/Very high speed - 0.10mm.json index 1b1e9c9108..e17dc83210 100644 --- a/resources/profiles/Volumic/process/Very high speed - 0.10mm.json +++ b/resources/profiles/Volumic/process/Very high speed - 0.10mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "ZqsUCKAhvogcqdcv", "name": "Very high speed - 0.10mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "ZqsUCKAhvogcqdcv", "instantiation": "true", "layer_height": "0.1", "initial_layer_print_height": "0.1", diff --git a/resources/profiles/Volumic/process/Very high speed - 0.15mm.json b/resources/profiles/Volumic/process/Very high speed - 0.15mm.json index 7e657c6498..5dda960dd4 100644 --- a/resources/profiles/Volumic/process/Very high speed - 0.15mm.json +++ b/resources/profiles/Volumic/process/Very high speed - 0.15mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "Ept7P07GPaZjDkH1", "name": "Very high speed - 0.15mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "Ept7P07GPaZjDkH1", "instantiation": "true", "layer_height": "0.15", "initial_layer_print_height": "0.15", diff --git a/resources/profiles/Volumic/process/Very high speed - 0.20mm.json b/resources/profiles/Volumic/process/Very high speed - 0.20mm.json index 5f12b90d5e..57e3372edb 100644 --- a/resources/profiles/Volumic/process/Very high speed - 0.20mm.json +++ b/resources/profiles/Volumic/process/Very high speed - 0.20mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "1I77SBl6Oe7z8QVf", "name": "Very high speed - 0.20mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "1I77SBl6Oe7z8QVf", "instantiation": "true", "layer_height": "0.2", "initial_layer_print_height": "0.2", diff --git a/resources/profiles/Volumic/process/Very high speed - 0.25mm.json b/resources/profiles/Volumic/process/Very high speed - 0.25mm.json index eede1a2bf3..41ff717f9c 100644 --- a/resources/profiles/Volumic/process/Very high speed - 0.25mm.json +++ b/resources/profiles/Volumic/process/Very high speed - 0.25mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "qy4K1ha3a6cbW0sw", "name": "Very high speed - 0.25mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "qy4K1ha3a6cbW0sw", "instantiation": "true", "layer_height": "0.25", "initial_layer_print_height": "0.25", diff --git a/resources/profiles/Volumic/process/Very high speed - 0.30mm.json b/resources/profiles/Volumic/process/Very high speed - 0.30mm.json index b6148c6aa6..2f34c6107d 100644 --- a/resources/profiles/Volumic/process/Very high speed - 0.30mm.json +++ b/resources/profiles/Volumic/process/Very high speed - 0.30mm.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "4up2FChqWIEn6vYl", "name": "Very high speed - 0.30mm", - "from": "system", "inherits": "fdm_process_volumic_common", + "from": "system", + "setting_id": "4up2FChqWIEn6vYl", "instantiation": "true", "layer_height": "0.3", "initial_layer_print_height": "0.3", diff --git a/resources/profiles/Vzbot.json b/resources/profiles/Vzbot.json index a64b4807e8..04e239ed45 100644 --- a/resources/profiles/Vzbot.json +++ b/resources/profiles/Vzbot.json @@ -1,6 +1,6 @@ { "name": "Vzbot", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "Vzbot configurations", "machine_model_list": [ diff --git a/resources/profiles/Vzbot/filament/Generic ABS @Vzbot.json b/resources/profiles/Vzbot/filament/Generic ABS @Vzbot.json index bc59bdfea7..0fe03d3148 100644 --- a/resources/profiles/Vzbot/filament/Generic ABS @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic ABS @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Vzbot", - "inherits": "fdm_filament_abs", "renamed_from": "Vzbot Generic ABS", + "inherits": "fdm_filament_abs", "from": "system", "setting_id": "0gr3MwdhoGW44mbr", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Vzbot/filament/Generic ASA @Vzbot.json b/resources/profiles/Vzbot/filament/Generic ASA @Vzbot.json index 9495f5cb1e..4341eb7b9a 100644 --- a/resources/profiles/Vzbot/filament/Generic ASA @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic ASA @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ASA @Vzbot", - "inherits": "fdm_filament_asa", "renamed_from": "Vzbot Generic ASA", + "inherits": "fdm_filament_asa", "from": "system", "setting_id": "0MutZpaR9XVzUGGS", "filament_id": "OFLPAxz3", diff --git a/resources/profiles/Vzbot/filament/Generic PA @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PA @Vzbot.json index a5e39c829c..db0e5fcca0 100644 --- a/resources/profiles/Vzbot/filament/Generic PA @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PA @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Vzbot", - "inherits": "fdm_filament_pa", "renamed_from": "Vzbot Generic PA", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "fwiU6RaIAOV38A9B", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Vzbot/filament/Generic PA-CF @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PA-CF @Vzbot.json index 30a13910e0..3dba44eea0 100644 --- a/resources/profiles/Vzbot/filament/Generic PA-CF @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PA-CF @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA-CF @Vzbot", - "inherits": "fdm_filament_pa", "renamed_from": "Vzbot Generic PA-CF", + "inherits": "fdm_filament_pa", "from": "system", "setting_id": "q8DtJmdJUN3KFV3E", "filament_id": "OFQLcbps", diff --git a/resources/profiles/Vzbot/filament/Generic PC @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PC @Vzbot.json index e2fecd6301..bcb2a6e11e 100644 --- a/resources/profiles/Vzbot/filament/Generic PC @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PC @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PC @Vzbot", - "inherits": "fdm_filament_pc", "renamed_from": "Vzbot Generic PC", + "inherits": "fdm_filament_pc", "from": "system", "setting_id": "crcoB7BvhVnnHNaF", "filament_id": "OFLakOUI", diff --git a/resources/profiles/Vzbot/filament/Generic PETG @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PETG @Vzbot.json index bfb1f5af81..753b2816a3 100644 --- a/resources/profiles/Vzbot/filament/Generic PETG @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PETG @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Vzbot", - "inherits": "fdm_filament_pet", "renamed_from": "Vzbot Generic PETG", + "inherits": "fdm_filament_pet", "from": "system", "setting_id": "NInr0jEJnziZ1poM", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Vzbot/filament/Generic PLA @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PLA @Vzbot.json index ee77c2fd61..1953b3353f 100644 --- a/resources/profiles/Vzbot/filament/Generic PLA @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PLA @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Vzbot", - "inherits": "fdm_filament_pla", "renamed_from": "Vzbot Generic PLA", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "Skn1ODpcSXd2NFcH", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Vzbot/filament/Generic PLA-CF @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PLA-CF @Vzbot.json index 2fd8b03ee5..5b62fb3c69 100644 --- a/resources/profiles/Vzbot/filament/Generic PLA-CF @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PLA-CF @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA-CF @Vzbot", - "inherits": "fdm_filament_pla", "renamed_from": "Vzbot Generic PLA-CF", + "inherits": "fdm_filament_pla", "from": "system", "setting_id": "FETpZHhHj60hztGS", "filament_id": "OFWbdGsC", diff --git a/resources/profiles/Vzbot/filament/Generic PVA @Vzbot.json b/resources/profiles/Vzbot/filament/Generic PVA @Vzbot.json index f8b6793e74..fb81783434 100644 --- a/resources/profiles/Vzbot/filament/Generic PVA @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic PVA @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PVA @Vzbot", - "inherits": "fdm_filament_pva", "renamed_from": "Vzbot Generic PVA", + "inherits": "fdm_filament_pva", "from": "system", "setting_id": "3xgrPw1nCEUaKQwQ", "filament_id": "OFDvXujf", diff --git a/resources/profiles/Vzbot/filament/Generic TPU @Vzbot.json b/resources/profiles/Vzbot/filament/Generic TPU @Vzbot.json index 6ba3a3e9e4..5b705e9be6 100644 --- a/resources/profiles/Vzbot/filament/Generic TPU @Vzbot.json +++ b/resources/profiles/Vzbot/filament/Generic TPU @Vzbot.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic TPU @Vzbot", - "inherits": "fdm_filament_tpu", "renamed_from": "Vzbot Generic TPU", + "inherits": "fdm_filament_tpu", "from": "system", "setting_id": "eC3Pgdpbwi2amDbk", "filament_id": "OFgbpcy9", diff --git a/resources/profiles/WEMAKE3D.json b/resources/profiles/WEMAKE3D.json index feeeba132b..197bf820dd 100644 --- a/resources/profiles/WEMAKE3D.json +++ b/resources/profiles/WEMAKE3D.json @@ -1,6 +1,6 @@ { "name": "WEMAKE3D", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "0", "description": "WEMAKE3D configurations", "machine_model_list": [ diff --git a/resources/profiles/WEMAKE3D/machine/WEMAKE3D PhoenixProV1 0.2mm nozzle.json b/resources/profiles/WEMAKE3D/machine/WEMAKE3D PhoenixProV1 0.2mm nozzle.json index c83afd8d4b..8943d7551c 100644 --- a/resources/profiles/WEMAKE3D/machine/WEMAKE3D PhoenixProV1 0.2mm nozzle.json +++ b/resources/profiles/WEMAKE3D/machine/WEMAKE3D PhoenixProV1 0.2mm nozzle.json @@ -3,8 +3,8 @@ "name": "WEMAKE3D PhoenixProV1 0.2mm nozzle", "inherits": "fdm_machine_phoenixprov1_common", "from": "system", - "instantiation": "true", "setting_id": "XHK731uBkstR3hRp", + "instantiation": "true", "printer_model": "WEMAKE3D PhoenixProV1", "nozzle_diameter": [ "0.2" diff --git a/resources/profiles/Wanhao France.json b/resources/profiles/Wanhao France.json index 9087899761..6392daea8d 100644 --- a/resources/profiles/Wanhao France.json +++ b/resources/profiles/Wanhao France.json @@ -1,6 +1,6 @@ { "name": "Wanhao France", - "version": "02.04.00.05", + "version": "02.04.00.06", "force_update": "0", "description": "Wanhao France D12 configurations", "machine_model_list": [ diff --git a/resources/profiles/Wanhao France/machine/D12 230 PRO M2 DIRECT 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 230 PRO M2 DIRECT 0.4 nozzle.json index 865bad7e88..bcac8171fb 100644 --- a/resources/profiles/Wanhao France/machine/D12 230 PRO M2 DIRECT 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 230 PRO M2 DIRECT 0.4 nozzle.json @@ -45,12 +45,15 @@ "70" ], "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -58,36 +61,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle PoopTool.json b/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle PoopTool.json index 4f89e83c22..56e2bb4b37 100644 --- a/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle PoopTool.json +++ b/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle PoopTool.json @@ -44,12 +44,15 @@ "enable_filament_ramming": "0", "gcode_flavor": "marlin2", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -57,36 +60,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle.json index 6f3cdc3ee9..c29401182c 100644 --- a/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 230 PRO M2 MONO DUAL 0.4 nozzle.json @@ -44,12 +44,15 @@ "enable_filament_ramming": "0", "gcode_flavor": "marlin2", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -57,36 +60,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD DIRECT 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD DIRECT 0.4 nozzle.json index 366c7b8ad8..396ff66720 100644 --- a/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD DIRECT 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD DIRECT 0.4 nozzle.json @@ -44,12 +44,15 @@ ], "gcode_flavor": "klipper", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -57,36 +60,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle PoopTool.json b/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle PoopTool.json index 80934434bb..fe92961917 100644 --- a/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle PoopTool.json +++ b/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle PoopTool.json @@ -44,12 +44,15 @@ "enable_filament_ramming": "0", "gcode_flavor": "klipper", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -57,36 +60,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "400", "400" ], "machine_max_speed_y": [ + "400", "400" ], "machine_max_speed_z": [ + "12", "12" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.3", "0.3" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle.json index a5dd04837c..fcaa8861c3 100644 --- a/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 230 PRO SMARTPAD MONO DUAL 0.4 nozzle.json @@ -44,12 +44,15 @@ "enable_filament_ramming": "0", "gcode_flavor": "klipper", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -57,36 +60,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "400", "400" ], "machine_max_speed_y": [ + "400", "400" ], "machine_max_speed_z": [ + "12", "12" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.3", "0.3" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 300 PRO M2 DIRECT 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 300 PRO M2 DIRECT 0.4 nozzle.json index f7308b5838..6b630b8cca 100644 --- a/resources/profiles/Wanhao France/machine/D12 300 PRO M2 DIRECT 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 300 PRO M2 DIRECT 0.4 nozzle.json @@ -45,12 +45,15 @@ "70" ], "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -58,36 +61,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL 0.4 nozzle.json index e431c6ee24..fa70748531 100644 --- a/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL 0.4 nozzle.json @@ -45,12 +45,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -58,36 +61,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json index fe00d9421b..c53452a713 100644 --- a/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 300 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD DIRECT 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD DIRECT 0.4 nozzle.json index 81e3bfe34b..c16167cf3d 100644 --- a/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD DIRECT 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD DIRECT 0.4 nozzle.json @@ -45,12 +45,15 @@ "70" ], "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -58,36 +61,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL 0.4 nozzle.json index fb189c1c70..32f8fdd6b6 100644 --- a/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json index 694ea29dc1..d73cf4dc6c 100644 --- a/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 300 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1200", "1200" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 500 PRO M2 DIRECT 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 500 PRO M2 DIRECT 0.4 nozzle.json index 916c24cef6..2a201bcdce 100644 --- a/resources/profiles/Wanhao France/machine/D12 500 PRO M2 DIRECT 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 500 PRO M2 DIRECT 0.4 nozzle.json @@ -45,12 +45,15 @@ "70" ], "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -58,36 +61,47 @@ "500" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "800", "800" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL 0.4 nozzle.json index f168fa5fe5..df4f560839 100644 --- a/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL 0.4 nozzle.json @@ -45,12 +45,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -58,36 +61,47 @@ "500" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "800", "800" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json index 6b0c3af76c..04454aa072 100644 --- a/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 500 PRO M2 MONO DUAL PoopTool 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "800", "800" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD DIRECT 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD DIRECT 0.4 nozzle.json index d79e811b91..3cded186e9 100644 --- a/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD DIRECT 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD DIRECT 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "800", "800" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL 0.4 nozzle.json index 931c88e897..30fae3ceae 100644 --- a/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "800", "800" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json b/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json index 6f6bea0067..8a3489ecea 100644 --- a/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json +++ b/resources/profiles/Wanhao France/machine/D12 500 PRO SMARTPAD MONO DUAL PoopTool 0.4 nozzle.json @@ -46,12 +46,15 @@ ], "enable_filament_ramming": "0", "machine_max_acceleration_e": [ + "6000", "6000" ], "machine_max_acceleration_extruding": [ + "10000", "10000" ], "machine_max_acceleration_retracting": [ + "5000", "5000" ], "machine_max_acceleration_travel": [ @@ -59,36 +62,47 @@ "500" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "800", "800" ], "machine_max_acceleration_z": [ + "500", "500" ], "machine_max_speed_e": [ + "50", "50" ], "machine_max_speed_x": [ + "200", "200" ], "machine_max_speed_y": [ + "200", "200" ], "machine_max_speed_z": [ + "15", "15" ], "machine_max_jerk_e": [ + "2.5", "2.5" ], "machine_max_jerk_x": [ + "14", "14" ], "machine_max_jerk_y": [ + "14", "14" ], "machine_max_jerk_z": [ + "0.2", "0.2" ], "max_layer_height": [ diff --git a/resources/profiles/Wanhao France/machine/fdm_machine_common.json b/resources/profiles/Wanhao France/machine/fdm_machine_common.json index e72b821fa1..dc3764c3ef 100644 --- a/resources/profiles/Wanhao France/machine/fdm_machine_common.json +++ b/resources/profiles/Wanhao France/machine/fdm_machine_common.json @@ -112,7 +112,7 @@ "1" ], "support_multi_bed_types": "1", - "template_custom_gcode": ";;;;;;;;;;;;;;;;;;;;;;;;CUSTOM G-CODE;;;;;;;;;;;;;;;;;;;;;;;;\n{if curr_bed_type==\"Textured PEI Plate\"}\n SET_GCODE_OFFSET Z=-0.00\n{else}\nSET_GCODE_OFFSET Z=0.0\n{endif}\n{if curr_bed_type==\"Cool Plate\"}\n\n;available bed types are:\n;\"Cool Plate\"\n;\"Engineering Plate\"\n;\"High Temp Plate\"\n;\"Textured PEI Plate\"\n;;;;;;;;;;;;;;;;;;;;;;;;;CUSTOM G-CODE;;;;;;;;;;;;;;;;;;;;;;;;\n", + "template_custom_gcode": ";;;;;;;;;;;;;;;;;;;;;;;;CUSTOM G-CODE;;;;;;;;;;;;;;;;;;;;;;;;\n{if curr_bed_type==\"Textured PEI Plate\"}\n SET_GCODE_OFFSET Z=-0.00\n{else}\nSET_GCODE_OFFSET Z=0.0\n{endif}\n\n;available bed types are:\n;\"Cool Plate\"\n;\"Engineering Plate\"\n;\"High Temp Plate\"\n;\"Textured PEI Plate\"\n;;;;;;;;;;;;;;;;;;;;;;;;;CUSTOM G-CODE;;;;;;;;;;;;;;;;;;;;;;;;\n", "z_hop_types": "Normal Lift", "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", "default_print_profile": "0.16mm Optimal @Bambu Lab X1 Carbon 0.4 nozzle", diff --git a/resources/profiles/Wanhao.json b/resources/profiles/Wanhao.json index 96290c7712..8595e67dce 100644 --- a/resources/profiles/Wanhao.json +++ b/resources/profiles/Wanhao.json @@ -1,6 +1,6 @@ { "name": "Wanhao", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "Wanhao configurations", "machine_model_list": [ diff --git a/resources/profiles/Wanhao/machine/Wanhao D12-300 0.4 nozzle.json b/resources/profiles/Wanhao/machine/Wanhao D12-300 0.4 nozzle.json index b96b3ce2d6..d79784d794 100644 --- a/resources/profiles/Wanhao/machine/Wanhao D12-300 0.4 nozzle.json +++ b/resources/profiles/Wanhao/machine/Wanhao D12-300 0.4 nozzle.json @@ -23,45 +23,59 @@ ], "gcode_flavor": "marlin", "machine_max_acceleration_e": [ + "10000", "10000" ], "machine_max_acceleration_extruding": [ + "1000", "1000" ], "machine_max_acceleration_retracting": [ + "1000", "1000" ], "machine_max_acceleration_x": [ + "1000", "1000" ], "machine_max_acceleration_y": [ + "1000", "1000" ], "machine_max_acceleration_z": [ + "100", "100" ], "machine_max_speed_e": [ + "60", "60" ], "machine_max_speed_x": [ + "500", "500" ], "machine_max_speed_y": [ + "500", "500" ], "machine_max_speed_z": [ + "10", "10" ], "machine_max_jerk_e": [ + "5", "5" ], "machine_max_jerk_x": [ + "10", "10" ], "machine_max_jerk_y": [ + "10", "10" ], "machine_max_jerk_z": [ + "0.3", "0.3" ], "max_layer_height": [ diff --git a/resources/profiles/Z-Bolt.json b/resources/profiles/Z-Bolt.json index 7c16785c62..b441ab9a72 100644 --- a/resources/profiles/Z-Bolt.json +++ b/resources/profiles/Z-Bolt.json @@ -1,7 +1,7 @@ { "name": "Z-Bolt", "url": "", - "version": "02.04.00.03", + "version": "02.04.00.04", "force_update": "0", "description": "Z-Bolt configurations", "machine_model_list": [ diff --git a/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.4 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.4 nozzle.json index 10b5421797..492f873ff9 100644 --- a/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Z-Bolt 0.4 nozzle", - "inherits": "Generic ABS @Z-Bolt Base", "renamed_from": "Z-Bolt ABS;Generic ABS @Z-Bolt;Z-Bolt ABS @0.4 nozzle", + "inherits": "Generic ABS @Z-Bolt Base", "from": "system", "setting_id": "p97bQCnVyGgwMn2y", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.6 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.6 nozzle.json index ea89fac80f..d207982007 100644 --- a/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Z-Bolt 0.6 nozzle", - "inherits": "Generic ABS @Z-Bolt Base", "renamed_from": "Z-Bolt ABS @0.6 nozzle", + "inherits": "Generic ABS @Z-Bolt Base", "from": "system", "setting_id": "BQdgCL8lvVW7I8Dw", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.8 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.8 nozzle.json index 48c8a20136..a27dc9d803 100644 --- a/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic ABS @Z-Bolt 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS @Z-Bolt 0.8 nozzle", - "inherits": "Generic ABS @Z-Bolt Base", "renamed_from": "Z-Bolt ABS @0.8 nozzle", + "inherits": "Generic ABS @Z-Bolt Base", "from": "system", "setting_id": "Xn2L7IBp26Bb6G2K", "filament_id": "OFY9muEs", diff --git a/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.4 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.4 nozzle.json index 7ee03a1904..b3b5e1990b 100644 --- a/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HT @Z-Bolt 0.4 nozzle", - "inherits": "Generic ABS HT @Z-Bolt Base", "renamed_from": "Z-Bolt ABS HT;Generic ABS HT @Z-Bolt;Z-Bolt ABS HT @0.4 nozzle", + "inherits": "Generic ABS HT @Z-Bolt Base", "from": "system", "setting_id": "TDGj84iuRAL9R1d4", "filament_id": "OFsP8PKH", diff --git a/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.6 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.6 nozzle.json index 626fbe9977..b36d374bfe 100644 --- a/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HT @Z-Bolt 0.6 nozzle", - "inherits": "Generic ABS HT @Z-Bolt Base", "renamed_from": "Z-Bolt ABS HT @0.6 nozzle", + "inherits": "Generic ABS HT @Z-Bolt Base", "from": "system", "setting_id": "2AKxm2VhVlL2vMM1", "filament_id": "OFsP8PKH", diff --git a/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.8 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.8 nozzle.json index feb932dcdb..8d3db4162a 100644 --- a/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic ABS HT @Z-Bolt 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic ABS HT @Z-Bolt 0.8 nozzle", - "inherits": "Generic ABS HT @Z-Bolt Base", "renamed_from": "Z-Bolt ABS HT @0.8 nozzle", + "inherits": "Generic ABS HT @Z-Bolt Base", "from": "system", "setting_id": "ztusMudd96Ns3Ip0", "filament_id": "OFsP8PKH", diff --git a/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.4 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.4 nozzle.json index c09de55efa..9071bde80a 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Z-Bolt 0.4 nozzle", - "inherits": "Generic PA @Z-Bolt Base", "renamed_from": "Z-Bolt PA;Generic PA @Z-Bolt;Z-Bolt PA @0.4 nozzle", + "inherits": "Generic PA @Z-Bolt Base", "from": "system", "setting_id": "zuvJBWxHOiPMyExQ", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.6 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.6 nozzle.json index d6886e6b1e..35c7e3352f 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Z-Bolt 0.6 nozzle", - "inherits": "Generic PA @Z-Bolt Base", "renamed_from": "Z-Bolt PA @0.6 nozzle", + "inherits": "Generic PA @Z-Bolt Base", "from": "system", "setting_id": "MB0n4BeDFEI25yTe", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.8 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.8 nozzle.json index 12a005431f..f50e82a0d9 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PA @Z-Bolt 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PA @Z-Bolt 0.8 nozzle", - "inherits": "Generic PA @Z-Bolt Base", "renamed_from": "Z-Bolt PA @0.8 nozzle", + "inherits": "Generic PA @Z-Bolt Base", "from": "system", "setting_id": "WZc4C1f6cPG8HZR3", "filament_id": "OFg8ndtj", diff --git a/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.4 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.4 nozzle.json index a28c4bc1c3..3ba2d3f680 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Z-Bolt 0.4 nozzle", - "inherits": "Generic PETG @Z-Bolt Base", "renamed_from": "Z-Bolt PETG;Generic PETG @Z-Bolt;Z-Bolt PETG @0.4 nozzle", + "inherits": "Generic PETG @Z-Bolt Base", "from": "system", "setting_id": "LWwbNXs8bf1iGELi", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.6 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.6 nozzle.json index 15aab3fe46..2eea58f874 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Z-Bolt 0.6 nozzle", - "inherits": "Generic PETG @Z-Bolt Base", "renamed_from": "Z-Bolt PETG @0.6 nozzle", + "inherits": "Generic PETG @Z-Bolt Base", "from": "system", "setting_id": "w4HVBbunzssG9j3s", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.8 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.8 nozzle.json index 4fe8b41490..5ff0c85771 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PETG @Z-Bolt 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PETG @Z-Bolt 0.8 nozzle", - "inherits": "Generic PETG @Z-Bolt Base", "renamed_from": "Z-Bolt PETG @0.8 nozzle", + "inherits": "Generic PETG @Z-Bolt Base", "from": "system", "setting_id": "TnLZ0vOVjIjng3u0", "filament_id": "OFYPdQJh", diff --git a/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.4 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.4 nozzle.json index 527888a93f..d5cc4c99aa 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.4 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Z-Bolt 0.4 nozzle", - "inherits": "Generic PLA @Z-Bolt Base", "renamed_from": "Z-Bolt PLA;Generic PLA @Z-Bolt;Z-Bolt PLA @0.4 nozzle", + "inherits": "Generic PLA @Z-Bolt Base", "from": "system", "setting_id": "0MfamDPH1L6sMRff", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.6 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.6 nozzle.json index af58bff7c5..e35e0b7a99 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.6 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Z-Bolt 0.6 nozzle", - "inherits": "Generic PLA @Z-Bolt Base", "renamed_from": "Z-Bolt PLA @0.6 nozzle", + "inherits": "Generic PLA @Z-Bolt Base", "from": "system", "setting_id": "tdq9Ye9GLpZXlak6", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.8 nozzle.json b/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.8 nozzle.json index dbe507507b..f86a0730bc 100644 --- a/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/filament/Generic PLA @Z-Bolt 0.8 nozzle.json @@ -1,8 +1,8 @@ { "type": "filament", "name": "Generic PLA @Z-Bolt 0.8 nozzle", - "inherits": "Generic PLA @Z-Bolt Base", "renamed_from": "Z-Bolt PLA @0.8 nozzle", + "inherits": "Generic PLA @Z-Bolt Base", "from": "system", "setting_id": "GKtc9mJusUZJD6kx", "filament_id": "OFDSrzZ8", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.4 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.4 nozzle.json index da04d25c6c..ee6b691a52 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.4 nozzle.json @@ -22,9 +22,11 @@ "0.08" ], "retraction_length": [ + "0.6", "0.6" ], "retraction_minimum_travel": [ + "1", "1" ], "change_filament_gcode": "G91\nG1 Z{z_hop[0]} F1000\nG90", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.6 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.6 nozzle.json index 309b3292d8..63748d753f 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.6 nozzle.json @@ -23,9 +23,11 @@ "0.12" ], "retraction_length": [ + "0.7", "0.7" ], "retraction_minimum_travel": [ + "2", "2" ], "thumbnails": "144x144/PNG,900x900/PNG", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.8 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.8 nozzle.json index 83f7fa507a..482a1ac26b 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S1000 Dual 0.8 nozzle.json @@ -23,12 +23,15 @@ "0.16" ], "retraction_length": [ + "0.8", "0.8" ], "retract_length_toolchange": [ + "3", "3" ], "retraction_minimum_travel": [ + "3", "3" ], "thumbnails": "144x144/PNG,900x900/PNG", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.4 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.4 nozzle.json index c461088460..b9b6d11f41 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.4 nozzle.json @@ -22,9 +22,11 @@ "0.08" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_minimum_travel": [ + "1", "1" ], "change_filament_gcode": "G91\nG1 Z{z_hop[0]} F1000\nG90", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.6 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.6 nozzle.json index 8e8cc70b43..8f99043bb0 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.6 nozzle.json @@ -23,9 +23,11 @@ "0.12" ], "retraction_length": [ + "1.4", "1.4" ], "retraction_minimum_travel": [ + "2", "2" ] } diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.8 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.8 nozzle.json index 506b51678b..b2c7cceef7 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S300 Dual 0.8 nozzle.json @@ -23,12 +23,15 @@ "0.16" ], "retraction_length": [ + "3", "3" ], "retract_length_toolchange": [ + "3", "3" ], "retraction_minimum_travel": [ + "3", "3" ] } diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.4 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.4 nozzle.json index d42c0e90f6..984bd4f36c 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.4 nozzle.json @@ -22,9 +22,11 @@ "0.08" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_minimum_travel": [ + "1", "1" ], "change_filament_gcode": "G91\nG1 Z{z_hop[0]} F1000\nG90", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.6 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.6 nozzle.json index 6664864f65..55bfcc4f2f 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.6 nozzle.json @@ -23,9 +23,11 @@ "0.12" ], "retraction_length": [ + "1.4", "1.4" ], "retraction_minimum_travel": [ + "2", "2" ] } diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.8 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.8 nozzle.json index 005c177fcf..2e57b6f3fa 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S400 Dual 0.8 nozzle.json @@ -23,12 +23,15 @@ "0.16" ], "retraction_length": [ + "3", "3" ], "retract_length_toolchange": [ + "3", "3" ], "retraction_minimum_travel": [ + "3", "3" ] } diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.4 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.4 nozzle.json index 5c2e417534..c53c5325a4 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.4 nozzle.json @@ -22,9 +22,11 @@ "0.08" ], "retraction_length": [ + "0.8", "0.8" ], "retraction_minimum_travel": [ + "1", "1" ], "change_filament_gcode": "G91\nG1 Z{z_hop[0]} F1000\nG90", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.6 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.6 nozzle.json index c15bf491f1..420c018e8c 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.6 nozzle.json @@ -23,9 +23,11 @@ "0.12" ], "retraction_length": [ + "1.4", "1.4" ], "retraction_minimum_travel": [ + "2", "2" ] } diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.8 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.8 nozzle.json index f51e1af0d8..5e1d2a0e99 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S600 Dual 0.8 nozzle.json @@ -23,12 +23,15 @@ "0.16" ], "retraction_length": [ + "3", "3" ], "retract_length_toolchange": [ + "3", "3" ], "retraction_minimum_travel": [ + "3", "3" ] } diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.4 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.4 nozzle.json index 1e204e9f5c..168b120746 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.4 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.4 nozzle.json @@ -30,62 +30,92 @@ "#018001" ], "machine_max_acceleration_e": [ + "1500", + "1500", "1500", "1500" ], "machine_max_acceleration_extruding": [ + "2500", + "2500", "2500", "2500" ], "machine_max_acceleration_retracting": [ + "1500", + "1500", "1500", "1500" ], "machine_max_acceleration_travel": [ + "9000", + "9000", "9000", "9000" ], "machine_max_acceleration_x": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_y": [ + "20000", + "20000", "20000", "20000" ], "machine_max_acceleration_z": [ + "12", + "12", "12", "12" ], "machine_max_speed_e": [ + "30", + "30", "30", "30" ], "machine_max_speed_x": [ + "500", + "200", "500", "200" ], "machine_max_speed_y": [ + "500", + "200", "500", "200" ], "machine_max_speed_z": [ + "20", + "20", "20", "20" ], "machine_max_jerk_e": [ + "2.5", + "2.5", "2.5", "2.5" ], "machine_max_jerk_x": [ + "9", + "9", "9", "9" ], "machine_max_jerk_y": [ + "9", + "9", "9", "9" ], "machine_max_jerk_z": [ + "3", + "3", "3", "3" ], @@ -107,27 +137,37 @@ "extruder_clearance_height_to_rod": "70", "extruder_clearance_height_to_lid": "200", "retraction_minimum_travel": [ + "1", "1" ], "retract_before_wipe": [ + "0%", "0%" ], "retraction_length": [ + "0.6", "0.6" ], "retract_length_toolchange": [ + "2", "2" ], "z_hop": [ + "1", "1" ], "retraction_speed": [ + "35", "35" ], "deretraction_speed": [ + "35", "35" ], - "nozzle_type": "hardened_steel", + "nozzle_type": [ + "hardened_steel", + "hardened_steel" + ], "machine_tool_change_time": "1", "support_chamber_temp_control": "1", "change_filament_gcode": "G91\nG1 Z{z_hop[0]} F1000\nG90", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.6 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.6 nozzle.json index 5c4fc79417..4180f78364 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.6 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.6 nozzle.json @@ -23,9 +23,11 @@ "0.12" ], "retraction_length": [ + "0.7", "0.7" ], "retraction_minimum_travel": [ + "2", "2" ], "thumbnails": "144x144/PNG,900x900/PNG", diff --git a/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.8 nozzle.json b/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.8 nozzle.json index 83fc5abc56..6b21d84d0f 100644 --- a/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.8 nozzle.json +++ b/resources/profiles/Z-Bolt/machine/Z-Bolt S800 Dual 0.8 nozzle.json @@ -23,12 +23,15 @@ "0.16" ], "retraction_length": [ + "0.8", "0.8" ], "retract_length_toolchange": [ + "3", "3" ], "retraction_minimum_travel": [ + "3", "3" ], "thumbnails": "144x144/PNG,900x900/PNG", diff --git a/resources/profiles/iQ.json b/resources/profiles/iQ.json index 1148b112f3..f6c8c1cab0 100644 --- a/resources/profiles/iQ.json +++ b/resources/profiles/iQ.json @@ -1,6 +1,6 @@ { "name": "innovatiQ", - "version": "02.04.00.04", + "version": "02.04.00.05", "force_update": "1", "description": "innovatiQ configuration", "machine_model_list": [ diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json index d0150d76e4..ef337f49eb 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json @@ -34,6 +34,8 @@ ], "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.4 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.4 nozzle.json index 0fe6cccdd7..b02954271f 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.4 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.4 nozzle.json @@ -33,6 +33,8 @@ ], "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json index efb586ab4b..de636867a2 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json @@ -34,6 +34,8 @@ ], "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json index 3758f03508..a5b99e26ec 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json @@ -34,6 +34,8 @@ ], "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json index 7409d9e6c6..3507d2e57a 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json @@ -33,6 +33,8 @@ ], "machine_end_gcode": "G1 X10 F3000 ; home X axis\nG1 Y10 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\n{if nozzle_temperature_initial_layer[current_extruder]>350}M140 S80{endif} ; Keep bed hot for easy part removal from PEI sheet\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], @@ -132,10 +134,14 @@ "Normal Lift" ], "machine_max_acceleration_x": [ + "1500", + "1500", "1500", "1500" ], "machine_max_acceleration_y": [ + "1500", + "1500", "1500", "1500" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json index 484f9275bf..6f9129bd9c 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json @@ -33,6 +33,8 @@ ], "machine_end_gcode": "G1 X10 F3000 ; home X axis\nG1 Y10 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\n{if nozzle_temperature_initial_layer[current_extruder]>350}M140 S80{endif} ; Keep bed hot for easy part removal from PEI sheet\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], @@ -132,10 +134,14 @@ "Normal Lift" ], "machine_max_acceleration_x": [ + "1500", + "1500", "1500", "1500" ], "machine_max_acceleration_y": [ + "1500", + "1500", "1500", "1500" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json index 6a12dcaaa0..7f8bdef3ff 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json @@ -33,6 +33,8 @@ ], "machine_end_gcode": "G1 X10 F3000 ; home X axis\nG1 Y10 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\n{if nozzle_temperature_initial_layer[current_extruder]>350}M140 S80{endif} ; Keep bed hot for easy part removal from PEI sheet\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], @@ -132,10 +134,14 @@ "Normal Lift" ], "machine_max_acceleration_x": [ + "1500", + "1500", "1500", "1500" ], "machine_max_acceleration_y": [ + "1500", + "1500", "1500", "1500" ], diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json index 76fe177a16..ab1e17cd04 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json @@ -33,6 +33,8 @@ ], "machine_end_gcode": "G1 X10 F3000 ; home X axis\nG1 Y10 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\n{if nozzle_temperature_initial_layer[current_extruder]>350}M140 S80{endif} ; Keep bed hot for easy part removal from PEI sheet\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", "machine_max_speed_z": [ + "15", + "12", "15", "12" ], @@ -132,10 +134,14 @@ "Normal Lift" ], "machine_max_acceleration_x": [ + "1500", + "1500", "1500", "1500" ], "machine_max_acceleration_y": [ + "1500", + "1500", "1500", "1500" ], diff --git a/resources/profiles/re3D.json b/resources/profiles/re3D.json index da34373d47..1a9e2ec591 100644 --- a/resources/profiles/re3D.json +++ b/resources/profiles/re3D.json @@ -1,7 +1,7 @@ { "name": "re3D", "url": "", - "version": "03.00.11", + "version": "03.00.12", "force_update": "0", "description": "re3D configurations", "machine_model_list": [ diff --git a/resources/profiles/re3D/filament/fdm_filament_pc.json b/resources/profiles/re3D/filament/fdm_filament_pc.json index 46e7670b93..58bd1fcb5f 100644 --- a/resources/profiles/re3D/filament/fdm_filament_pc.json +++ b/resources/profiles/re3D/filament/fdm_filament_pc.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "fdm_filament_pc", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "filament_type": [ "PC" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/fdm_filament_pet.json b/resources/profiles/re3D/filament/fdm_filament_pet.json index 3aab46b0d5..1366d9007d 100644 --- a/resources/profiles/re3D/filament/fdm_filament_pet.json +++ b/resources/profiles/re3D/filament/fdm_filament_pet.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "fdm_filament_pet", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "filament_type": [ "PETG" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/fdm_filament_pla.json b/resources/profiles/re3D/filament/fdm_filament_pla.json index b678250264..afb8d68adf 100644 --- a/resources/profiles/re3D/filament/fdm_filament_pla.json +++ b/resources/profiles/re3D/filament/fdm_filament_pla.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "fdm_filament_pla", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "filament_type": [ "PLA" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/fdm_filament_pp.json b/resources/profiles/re3D/filament/fdm_filament_pp.json index 16a1c9705d..2eb4a7e3e5 100644 --- a/resources/profiles/re3D/filament/fdm_filament_pp.json +++ b/resources/profiles/re3D/filament/fdm_filament_pp.json @@ -1,10 +1,10 @@ { "type": "filament", "name": "fdm_filament_pp", + "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "inherits": "fdm_filament_common", "filament_type": [ "PP" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D PC @0.4 nozzle.json b/resources/profiles/re3D/filament/re3D PC @0.4 nozzle.json index aa4a0baa91..c449570508 100644 --- a/resources/profiles/re3D/filament/re3D PC @0.4 nozzle.json +++ b/resources/profiles/re3D/filament/re3D PC @0.4 nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", "name": "re3D PC @0.4 nozzle", - "from": "system", "renamed_from": "re3D PC", - "instantiation": "true", "inherits": "fdm_filament_pc", - "filament_id": "OFU3QXL7", + "from": "system", "setting_id": "6yqRE2eSyER7X82N", + "filament_id": "OFU3QXL7", + "instantiation": "true", "filament_settings_id": [ "re3D PC @0.4 nozzle" ], @@ -174,4 +174,4 @@ "filament_stamping_distance": [ "0" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D PC @0.8 nozzle.json b/resources/profiles/re3D/filament/re3D PC @0.8 nozzle.json index 370a16baca..cd8fb98c77 100644 --- a/resources/profiles/re3D/filament/re3D PC @0.8 nozzle.json +++ b/resources/profiles/re3D/filament/re3D PC @0.8 nozzle.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "re3D PC @0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pc", - "filament_id": "OFU3QXL7", + "from": "system", "setting_id": "YVPbVSiVCzjp5ynf", + "filament_id": "OFU3QXL7", + "instantiation": "true", "filament_settings_id": [ "re3D PC @0.8 nozzle" ], @@ -173,4 +173,4 @@ "filament_stamping_distance": [ "0" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D PETG @0.4 nozzle.json b/resources/profiles/re3D/filament/re3D PETG @0.4 nozzle.json index 444fa42c55..d855ba13db 100644 --- a/resources/profiles/re3D/filament/re3D PETG @0.4 nozzle.json +++ b/resources/profiles/re3D/filament/re3D PETG @0.4 nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", "name": "re3D PETG @0.4 nozzle", - "from": "system", "renamed_from": "re3D PETG", - "instantiation": "true", "inherits": "fdm_filament_pet", - "filament_id": "OF3F63OE", + "from": "system", "setting_id": "epcrSCwjgRXMycBx", + "filament_id": "OF3F63OE", + "instantiation": "true", "filament_settings_id": [ "re3D PETG @0.4 nozzle" ], @@ -174,4 +174,4 @@ "filament_stamping_distance": [ "0" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D PETG @0.8 nozzle.json b/resources/profiles/re3D/filament/re3D PETG @0.8 nozzle.json index 93ae0e65a2..188406d9b6 100644 --- a/resources/profiles/re3D/filament/re3D PETG @0.8 nozzle.json +++ b/resources/profiles/re3D/filament/re3D PETG @0.8 nozzle.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "re3D PETG @0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pet", - "filament_id": "OF3F63OE", + "from": "system", "setting_id": "MoQie1JMlUeH0BwR", + "filament_id": "OF3F63OE", + "instantiation": "true", "filament_settings_id": [ "re3D PETG @0.8 nozzle" ], @@ -173,4 +173,4 @@ "filament_stamping_distance": [ "0" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D PLA @0.4 nozzle.json b/resources/profiles/re3D/filament/re3D PLA @0.4 nozzle.json index 0314778218..dcd1eda8dd 100644 --- a/resources/profiles/re3D/filament/re3D PLA @0.4 nozzle.json +++ b/resources/profiles/re3D/filament/re3D PLA @0.4 nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", "name": "re3D PLA @0.4 nozzle", - "from": "system", "renamed_from": "re3D PLA", - "instantiation": "true", "inherits": "fdm_filament_pla", - "filament_id": "OFRyOsZj", + "from": "system", "setting_id": "M8OOntNjjDBR4W32", + "filament_id": "OFRyOsZj", + "instantiation": "true", "filament_settings_id": [ "re3D PLA @0.4 nozzle" ], @@ -175,4 +175,4 @@ "filament_stamping_distance": [ "0" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D PLA @0.8 nozzle.json b/resources/profiles/re3D/filament/re3D PLA @0.8 nozzle.json index f537d9316c..0af2e0ac5e 100644 --- a/resources/profiles/re3D/filament/re3D PLA @0.8 nozzle.json +++ b/resources/profiles/re3D/filament/re3D PLA @0.8 nozzle.json @@ -1,11 +1,11 @@ { "type": "filament", "name": "re3D PLA @0.8 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pla", - "filament_id": "OFRyOsZj", + "from": "system", "setting_id": "SpF19Y2sSYbPHyxz", + "filament_id": "OFRyOsZj", + "instantiation": "true", "filament_settings_id": [ "re3D PLA @0.8 nozzle" ], @@ -174,4 +174,4 @@ "filament_stamping_distance": [ "0" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D rPETG @0.8 nozzle.json b/resources/profiles/re3D/filament/re3D rPETG @0.8 nozzle.json index 5bc3c037bf..cdbb1e4a60 100644 --- a/resources/profiles/re3D/filament/re3D rPETG @0.8 nozzle.json +++ b/resources/profiles/re3D/filament/re3D rPETG @0.8 nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFmCOW2Y", - "setting_id": "WlELqPVnuL7DaTxs", "name": "re3D rPETG @0.8 nozzle", - "from": "system", "renamed_from": "re3D Greengate rPETG @0.8 nozzle;re3D rPETG;re3D Greengate rPETG", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "WlELqPVnuL7DaTxs", + "filament_id": "OFmCOW2Y", + "instantiation": "true", "nozzle_temperature_initial_layer": [ "0" ], @@ -117,4 +117,4 @@ "re3D GigabotX 2 XLT 0.8 nozzle", "re3D TerabotX 2 0.8 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D rPETG @1.75 nozzle.json b/resources/profiles/re3D/filament/re3D rPETG @1.75 nozzle.json index 888880055f..06c9f7ade1 100644 --- a/resources/profiles/re3D/filament/re3D rPETG @1.75 nozzle.json +++ b/resources/profiles/re3D/filament/re3D rPETG @1.75 nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFmCOW2Y", - "setting_id": "sHzO2S3mmE6Iqs2O", "name": "re3D rPETG @1.75 nozzle", - "from": "system", "renamed_from": "re3D Greengate rPETG @1.75 nozzle", - "instantiation": "true", "inherits": "fdm_filament_pet", + "from": "system", + "setting_id": "sHzO2S3mmE6Iqs2O", + "filament_id": "OFmCOW2Y", + "instantiation": "true", "nozzle_temperature_initial_layer": [ "0" ], @@ -117,4 +117,4 @@ "re3D GigabotX 2 XLT 1.75 nozzle", "re3D TerabotX 2 1.75 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D rPP @0.8 nozzle.json b/resources/profiles/re3D/filament/re3D rPP @0.8 nozzle.json index 0b8b99eda1..b663a0dbce 100644 --- a/resources/profiles/re3D/filament/re3D rPP @0.8 nozzle.json +++ b/resources/profiles/re3D/filament/re3D rPP @0.8 nozzle.json @@ -1,12 +1,12 @@ { "type": "filament", - "filament_id": "OFfHGM1D", - "setting_id": "i9ii0b7qFYWnkGSq", "name": "re3D rPP @0.8 nozzle", - "from": "system", "renamed_from": "re3D rPP", - "instantiation": "true", "inherits": "fdm_filament_pp", + "from": "system", + "setting_id": "i9ii0b7qFYWnkGSq", + "filament_id": "OFfHGM1D", + "instantiation": "true", "filament_type": [ "PP" ], @@ -63,4 +63,4 @@ "re3D GigabotX 2 XLT 0.8 nozzle", "re3D TerabotX 2 0.8 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/filament/re3D rPP @1.75 nozzle.json b/resources/profiles/re3D/filament/re3D rPP @1.75 nozzle.json index e0b8574ab7..fe56a99f39 100644 --- a/resources/profiles/re3D/filament/re3D rPP @1.75 nozzle.json +++ b/resources/profiles/re3D/filament/re3D rPP @1.75 nozzle.json @@ -1,11 +1,11 @@ { "type": "filament", - "filament_id": "OFfHGM1D", - "setting_id": "356nOwsfGLI3CNqU", "name": "re3D rPP @1.75 nozzle", - "from": "system", - "instantiation": "true", "inherits": "fdm_filament_pp", + "from": "system", + "setting_id": "356nOwsfGLI3CNqU", + "filament_id": "OFfHGM1D", + "instantiation": "true", "filament_type": [ "PP" ], @@ -62,4 +62,4 @@ "re3D GigabotX 2 XLT 1.75 nozzle", "re3D TerabotX 2 1.75 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/machine/fdm_re3D_common.json b/resources/profiles/re3D/machine/fdm_re3D_common.json index b8922e2fb9..3924573048 100644 --- a/resources/profiles/re3D/machine/fdm_re3D_common.json +++ b/resources/profiles/re3D/machine/fdm_re3D_common.json @@ -1,9 +1,11 @@ { + "type": "machine", + "name": "fdm_re3D_common", + "inherits": "fdm_machine_common", + "instantiation": "false", "bed_exclude_area": [ "0x0" ], - "instantiation": "false", - "type": "machine", "deretraction_speed": [ "30", "30" @@ -16,13 +18,11 @@ "extruders_count": [ "2" ], - "inherits": "fdm_machine_common", "machine_end_gcode": "G92 E0\nTURN_OFF_HEATERS\nG28 X Y\nM18\nM107", "machine_start_gcode": "M83 ; Use relative extrusion distances\nG28 ; Home all axes\nM140 S{first_layer_bed_temperature[initial_tool]} ; Start heating bed\nM190 S{first_layer_bed_temperature[initial_tool]} ; Wait for bed to reach temperature\n\nT{initial_tool}\n\n\n; ---------------------------\n; HEAT THE USED TOOL\n; ---------------------------\n{if is_extruder_used[initial_tool]}\nM104 T{initial_tool} S{first_layer_temperature[initial_tool]} ; Preheat active extruder to first layer temperature\nM109 T{initial_tool} S{first_layer_temperature[initial_tool]} ; Wait for active extruder to reach temperature\n{endif}\n\nG1 F18000\nG4 S0\nG92 E0", "machine_tool_change_time": [ "90" ], - "name": "fdm_re3D_common", "printer_technology": "FFF", "retract_before_wipe": [ "70%", @@ -128,4 +128,4 @@ ], "wipe_tower_type": "type2", "z_offset": "0" -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/machine/re3D Gigabot 4 0.4 nozzle.json b/resources/profiles/re3D/machine/re3D Gigabot 4 0.4 nozzle.json index 6ab8f4ed61..394edef4ba 100644 --- a/resources/profiles/re3D/machine/re3D Gigabot 4 0.4 nozzle.json +++ b/resources/profiles/re3D/machine/re3D Gigabot 4 0.4 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D Gigabot 4 0.4 nozzle", "inherits": "fdm_re3D_common", + "setting_id": "2FfoXQpNqgdO0psS", "instantiation": "true", "machine_tech": "FFF", "model_id": "GB4", @@ -31,6 +32,5 @@ "re3D PETG @0.4 nozzle" ], "default_print_profile": "0.26 Standard", - "printer_settings_id": "re3d_gigbot4_04", - "setting_id": "2FfoXQpNqgdO0psS" -} \ No newline at end of file + "printer_settings_id": "re3d_gigbot4_04" +} diff --git a/resources/profiles/re3D/machine/re3D Gigabot 4 0.8 nozzle.json b/resources/profiles/re3D/machine/re3D Gigabot 4 0.8 nozzle.json index e87cdacef1..87086d516b 100644 --- a/resources/profiles/re3D/machine/re3D Gigabot 4 0.8 nozzle.json +++ b/resources/profiles/re3D/machine/re3D Gigabot 4 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D Gigabot 4 0.8 nozzle", "inherits": "fdm_re3D_common", + "setting_id": "t5Efv7WaUvnPYIAm", "instantiation": "true", "machine_tech": "FFF", "model_id": "GB4", @@ -31,6 +32,5 @@ "re3D PETG @0.8 nozzle" ], "default_print_profile": "0.4 Standard", - "printer_settings_id": "re3d_gigbot4_08", - "setting_id": "t5Efv7WaUvnPYIAm" -} \ No newline at end of file + "printer_settings_id": "re3d_gigbot4_08" +} diff --git a/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.4 nozzle.json b/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.4 nozzle.json index dedb29c3e8..b58338c041 100644 --- a/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.4 nozzle.json +++ b/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.4 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D Gigabot 4 XLT 0.4 nozzle", "inherits": "fdm_re3D_common", + "setting_id": "UrYpMJff1UulWnSk", "instantiation": "true", "machine_tech": "FFF", "model_id": "GB4", @@ -31,6 +32,5 @@ "re3D PETG @0.4 nozzle" ], "default_print_profile": "0.26 Standard", - "printer_settings_id": "re3d_gigabot4_xlt_04", - "setting_id": "UrYpMJff1UulWnSk" -} \ No newline at end of file + "printer_settings_id": "re3d_gigabot4_xlt_04" +} diff --git a/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.8 nozzle.json b/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.8 nozzle.json index f34890289c..8fd896087e 100644 --- a/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.8 nozzle.json +++ b/resources/profiles/re3D/machine/re3D Gigabot 4 XLT 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D Gigabot 4 XLT 0.8 nozzle", "inherits": "fdm_re3D_common", + "setting_id": "owqU0OvESWbbsBaw", "instantiation": "true", "machine_tech": "FFF", "model_id": "GB4", @@ -31,6 +32,5 @@ "re3D PETG @0.8 nozzle" ], "default_print_profile": "0.4 Standard", - "printer_settings_id": "re3d_gigabot4_xlt_08", - "setting_id": "owqU0OvESWbbsBaw" -} \ No newline at end of file + "printer_settings_id": "re3d_gigabot4_xlt_08" +} diff --git a/resources/profiles/re3D/machine/re3D Gigabot 4 XLT.json b/resources/profiles/re3D/machine/re3D Gigabot 4 XLT.json index fd7858de60..5fa299ee5e 100644 --- a/resources/profiles/re3D/machine/re3D Gigabot 4 XLT.json +++ b/resources/profiles/re3D/machine/re3D Gigabot 4 XLT.json @@ -1,9 +1,9 @@ { "type": "machine_model", "name": "re3D Gigabot 4 XLT", + "instantiation": "false", "model_id": "re3D Gigabot 4 XLT", "nozzle_diameter": "0.4;0.8", - "instantiation": "false", "machine_tech": "FFF", "family": "re3D", "bed_model": "", diff --git a/resources/profiles/re3D/machine/re3D Gigabot 4.json b/resources/profiles/re3D/machine/re3D Gigabot 4.json index 67531b1214..9926381d68 100644 --- a/resources/profiles/re3D/machine/re3D Gigabot 4.json +++ b/resources/profiles/re3D/machine/re3D Gigabot 4.json @@ -1,9 +1,9 @@ { "type": "machine_model", "name": "re3D Gigabot 4", + "instantiation": "false", "model_id": "re3D Gigabot 4", "nozzle_diameter": "0.4;0.8", - "instantiation": "false", "machine_tech": "FFF", "family": "re3D", "bed_model": "", diff --git a/resources/profiles/re3D/machine/re3D GigabotX 2 0.8 nozzle.json b/resources/profiles/re3D/machine/re3D GigabotX 2 0.8 nozzle.json index f6bac17a0d..7765edcebe 100644 --- a/resources/profiles/re3D/machine/re3D GigabotX 2 0.8 nozzle.json +++ b/resources/profiles/re3D/machine/re3D GigabotX 2 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D GigabotX 2 0.8 nozzle", "inherits": "fgf_re3D_common", + "setting_id": "pASXL7fDFXAG0tkJ", "instantiation": "true", "machine_tech": "FGF", "model_id": "re3D GBX2", @@ -28,6 +29,5 @@ "re3D rPETG @0.8 nozzle" ], "default_print_profile": "0.6 Standard", - "printer_settings_id": "re3d_gbx_08", - "setting_id": "pASXL7fDFXAG0tkJ" -} \ No newline at end of file + "printer_settings_id": "re3d_gbx_08" +} diff --git a/resources/profiles/re3D/machine/re3D GigabotX 2 1.75 nozzle.json b/resources/profiles/re3D/machine/re3D GigabotX 2 1.75 nozzle.json index 585c219bc7..d827deb4ff 100644 --- a/resources/profiles/re3D/machine/re3D GigabotX 2 1.75 nozzle.json +++ b/resources/profiles/re3D/machine/re3D GigabotX 2 1.75 nozzle.json @@ -3,6 +3,7 @@ "name": "re3D GigabotX 2 1.75 nozzle", "renamed_from": "re3D Gigabot X2 1.75 nozzle", "inherits": "fgf_re3D_common", + "setting_id": "ozJ43xjd5bOWGvPH", "instantiation": "true", "machine_tech": "FGF", "model_id": "re3D GBX2", @@ -29,6 +30,5 @@ "re3D rPETG @1.75 nozzle" ], "default_print_profile": "1.0 Standard", - "printer_settings_id": "re3d_gbx_175", - "setting_id": "ozJ43xjd5bOWGvPH" -} \ No newline at end of file + "printer_settings_id": "re3d_gbx_175" +} diff --git a/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 0.8 nozzle.json b/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 0.8 nozzle.json index 863d8e6403..a9b0c1e3c5 100644 --- a/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 0.8 nozzle.json +++ b/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D GigabotX 2 XLT 0.8 nozzle", "inherits": "fgf_re3D_common", + "setting_id": "66tcU44A7VD232wV", "instantiation": "true", "machine_tech": "FGF", "model_id": "re3D GBX2 XLT", @@ -28,6 +29,5 @@ "re3D rPETG @0.8 nozzle" ], "default_print_profile": "0.6 Standard", - "printer_settings_id": "re3d_gbx_xlt_08", - "setting_id": "66tcU44A7VD232wV" -} \ No newline at end of file + "printer_settings_id": "re3d_gbx_xlt_08" +} diff --git a/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 1.75 nozzle.json b/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 1.75 nozzle.json index 5784b4e673..76023b8a1b 100644 --- a/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 1.75 nozzle.json +++ b/resources/profiles/re3D/machine/re3D GigabotX 2 XLT 1.75 nozzle.json @@ -3,6 +3,7 @@ "name": "re3D GigabotX 2 XLT 1.75 nozzle", "renamed_from": "re3D Gigabot X2 XLT 1.75 nozzle", "inherits": "fgf_re3D_common", + "setting_id": "L0PKsbwUEul8gil3", "instantiation": "true", "machine_tech": "FGF", "model_id": "re3D GBX2 XLT", @@ -29,6 +30,5 @@ "re3D rPETG @1.75 nozzle" ], "default_print_profile": "1.0 Standard", - "printer_settings_id": "re3d_gbx_xlt_175", - "setting_id": "L0PKsbwUEul8gil3" -} \ No newline at end of file + "printer_settings_id": "re3d_gbx_xlt_175" +} diff --git a/resources/profiles/re3D/machine/re3D GigabotX 2 XLT.json b/resources/profiles/re3D/machine/re3D GigabotX 2 XLT.json index 1b77360139..0e14643a29 100644 --- a/resources/profiles/re3D/machine/re3D GigabotX 2 XLT.json +++ b/resources/profiles/re3D/machine/re3D GigabotX 2 XLT.json @@ -1,9 +1,9 @@ { "type": "machine_model", "name": "re3D GigabotX 2 XLT", + "instantiation": "false", "model_id": "re3D GigabotX 2 XLT", "nozzle_diameter": "0.8;1.75", - "instantiation": "false", "machine_tech": "FGF", "family": "re3D", "bed_model": "", diff --git a/resources/profiles/re3D/machine/re3D GigabotX 2.json b/resources/profiles/re3D/machine/re3D GigabotX 2.json index 20ec4ff207..b57f46585d 100644 --- a/resources/profiles/re3D/machine/re3D GigabotX 2.json +++ b/resources/profiles/re3D/machine/re3D GigabotX 2.json @@ -1,9 +1,9 @@ { "type": "machine_model", "name": "re3D GigabotX 2", + "instantiation": "false", "model_id": "re3D GigabotX 2", "nozzle_diameter": "0.8;1.75", - "instantiation": "false", "machine_tech": "FGF", "family": "re3D", "bed_model": "", diff --git a/resources/profiles/re3D/machine/re3D Terabot 4 0.4 nozzle.json b/resources/profiles/re3D/machine/re3D Terabot 4 0.4 nozzle.json index e57e4058af..f151217f96 100644 --- a/resources/profiles/re3D/machine/re3D Terabot 4 0.4 nozzle.json +++ b/resources/profiles/re3D/machine/re3D Terabot 4 0.4 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D Terabot 4 0.4 nozzle", "inherits": "fdm_re3D_common", + "setting_id": "fjQ7KSytjKq40DSo", "instantiation": "true", "machine_tech": "FFF", "model_id": "TB4", @@ -31,6 +32,5 @@ "re3D PETG @0.4 nozzle" ], "default_print_profile": "0.26 Standard", - "printer_settings_id": "re3d_terabot4_04", - "setting_id": "fjQ7KSytjKq40DSo" -} \ No newline at end of file + "printer_settings_id": "re3d_terabot4_04" +} diff --git a/resources/profiles/re3D/machine/re3D Terabot 4 0.8 nozzle.json b/resources/profiles/re3D/machine/re3D Terabot 4 0.8 nozzle.json index c15ac1f8b9..67db6a6a72 100644 --- a/resources/profiles/re3D/machine/re3D Terabot 4 0.8 nozzle.json +++ b/resources/profiles/re3D/machine/re3D Terabot 4 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D Terabot 4 0.8 nozzle", "inherits": "fdm_re3D_common", + "setting_id": "EsfqTpN28Qmlaov3", "instantiation": "true", "machine_tech": "FFF", "model_id": "TB4", @@ -31,6 +32,5 @@ "re3D PETG @0.8 nozzle" ], "default_print_profile": "0.4 Standard", - "printer_settings_id": "re3d_terabot4_08", - "setting_id": "EsfqTpN28Qmlaov3" -} \ No newline at end of file + "printer_settings_id": "re3d_terabot4_08" +} diff --git a/resources/profiles/re3D/machine/re3D Terabot 4.json b/resources/profiles/re3D/machine/re3D Terabot 4.json index eaca67fba0..000cc921bf 100644 --- a/resources/profiles/re3D/machine/re3D Terabot 4.json +++ b/resources/profiles/re3D/machine/re3D Terabot 4.json @@ -1,9 +1,9 @@ { "type": "machine_model", "name": "re3D Terabot 4", + "instantiation": "false", "model_id": "re3D Terabot 4", "nozzle_diameter": "0.4;0.8", - "instantiation": "false", "machine_tech": "FFF", "family": "re3D", "bed_model": "", diff --git a/resources/profiles/re3D/machine/re3D TerabotX 2 0.8 nozzle.json b/resources/profiles/re3D/machine/re3D TerabotX 2 0.8 nozzle.json index 5622a813c1..86b1d77c6e 100644 --- a/resources/profiles/re3D/machine/re3D TerabotX 2 0.8 nozzle.json +++ b/resources/profiles/re3D/machine/re3D TerabotX 2 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "re3D TerabotX 2 0.8 nozzle", "inherits": "fgf_re3D_common", + "setting_id": "A6jcgezqyq6DE5mi", "instantiation": "true", "machine_tech": "FGF", "model_id": "re3D TBX2", @@ -28,6 +29,5 @@ "re3D rPETG @0.8 nozzle" ], "default_print_profile": "0.6 Standard", - "printer_settings_id": "re3d_tbx2_08", - "setting_id": "A6jcgezqyq6DE5mi" -} \ No newline at end of file + "printer_settings_id": "re3d_tbx2_08" +} diff --git a/resources/profiles/re3D/machine/re3D TerabotX 2 1.75 nozzle.json b/resources/profiles/re3D/machine/re3D TerabotX 2 1.75 nozzle.json index 398ab006bd..c8b865bfd8 100644 --- a/resources/profiles/re3D/machine/re3D TerabotX 2 1.75 nozzle.json +++ b/resources/profiles/re3D/machine/re3D TerabotX 2 1.75 nozzle.json @@ -3,6 +3,7 @@ "name": "re3D TerabotX 2 1.75 nozzle", "renamed_from": "re3D Terabot X2 1.75 nozzle", "inherits": "fgf_re3D_common", + "setting_id": "FCcmkG4pnJhjZUBd", "instantiation": "true", "machine_tech": "FGF", "model_id": "re3D TBX2", @@ -29,6 +30,5 @@ "re3D rPETG @1.75 nozzle" ], "default_print_profile": "1.0 Standard", - "printer_settings_id": "re3d_tbx2_175", - "setting_id": "FCcmkG4pnJhjZUBd" -} \ No newline at end of file + "printer_settings_id": "re3d_tbx2_175" +} diff --git a/resources/profiles/re3D/machine/re3D TerabotX 2.json b/resources/profiles/re3D/machine/re3D TerabotX 2.json index 177c1e05d0..bbd8b1c22a 100644 --- a/resources/profiles/re3D/machine/re3D TerabotX 2.json +++ b/resources/profiles/re3D/machine/re3D TerabotX 2.json @@ -1,9 +1,9 @@ { "type": "machine_model", "name": "re3D TerabotX 2", + "instantiation": "false", "model_id": "re3D TerabotX 2", "nozzle_diameter": "0.8;1.75", - "instantiation": "false", "machine_tech": "FGF", "family": "re3D", "bed_model": "", diff --git a/resources/profiles/re3D/process/0.26mm Standard @re3D fdm 0.4.json b/resources/profiles/re3D/process/0.26mm Standard @re3D fdm 0.4.json index 2ab80cdf26..1bef3f24ab 100644 --- a/resources/profiles/re3D/process/0.26mm Standard @re3D fdm 0.4.json +++ b/resources/profiles/re3D/process/0.26mm Standard @re3D fdm 0.4.json @@ -1,11 +1,11 @@ { "type": "process", - "setting_id": "z8J2jOmdssB8DCBO", "name": "0.26 Standard", "renamed_from": "0.26mm Standard @re3D fdm 0.4", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_re3D_common", + "from": "system", + "setting_id": "z8J2jOmdssB8DCBO", + "instantiation": "true", "compatible_printers": [ "re3D Gigabot 4 0.4 nozzle", "re3D Gigabot 4 XLT 0.4 nozzle", @@ -24,33 +24,33 @@ "support_top_z_distance": "0.2", "support_bottom_z_distance": "0.2", "bridge_speed": "50", - "internal_bridge_speed": "150%", - "default_acceleration": "5000", - "outer_wall_speed": "60", - "initial_layer_speed": "50", - "gap_infill_speed": "60", - "sparse_infill_speed": "80", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "support_interface_speed": "30", - "support_speed": "90", - "top_surface_speed": "50", - "travel_speed": "300", - "top_surface_acceleration": "2500", - "initial_layer_acceleration": "1000", - "travel_acceleration": "5000", - "inner_wall_acceleration": "5000", - "ironing_speed": "25", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", - "initial_layer_infill_speed": "50", - "outer_wall_acceleration": "2500", - "bridge_acceleration": "3500", - "sparse_infill_acceleration": "5000", - "internal_solid_infill_acceleration": "5000", - "initial_layer_travel_speed": "100%", - "small_perimeter_speed": "50%", + "internal_bridge_speed": "150%", + "default_acceleration": "5000", + "outer_wall_speed": "60", + "initial_layer_speed": "50", + "gap_infill_speed": "60", + "sparse_infill_speed": "80", + "inner_wall_speed": "80", + "internal_solid_infill_speed": "80", + "support_interface_speed": "30", + "support_speed": "90", + "top_surface_speed": "50", + "travel_speed": "300", + "top_surface_acceleration": "2500", + "initial_layer_acceleration": "1000", + "travel_acceleration": "5000", + "inner_wall_acceleration": "5000", + "ironing_speed": "25", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "30", + "overhang_4_4_speed": "10", + "initial_layer_infill_speed": "50", + "outer_wall_acceleration": "2500", + "bridge_acceleration": "3500", + "sparse_infill_acceleration": "5000", + "internal_solid_infill_acceleration": "5000", + "initial_layer_travel_speed": "100%", + "small_perimeter_speed": "50%", "filename_format": "{input_filename_base}_{\"E\"}{initial_tool}_{filament_type[initial_tool]}_{print_time}.gcode" } diff --git a/resources/profiles/re3D/process/0.2mm Fine @re3D fdm 0.4.json b/resources/profiles/re3D/process/0.2mm Fine @re3D fdm 0.4.json index 10013e9c36..5b2d009cf4 100644 --- a/resources/profiles/re3D/process/0.2mm Fine @re3D fdm 0.4.json +++ b/resources/profiles/re3D/process/0.2mm Fine @re3D fdm 0.4.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "u9PNexqDf7jWUnnH", "name": "0.2 Fine", "renamed_from": "0.2mm Fine @re3D fdm 0.4", - "from": "system", "inherits": "fdm_process_re3D_common", + "from": "system", + "setting_id": "u9PNexqDf7jWUnnH", "instantiation": "true", "compatible_printers": [ "re3D Gigabot 4 0.4 nozzle", @@ -24,30 +24,30 @@ "support_top_z_distance": "0.2", "support_bottom_z_distance": "0.2", "outer_wall_speed": "60", - "initial_layer_speed": "50", - "gap_infill_speed": "60", - "sparse_infill_speed": "80", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "support_interface_speed": "30", - "support_speed": "90", - "top_surface_speed": "50", - "travel_speed": "300", - "top_surface_acceleration": "2500", - "initial_layer_acceleration": "1000", - "travel_acceleration": "5000", - "inner_wall_acceleration": "5000", - "ironing_speed": "25", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", - "initial_layer_infill_speed": "50", - "outer_wall_acceleration": "2500", - "bridge_acceleration": "3500", - "sparse_infill_acceleration": "5000", - "internal_solid_infill_acceleration": "5000", - "initial_layer_travel_speed": "100%", - "small_perimeter_speed": "50%", + "initial_layer_speed": "50", + "gap_infill_speed": "60", + "sparse_infill_speed": "80", + "inner_wall_speed": "80", + "internal_solid_infill_speed": "80", + "support_interface_speed": "30", + "support_speed": "90", + "top_surface_speed": "50", + "travel_speed": "300", + "top_surface_acceleration": "2500", + "initial_layer_acceleration": "1000", + "travel_acceleration": "5000", + "inner_wall_acceleration": "5000", + "ironing_speed": "25", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "30", + "overhang_4_4_speed": "10", + "initial_layer_infill_speed": "50", + "outer_wall_acceleration": "2500", + "bridge_acceleration": "3500", + "sparse_infill_acceleration": "5000", + "internal_solid_infill_acceleration": "5000", + "initial_layer_travel_speed": "100%", + "small_perimeter_speed": "50%", "filename_format": "{input_filename_base}_{\"E\"}{initial_tool}_{filament_type[initial_tool]}_{print_time}.gcode" } diff --git a/resources/profiles/re3D/process/0.32mm Draft @re3D fdm 0.4.json b/resources/profiles/re3D/process/0.32mm Draft @re3D fdm 0.4.json index 1b14349f81..b64285819c 100644 --- a/resources/profiles/re3D/process/0.32mm Draft @re3D fdm 0.4.json +++ b/resources/profiles/re3D/process/0.32mm Draft @re3D fdm 0.4.json @@ -1,11 +1,11 @@ { "type": "process", - "setting_id": "pcKSZbNmByNtOHYX", "name": "0.32 Draft", "renamed_from": "0.32mm Draft @re3D fdm 0.4", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_re3D_common", + "from": "system", + "setting_id": "pcKSZbNmByNtOHYX", + "instantiation": "true", "compatible_printers": [ "re3D Gigabot 4 0.4 nozzle", "re3D Gigabot 4 XLT 0.4 nozzle", @@ -24,30 +24,30 @@ "support_top_z_distance": "0.35", "support_bottom_z_distance": "0.35", "outer_wall_speed": "60", - "initial_layer_speed": "50", - "gap_infill_speed": "60", - "sparse_infill_speed": "80", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "support_interface_speed": "30", - "support_speed": "90", - "top_surface_speed": "50", - "travel_speed": "300", - "top_surface_acceleration": "2500", - "initial_layer_acceleration": "1000", - "travel_acceleration": "5000", - "inner_wall_acceleration": "5000", - "ironing_speed": "25", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", - "initial_layer_infill_speed": "50", - "outer_wall_acceleration": "2500", - "bridge_acceleration": "3500", - "sparse_infill_acceleration": "5000", - "internal_solid_infill_acceleration": "5000", - "initial_layer_travel_speed": "100%", - "small_perimeter_speed": "50%", + "initial_layer_speed": "50", + "gap_infill_speed": "60", + "sparse_infill_speed": "80", + "inner_wall_speed": "80", + "internal_solid_infill_speed": "80", + "support_interface_speed": "30", + "support_speed": "90", + "top_surface_speed": "50", + "travel_speed": "300", + "top_surface_acceleration": "2500", + "initial_layer_acceleration": "1000", + "travel_acceleration": "5000", + "inner_wall_acceleration": "5000", + "ironing_speed": "25", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "30", + "overhang_4_4_speed": "10", + "initial_layer_infill_speed": "50", + "outer_wall_acceleration": "2500", + "bridge_acceleration": "3500", + "sparse_infill_acceleration": "5000", + "internal_solid_infill_acceleration": "5000", + "initial_layer_travel_speed": "100%", + "small_perimeter_speed": "50%", "filename_format": "{input_filename_base}_{\"E\"}{initial_tool}_{filament_type[initial_tool]}_{print_time}.gcode" } diff --git a/resources/profiles/re3D/process/0.3mm Fine @re3D fdm 0.8.json b/resources/profiles/re3D/process/0.3mm Fine @re3D fdm 0.8.json index 2b35f2c1f8..a5418c1cee 100644 --- a/resources/profiles/re3D/process/0.3mm Fine @re3D fdm 0.8.json +++ b/resources/profiles/re3D/process/0.3mm Fine @re3D fdm 0.8.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "ChglxET1YwzVuD6a", "name": "0.3 Fine", "renamed_from": "0.2mm Standard @re3D fdm 0.8", - "from": "system", "inherits": "fdm_process_re3D_common", + "from": "system", + "setting_id": "ChglxET1YwzVuD6a", "instantiation": "true", "compatible_printers": [ "re3D Gigabot 4 0.8 nozzle", @@ -24,30 +24,30 @@ "support_top_z_distance": "0.24", "support_bottom_z_distance": "0.24", "outer_wall_speed": "60", - "initial_layer_speed": "50", - "gap_infill_speed": "60", - "sparse_infill_speed": "80", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "support_interface_speed": "30", - "support_speed": "90", - "top_surface_speed": "50", - "travel_speed": "300", - "top_surface_acceleration": "2500", - "initial_layer_acceleration": "1000", - "travel_acceleration": "5000", - "inner_wall_acceleration": "5000", - "ironing_speed": "25", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", - "initial_layer_infill_speed": "50", - "outer_wall_acceleration": "2500", - "bridge_acceleration": "3500", - "sparse_infill_acceleration": "5000", - "internal_solid_infill_acceleration": "5000", - "initial_layer_travel_speed": "100%", - "small_perimeter_speed": "50%", + "initial_layer_speed": "50", + "gap_infill_speed": "60", + "sparse_infill_speed": "80", + "inner_wall_speed": "80", + "internal_solid_infill_speed": "80", + "support_interface_speed": "30", + "support_speed": "90", + "top_surface_speed": "50", + "travel_speed": "300", + "top_surface_acceleration": "2500", + "initial_layer_acceleration": "1000", + "travel_acceleration": "5000", + "inner_wall_acceleration": "5000", + "ironing_speed": "25", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "30", + "overhang_4_4_speed": "10", + "initial_layer_infill_speed": "50", + "outer_wall_acceleration": "2500", + "bridge_acceleration": "3500", + "sparse_infill_acceleration": "5000", + "internal_solid_infill_acceleration": "5000", + "initial_layer_travel_speed": "100%", + "small_perimeter_speed": "50%", "filename_format": "{input_filename_base}_{\"E\"}{initial_tool}_{filament_type[initial_tool]}_{print_time}.gcode" } diff --git a/resources/profiles/re3D/process/0.4mm Draft @re3D fdm 0.8.json b/resources/profiles/re3D/process/0.4mm Draft @re3D fdm 0.8.json index d00f8bce44..4ac2239ccb 100644 --- a/resources/profiles/re3D/process/0.4mm Draft @re3D fdm 0.8.json +++ b/resources/profiles/re3D/process/0.4mm Draft @re3D fdm 0.8.json @@ -1,11 +1,11 @@ { "type": "process", - "setting_id": "hiBgnEuKo4yjK3wp", "name": "0.4 Standard", "renamed_from": "0.4mm Draft @re3D fdm 0.8", - "from": "system", - "instantiation": "true", "inherits": "fdm_process_re3D_common", + "from": "system", + "setting_id": "hiBgnEuKo4yjK3wp", + "instantiation": "true", "compatible_printers": [ "re3D Gigabot 4 0.8 nozzle", "re3D Gigabot 4 XLT 0.8 nozzle", @@ -24,30 +24,30 @@ "support_top_z_distance": "0.42", "support_bottom_z_distance": "0.42", "outer_wall_speed": "60", - "initial_layer_speed": "50", - "gap_infill_speed": "60", - "sparse_infill_speed": "80", - "inner_wall_speed": "80", - "internal_solid_infill_speed": "80", - "support_interface_speed": "30", - "support_speed": "90", - "top_surface_speed": "50", - "travel_speed": "300", - "top_surface_acceleration": "2500", - "initial_layer_acceleration": "1000", - "travel_acceleration": "5000", - "inner_wall_acceleration": "5000", - "ironing_speed": "25", - "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", - "overhang_3_4_speed": "30", - "overhang_4_4_speed": "10", - "initial_layer_infill_speed": "50", - "outer_wall_acceleration": "2500", - "bridge_acceleration": "3500", - "sparse_infill_acceleration": "5000", - "internal_solid_infill_acceleration": "5000", - "initial_layer_travel_speed": "100%", - "small_perimeter_speed": "50%", + "initial_layer_speed": "50", + "gap_infill_speed": "60", + "sparse_infill_speed": "80", + "inner_wall_speed": "80", + "internal_solid_infill_speed": "80", + "support_interface_speed": "30", + "support_speed": "90", + "top_surface_speed": "50", + "travel_speed": "300", + "top_surface_acceleration": "2500", + "initial_layer_acceleration": "1000", + "travel_acceleration": "5000", + "inner_wall_acceleration": "5000", + "ironing_speed": "25", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "30", + "overhang_4_4_speed": "10", + "initial_layer_infill_speed": "50", + "outer_wall_acceleration": "2500", + "bridge_acceleration": "3500", + "sparse_infill_acceleration": "5000", + "internal_solid_infill_acceleration": "5000", + "initial_layer_travel_speed": "100%", + "small_perimeter_speed": "50%", "filename_format": "{input_filename_base}_{\"E\"}{initial_tool}_{filament_type[initial_tool]}_{print_time}.gcode" } diff --git a/resources/profiles/re3D/process/0.6mm Standard @re3D fgf 0.8.json b/resources/profiles/re3D/process/0.6mm Standard @re3D fgf 0.8.json index 80cc07b339..15c9322c23 100644 --- a/resources/profiles/re3D/process/0.6mm Standard @re3D fgf 0.8.json +++ b/resources/profiles/re3D/process/0.6mm Standard @re3D fgf 0.8.json @@ -1,9 +1,9 @@ { "type": "process", - "setting_id": "7V7GXJOUd5LT6YNi", "name": "0.6 Standard", - "from": "system", "inherits": "fgf_process_re3D_common", + "from": "system", + "setting_id": "7V7GXJOUd5LT6YNi", "instantiation": "true", "layer_height": "0.6", "initial_layer_print_height": "0.8", @@ -23,4 +23,4 @@ "re3D GigabotX 2 XLT 0.8 nozzle", "re3D TerabotX 2 0.8 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/profiles/re3D/process/1.0mm Standard @re3D fgf 1.75.json b/resources/profiles/re3D/process/1.0mm Standard @re3D fgf 1.75.json index 5f703baaec..cf41e6854d 100644 --- a/resources/profiles/re3D/process/1.0mm Standard @re3D fgf 1.75.json +++ b/resources/profiles/re3D/process/1.0mm Standard @re3D fgf 1.75.json @@ -1,10 +1,10 @@ { "type": "process", - "setting_id": "LKf4K1hjRuLeW7SM", "name": "1.0 Standard", "renamed_from": "1.0mm Standard @re3D fgf 1.75", - "from": "system", "inherits": "fgf_process_re3D_common", + "from": "system", + "setting_id": "LKf4K1hjRuLeW7SM", "instantiation": "true", "layer_height": "1.0", "initial_layer_print_height": "1.0", @@ -24,4 +24,4 @@ "re3D GigabotX 2 XLT 1.75 nozzle", "re3D TerabotX 2 1.75 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/shaders/110/texture_displacement_shaded.fs b/resources/shaders/110/texture_displacement_shaded.fs new file mode 100644 index 0000000000..4a2980cd64 --- /dev/null +++ b/resources/shaders/110/texture_displacement_shaded.fs @@ -0,0 +1,425 @@ +#version 110 + +// See resources/shaders/140/texture_displacement_shaded.fs for full documentation; this is the +// GLSL 1.10 compatibility variant (same logic, older syntax). + +#define INTENSITY_CORRECTION 0.6 + +#define PARALLAX_STEPS 24 +#define H_AT(uv) texture2D(height_tex, uv).r + +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform vec4 uniform_color; +// The printable palette, in **CIELAB** as well as RGB, and how many entries are real. Lab because the +// match has to be perceptual - the same reason the CPU side uses CIEDE2000 - and converting the +// palette once on the CPU is what lets the fragment shader match with a plain squared distance. +// Count 0 means nothing is colouring, and every fragment falls back to uniform_color as before. +uniform vec3 palette_lab[64]; +uniform vec3 palette_rgb[64]; +uniform int palette_count; +uniform bool pure_only; // match against single filaments only (flat-colour image) +// How each entry prints. A pure entry is one filament (a == b); a mix interleaves filaments a and b, +// num parts of a in every den, and the print shows that interleave rather than the entry's average +// colour. The fragment resolves it exactly as GLGizmoTextureDisplacement::make_mix_resolver() does +// per triangle on the CPU, so the preview shows the pattern the bake will print. +uniform int palette_a[64]; +uniform int palette_b[64]; +uniform int palette_num[64]; +uniform int palette_den[64]; +uniform vec3 filament_rgb[16]; +uniform int filament_count; +uniform int mix_mode; // ColorMixMode: 0 Z bands, 1 XY dither, 2 auto +uniform float layer_height; // mm; one Z band per print layer +uniform float dither_cell; // mm; one XY dither cell +uniform sampler2D color_tex; // the layer's colour image, sampled at the same uv as the height +uniform bool has_color_tex; +uniform bool volume_mirrored; + +uniform mat4 view_model_matrix; +uniform mat3 view_normal_matrix; + +uniform sampler2D height_tex; +uniform vec2 height_tex_texel; +uniform float depth_mm; +uniform float tiling_scale; +// Height map width / height. Scales the v axis so a non-square image keeps its proportions +// instead of being squeezed into a square tile - mirrors libslic3r's apply_uv_transform(). +uniform float tex_aspect; +uniform float rotation_rad; +uniform vec2 uv_offset; +uniform bool invert; +uniform float midlevel; // the height that means "don't move"; needed by the parallax step +uniform vec3 eye_model_pos; // camera position in the texture frame (world minus tex_anchor) +uniform vec3 tex_anchor; // the volume's origin in world space: the texture frame's origin +uniform bool use_vertex_uv; +// 2x3 affine (lin = (m00, m01, m10, m11), tr = (m02, m12)) applied to the dragged island's uv; see the +// 140 variant. Identity when nothing is dragged. +uniform vec4 island_delta_lin; +uniform vec2 island_delta_tr; +// In-shader projection (0 Triplanar, 1 Cylindrical, 2 Spherical) and the painted patch's own frame the +// two wrapping ones wrap around, in the texture frame; see the 140 variant. +uniform int projection_mode; +uniform vec3 patch_center; +uniform vec3 patch_axis; + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; +varying vec4 world_pos; +varying float weight; +varying float island_active; +varying vec2 vertex_uv; + +// The cylinder's own frame, built exactly as libslic3r's project_cylindrical() builds it - including +// the handedness, which comes out left-handed for an axis of +Z. Copied rather than "corrected", so +// the preview wraps the texture the same way round as the bake. +void cylinder_frame(out vec3 up, out vec3 right, out vec3 fwd) +{ + up = (length(patch_axis) > 1e-8) ? normalize(patch_axis) : vec3(0.0, 0.0, 1.0); + vec3 arbitrary = (abs(up.z) < 0.9) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + right = normalize(cross(up, arbitrary)); + fwd = normalize(cross(right, up)); +} + +// The raw, millimetre-valued projection of `p` (a position in the texture frame), before the layer's +// tiling/rotation/aspect/offset - a term-for-term transcription of libslic3r's project_planar(), +// project_cylindrical() and project_spherical(). `n` is read by the planar mode only. +vec2 projection_raw(vec3 p, vec3 n) +{ + if (projection_mode == 1) { // Cylindrical: (arc length around, distance along) + vec3 up, right, fwd; + cylinder_frame(up, right, fwd); + vec3 rel = p - patch_center; + float x = dot(rel, right); + float y = dot(rel, fwd); + return vec2(atan(y, x) * sqrt(x * x + y * y), dot(rel, up)); + } + if (projection_mode == 2) { // Spherical: (longitude, latitude) * radius + vec3 rel = p - patch_center; + float radius = length(rel); + if (radius < 1e-8) + return vec2(0.0); + vec3 dir = rel / radius; + return vec2(atan(dir.y, dir.x), asin(clamp(dir.z, -1.0, 1.0))) * radius; + } + vec3 an = abs(n); // Triplanar: drop the dominant normal axis + return (an.x >= an.y && an.x >= an.z) ? p.yz : ((an.y >= an.x && an.y >= an.z) ? p.xz : p.xy); +} + +// The two surface directions projection_raw()'s u and v run along at `p`, plus how many raw units one +// millimetre of travel along each of them covers - the factor that turns the uv-space height gradient +// into a real mm-per-mm slope. For the planar projection both axes are world axes and the factor is 1. +// Cylindrical and Spherical are arc-length parametrized, so it is 1 there too, except for the +// spherical longitude, whose circle shrinks by cos(latitude) toward the poles. Exact where the surface +// really is the cylinder/sphere the projection assumes - the same assumption libslic3r makes. +void projection_axes(vec3 p, vec3 n, out vec3 t, out vec3 b, out vec2 units_per_mm) +{ + units_per_mm = vec2(1.0, 1.0); + if (projection_mode == 1) { + vec3 up, right, fwd; + cylinder_frame(up, right, fwd); + vec3 rel = p - patch_center; + vec2 xy = vec2(dot(rel, right), dot(rel, fwd)); + float r = length(xy); + t = (r > 1e-6) ? (fwd * xy.x - right * xy.y) / r : right; // circumferential: u runs along it + b = up; // v is the distance along the axis + return; + } + if (projection_mode == 2) { + vec3 rel = p - patch_center; + float r = length(rel); + vec3 dir = (r > 1e-8) ? rel / r : vec3(0.0, 0.0, 1.0); + float c = length(dir.xy); // cos(latitude) + t = (c > 1e-6) ? vec3(-dir.y, dir.x, 0.0) / c : vec3(1.0, 0.0, 0.0); + b = cross(dir, t); // increasing latitude, unit length + units_per_mm = vec2(1.0 / max(c, 1e-3), 1.0); + return; + } + vec3 an = abs(n); + if (an.x >= an.y && an.x >= an.z) { // planar = p.yz + t = vec3(0.0, 1.0, 0.0); + b = vec3(0.0, 0.0, 1.0); + } else if (an.y >= an.x && an.y >= an.z) { // planar = p.xz + t = vec3(1.0, 0.0, 0.0); + b = vec3(0.0, 0.0, 1.0); + } else { // planar = p.xy + t = vec3(1.0, 0.0, 0.0); + b = vec3(0.0, 1.0, 0.0); + } +} + +vec2 project_uv(vec3 p, vec3 n) +{ + vec2 planar = projection_raw(p, n); + planar *= (tiling_scale > 1e-6) ? (1.0 / tiling_scale) : 1.0; + float cs = cos(rotation_rad); + float sn = sin(rotation_rad); + vec2 r = vec2(planar.x * cs - planar.y * sn, planar.x * sn + planar.y * cs); + // After the rotation, so the rotation stays a rotation rather than becoming a shear. + r.y *= tex_aspect; + return r + uv_offset; +} + +// sRGB -> CIELAB, matching slic3r/Utils/ColorSpaceConvert's RGB2Lab so this picks the same entry the +// bake does. +vec3 srgb_to_lab(vec3 c) +{ + vec3 v = vec3(c.r > 0.04045 ? pow((c.r + 0.055) / 1.055, 2.4) : c.r / 12.92, + c.g > 0.04045 ? pow((c.g + 0.055) / 1.055, 2.4) : c.g / 12.92, + c.b > 0.04045 ? pow((c.b + 0.055) / 1.055, 2.4) : c.b / 12.92); + vec3 xyz = vec3(dot(v, vec3(0.4124, 0.3576, 0.1805)) / 0.95047, + dot(v, vec3(0.2126, 0.7152, 0.0722)), + dot(v, vec3(0.0193, 0.1192, 0.9505)) / 1.08883); + vec3 f = vec3(xyz.x > 0.008856 ? pow(xyz.x, 1.0 / 3.0) : (7.787 * xyz.x) + 16.0 / 116.0, + xyz.y > 0.008856 ? pow(xyz.y, 1.0 / 3.0) : (7.787 * xyz.y) + 16.0 / 116.0, + xyz.z > 0.008856 ? pow(xyz.z, 1.0 / 3.0) : (7.787 * xyz.z) + 16.0 / 116.0); + return vec3(116.0 * f.y - 16.0, 500.0 * (f.x - f.y), 200.0 * (f.y - f.z)); +} + +// Nearest printable colour to a sampled one. Quantizing per *fragment* rather than per facet is the +// whole point of this path: it shows the image at the texture's resolution instead of the mesh's, +// which is what you need while choosing a texture and placing it. The Normal view is where the +// facet-resolution truth - what actually bakes - is shown. +// +// Squared distance in Lab (CIE76) rather than the CPU's CIEDE2000: the two agree except on near-ties, +// and CIEDE2000 per fragment across 64 entries is not worth its cost in a preview. +int nearest_palette_entry(vec3 rgb) +{ + vec3 lab = srgb_to_lab(rgb); + int best = 0; + int best_pure = -1; + float bd = 1.0e20; + float bd_pure = 1.0e20; + for (int i = 0; i < 64; ++i) { + if (i >= palette_count) + break; + if (pure_only && palette_a[i] != palette_b[i]) + continue; // a flat-colour image never takes a mix (see the bake) + vec3 d = lab - palette_lab[i]; + float d2 = dot(d, d); + if (palette_a[i] == palette_b[i] && d2 < bd_pure) { + bd_pure = d2; + best_pure = i; + } + if (d2 < bd) { + bd = d2; + best = i; + } + } + // The same bias make_palette_quantizer() applies (PREFER_PURE_DE = 10): a mix is an interleave, so + // it is only worth taking when it beats the nearest single filament by a visible step. Without it + // this picked a mix for almost every fragment - with four filaments the palette is 4 pure entries + // against 30 mixes - while the bake picked a single filament for most of them, so the preview + // interleaved the whole wall where the bake interleaves only patches. Compared on the distances + // rather than their squares, so the threshold means the same thing as it does on the CPU (up to + // CIE76 against CIEDE2000, the approximation already noted above). + if (best_pure >= 0 && palette_a[best] != palette_b[best] && sqrt(bd_pure) - sqrt(bd) < 10.0) + best = best_pure; + return best; +} + +// One 2x2 Bayer cell, {0, 2; 3, 1}, for x and y in {0, 1}. +float bayer2(float x, float y) { return 2.0 * x + 3.0 * y - 4.0 * x * y; } + +// The colour the printer lays down at world point `pos` for palette entry `index`: its filament, or +// for a mix whichever of its two filaments this point falls on. Mirrors make_mix_resolver() on the +// CPU, floors on the band/cell size included. All the modular arithmetic is done in floats with +// mod(), which wraps negative coordinates the way the CPU's ((v % n) + n) % n does and needs no +// integer % (not available on every GLSL 1.10 target). +vec3 printed_color(int index, vec3 pos, vec3 normal, vec3 footprint) +{ + int a = palette_a[index]; + int b = palette_b[index]; + if (a < 0 || a >= filament_count || b < 0 || b >= filament_count) + return palette_rgb[index]; // no filament to resolve to: the entry's own colour + if (a == b) + return filament_rgb[a]; + float num = float(palette_num[index]); + float den = float(palette_den[index]); + // Auto: bands where the surface is steeper than ~45 degrees, the dominant filament elsewhere. + if (mix_mode == 2 && abs(normal.z) >= 0.7) + return filament_rgb[(num * 2.0 >= den) ? a : b]; + + // Pre-filter. The interleave is an ordered dither the eye is meant to blend away, and no dither + // blends when it is drawn at less than a few pixels per period - it aliases, which is what turned + // every upright wall into horizontal streaks: the Z band cycle is den * layer_height (around a + // millimetre), and every pixel of a row on a vertical wall shares one z, so each row came out as a + // 1-bit threshold of the image at that row's phase. `footprint` is mm of world position per pixel, + // so this is zoom- and resolution-correct rather than a tuned constant: where the print's own + // pattern is finer than this view can resolve, show what the print looks like from here, which is + // the entry's perceptual average. The Normal view remains where the per-facet truth lives. + float period = (mix_mode == 1) ? 2.0 * max(dither_cell, 0.01) : den * max(layer_height, 0.01); + float px = (mix_mode == 1) ? max(footprint.x, footprint.y) : footprint.z; + float sharp = clamp(period / max(4.0 * px, 1e-6) - 0.5, 0.0, 1.0); + if (sharp <= 0.0) + return palette_rgb[index]; + + vec3 picked; + if (mix_mode == 1) { + // Ordered 4x4 Bayer over floor(x / cell), floor(y / cell). The CPU's table + // 0 8 2 10 + // 12 4 14 6 + // 3 11 1 9 + // 15 7 13 5 + // is 4 * bayer2(x % 2, y % 2) + bayer2(x / 2, y / 2), which needs no array (GLSL 1.10 has + // no constant arrays). + float cell = max(dither_cell, 0.01); + float gx = mod(floor(pos.x / cell), 4.0); + float gy = mod(floor(pos.y / cell), 4.0); + float bayer = 4.0 * bayer2(mod(gx, 2.0), mod(gy, 2.0)) + bayer2(floor(gx / 2.0), floor(gy / 2.0)); + picked = filament_rgb[(num / den > (bayer + 0.5) / 16.0) ? a : b]; + } else { + // Z bands: one per band height, the band's phase in the a/b cycle picks the filament. Both + // operands are integer-valued, so the half keeps "phase < num" exact under float rounding. + float slot = floor(pos.z / max(layer_height, 0.01)); + float phase = mod(slot, den); + picked = filament_rgb[(phase < num - 0.5) ? a : b]; + } + return mix(palette_rgb[index], picked, sharp); +} + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + // World millimetres throughout, like the bake - see the 140 variant. + vec3 triangle_normal = normalize(cross(dFdx(world_pos.xyz), dFdy(world_pos.xyz))); + vec3 tex_pos = world_pos.xyz - tex_anchor; // the frame the texture is projected in, as the bake does + // World mm per pixel, for pre-filtering the interleave in printed_color(). Taken here because the + // albedo branch at the end of main() is non-uniform control flow, where derivatives are undefined. + vec3 pos_fwidth = fwidth(world_pos.xyz); + if (volume_mirrored) + triangle_normal = -triangle_normal; + + // Where the colour is read from. Both branches below already compute the uv this fragment's + // *height* came from - including the parallax-marched one on the triplanar path - and the colour + // has to follow it exactly, or the colour would slide off the relief as the camera orbits. + vec2 color_uv = vec2(0.0); + bool have_uv = false; + + if (use_vertex_uv) { + // Mikkelsen surface-gradient normal perturbation; see the 140 variant for the full rationale. Scale-exact + // for a conformal LSCM map (no global 1/tiling assumption), and gated by the paint weight + // via a multiply so the branch stays uniform (use_vertex_uv is a uniform). + vec2 uv = (island_active > 0.5) + ? vec2(dot(island_delta_lin.xy, vertex_uv), dot(island_delta_lin.zw, vertex_uv)) + island_delta_tr + : vertex_uv; + color_uv = uv; + have_uv = true; + float h = texture2D(height_tex, uv).r; + float k = (invert ? -1.0 : 1.0) * depth_mm * clamp(weight, 0.0, 1.0); + vec3 sigmaS = dFdx(world_pos.xyz); + vec3 sigmaT = dFdy(world_pos.xyz); + vec3 R1 = cross(sigmaT, triangle_normal); + vec3 R2 = cross(triangle_normal, sigmaS); + float det = dot(sigmaS, R1); + float dHdx = k * dFdx(h); + float dHdy = k * dFdy(h); + if (abs(det) > 1e-12) + triangle_normal = normalize(triangle_normal - (dHdx * R1 + dHdy * R2) / det); + } else if (weight > 0.0) { + vec3 t, b; + vec2 units_per_mm; + projection_axes(tex_pos, triangle_normal, t, b, units_per_mm); + + // Parallax occlusion mapping: march the view ray through the height shell and shade at the + // first point where it drops below the displaced surface (see header). + float amp = (invert ? -1.0 : 1.0) * depth_mm * clamp(weight, 0.0, 1.0); + vec3 view_dir = normalize(eye_model_pos - tex_pos); + float v_dot_n = dot(view_dir, triangle_normal); + vec2 uv = project_uv(tex_pos, triangle_normal); + + // The shell the displaced surface lives inside, as signed heights along the normal. Taken from + // both ends of h in [0, 1] so it stays correct for an inverted layer or a raised midlevel, + // where the surface sits *below* the undisplaced one. + float h_end_a = amp * (0.0 - midlevel); + float h_end_b = amp * (1.0 - midlevel); + float h_hi = max(h_end_a, h_end_b); + float h_lo = min(h_end_a, h_end_b); + // How far, in mm, sweeping the ray across the shell slides the sample point sideways. Below half + // a texel there is no parallax to find and the march would be pure cost - which is the common + // case of looking straight down at a surface. + float sweep = length(view_dir - triangle_normal * v_dot_n) * (h_hi - h_lo) / max(v_dot_n, 1e-4); + if (v_dot_n > 0.05 && sweep > 0.5 * tiling_scale * height_tex_texel.x) { + // A point at ray parameter s (model_pos + view_dir * s) sits at height s * v_dot_n above the + // undisplaced surface. Start at the top of the shell, where the ray is outside the surface + // by construction, and step inward; the crossing is what this pixel actually sees. + float s = h_hi / v_dot_n; + float ds = (h_hi - h_lo) / (v_dot_n * float(PARALLAX_STEPS)); + vec2 prev_uv = project_uv(tex_pos + view_dir * s, triangle_normal); + float prev_gap = h_hi - amp * (H_AT(prev_uv) - midlevel); // >= 0 by construction + for (int i = 0; i < PARALLAX_STEPS; ++i) { + s -= ds; + vec2 cur_uv = project_uv(tex_pos + view_dir * s, triangle_normal); + float gap = s * v_dot_n - amp * (H_AT(cur_uv) - midlevel); + if (gap <= 0.0) { + // Crossed between the last two samples - interpolating the hit is what stops it + // quantising to the step size, and so what keeps the step count affordable. + uv = mix(prev_uv, cur_uv, clamp(prev_gap / max(prev_gap - gap, 1e-6), 0.0, 1.0)); + break; + } + prev_uv = cur_uv; + prev_gap = gap; + } + } + + color_uv = uv; // after the parallax march, so colour and relief stay registered + have_uv = true; + + float hL = texture2D(height_tex, uv - vec2(height_tex_texel.x, 0.0)).r; + float hR = texture2D(height_tex, uv + vec2(height_tex_texel.x, 0.0)).r; + float hD = texture2D(height_tex, uv - vec2(0.0, height_tex_texel.y)).r; + float hU = texture2D(height_tex, uv + vec2(0.0, height_tex_texel.y)).r; + + vec2 dh_duv = vec2((hR - hL) / (2.0 * height_tex_texel.x), (hU - hD) / (2.0 * height_tex_texel.y)); + float inv_tiling = (tiling_scale > 1e-6) ? (1.0 / tiling_scale) : 1.0; + float amplitude = (invert ? -1.0 : 1.0) * depth_mm * inv_tiling * clamp(weight, 0.0, 1.0); + + float cs = cos(rotation_rad); + float sn = sin(rotation_rad); + // One uv unit is tiling_scale mm along u but tiling_scale / tex_aspect mm along v, so the v + // component of the gradient carries the extra factor before being rotated back into t/b. + vec2 g = vec2(dh_duv.x, dh_duv.y * tex_aspect); + // ...and back out of raw-projection units into millimetres along t / b; see the 140 variant. + vec2 slope = amplitude * vec2(g.x * cs + g.y * sn, -g.x * sn + g.y * cs) * units_per_mm; + + vec3 gradient = slope.x * t + slope.y * b; + gradient -= triangle_normal * dot(triangle_normal, gradient); + triangle_normal = normalize(triangle_normal - gradient); + } + + vec3 eye_normal = normalize(view_normal_matrix * triangle_normal); + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + vec2 intensity = vec2(0.0); + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec3 position = (view_model_matrix * model_pos).xyz; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Diffuse albedo: the image's colour at this fragment, snapped to the nearest printable colour - + // and, where that is a mix, the filament the interleave puts here, so the pattern that prints shows. + // Only the albedo - the specular term (intensity.y) stays white - so a coloured fragment reads as + // the same material under the same light, and the relief this preview exists to show is unaffected. + vec3 albedo = uniform_color.rgb; + if (palette_count > 0 && has_color_tex && have_uv && weight > 0.0) + // tex_pos, not world_pos: the bake resolves the interleave in the bake frame (world + // orientation and scale about the volume's origin, see texture_displacement_bake_frame()), so + // measuring z from the bed instead shifted the band phase by the volume origin's height - a + // different filament in the same place than the bake produces. + albedo = printed_color(nearest_palette_entry(texture2D(color_tex, color_uv).rgb), tex_pos, triangle_normal, pos_fwidth); + gl_FragColor = vec4(vec3(intensity.y) + albedo * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/110/texture_displacement_shaded.vs b/resources/shaders/110/texture_displacement_shaded.vs new file mode 100644 index 0000000000..468bdf56d9 --- /dev/null +++ b/resources/shaders/110/texture_displacement_shaded.vs @@ -0,0 +1,34 @@ +#version 110 + +// See resources/shaders/140/texture_displacement_shaded.vs for full documentation; this is the +// GLSL 1.10 compatibility variant. + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat4 volume_world_matrix; +uniform vec2 z_range; +uniform vec4 clipping_plane; + +attribute vec3 v_position; +attribute vec3 v_normal; // .x = paint weight (0/1); .y = 1 for the dragged island's vertices +attribute vec2 v_tex_coord; // precomputed texture uv, used only when use_vertex_uv is set + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; +varying vec4 world_pos; +varying float weight; +varying float island_active; +varying vec2 vertex_uv; + +void main() +{ + model_pos = vec4(v_position, 1.0); + world_pos = volume_world_matrix * model_pos; + + gl_Position = projection_matrix * view_model_matrix * model_pos; + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + weight = v_normal.x; + island_active = v_normal.y; + vertex_uv = v_tex_coord; +} diff --git a/resources/shaders/110/texture_displacement_uvcheck.fs b/resources/shaders/110/texture_displacement_uvcheck.fs new file mode 100644 index 0000000000..f9e998adc2 --- /dev/null +++ b/resources/shaders/110/texture_displacement_uvcheck.fs @@ -0,0 +1,114 @@ +#version 110 + +// See resources/shaders/140/texture_displacement_uvcheck.fs; GLSL 1.10 compatibility variant. + +#define INTENSITY_CORRECTION 0.6 +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) +#define INTENSITY_AMBIENT 0.3 +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform mat3 view_normal_matrix; +uniform bool volume_mirrored; + +uniform int mode; +uniform float checker_freq; +uniform float tiling_scale; +uniform vec3 tex_anchor; // the volume's origin in world space +uniform float rotation_rad; +uniform vec2 uv_offset; +uniform bool use_vertex_uv; +// The in-shader projection (0 Triplanar, 1 Cylindrical, 2 Spherical) and the painted patch's frame the +// wrapping ones wrap around, in the texture frame - the same uniforms, and the same formulas, as +// texture_displacement_shaded.fs, so the checker reports the projection the bake will actually use. +uniform int projection_mode; +uniform vec3 patch_center; +uniform vec3 patch_axis; +// Height map width / height, as apply_uv_transform() applies it. Without it the checker diverged from +// the bake for any non-square texture, in every in-shader projection. +uniform float tex_aspect; + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; +varying vec4 world_pos; +varying float distortion; +varying vec2 vertex_uv; + +void cylinder_frame(out vec3 up, out vec3 right, out vec3 fwd) +{ + up = (length(patch_axis) > 1e-8) ? normalize(patch_axis) : vec3(0.0, 0.0, 1.0); + vec3 arbitrary = (abs(up.z) < 0.9) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + right = normalize(cross(up, arbitrary)); + fwd = normalize(cross(right, up)); +} + +// Term for term libslic3r's project_planar() / project_cylindrical() / project_spherical(), in mm. +vec2 projection_raw(vec3 p, vec3 n) +{ + if (projection_mode == 1) { + vec3 up, right, fwd; + cylinder_frame(up, right, fwd); + vec3 rel = p - patch_center; + float x = dot(rel, right); + float y = dot(rel, fwd); + return vec2(atan(y, x) * sqrt(x * x + y * y), dot(rel, up)); + } + if (projection_mode == 2) { + vec3 rel = p - patch_center; + float radius = length(rel); + if (radius < 1e-8) + return vec2(0.0); + vec3 dir = rel / radius; + return vec2(atan(dir.y, dir.x), asin(clamp(dir.z, -1.0, 1.0))) * radius; + } + vec3 an = abs(n); + return (an.x >= an.y && an.x >= an.z) ? p.yz : ((an.y >= an.x && an.y >= an.z) ? p.xz : p.xy); +} + +vec2 project_uv(vec3 p, vec3 n) +{ + vec2 planar = projection_raw(p, n); + planar *= (tiling_scale > 1e-6) ? (1.0 / tiling_scale) : 1.0; + float cs = cos(rotation_rad); + float sn = sin(rotation_rad); + vec2 r = vec2(planar.x * cs - planar.y * sn, planar.x * sn + planar.y * cs); + r.y *= tex_aspect; // after the rotation, so the rotation stays a rotation rather than a shear + return r + uv_offset; +} + +vec3 heatmap(float t) +{ + t = clamp(t, 0.0, 1.0); + return clamp(vec3(1.5 - abs(4.0 * t - 3.0), + 1.5 - abs(4.0 * t - 2.0), + 1.5 - abs(4.0 * t - 1.0)), 0.0, 1.0); +} + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + // World space anchored at the volume's origin, like the bake and the shaded preview. + vec3 triangle_normal = normalize(cross(dFdx(world_pos.xyz), dFdy(world_pos.xyz))); + vec3 tex_pos = world_pos.xyz - tex_anchor; + if (volume_mirrored) + triangle_normal = -triangle_normal; + + vec3 base; + if (mode == 1) { + base = heatmap(distortion); + } else { + vec2 uv = use_vertex_uv ? vertex_uv : project_uv(tex_pos, triangle_normal); + vec2 c = floor(uv * checker_freq); + float check = mod(c.x + c.y, 2.0); + base = (check < 0.5) ? vec3(0.22, 0.23, 0.26) : vec3(0.82, 0.83, 0.86); + } + + vec3 eye_normal = normalize(view_normal_matrix * triangle_normal); + float intensity = INTENSITY_AMBIENT + max(dot(eye_normal, LIGHT_TOP_DIR), 0.0) * LIGHT_TOP_DIFFUSE + + max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0) * LIGHT_FRONT_DIFFUSE; + gl_FragColor = vec4(base * intensity, 1.0); +} diff --git a/resources/shaders/110/texture_displacement_uvcheck.vs b/resources/shaders/110/texture_displacement_uvcheck.vs new file mode 100644 index 0000000000..06c59e5c61 --- /dev/null +++ b/resources/shaders/110/texture_displacement_uvcheck.vs @@ -0,0 +1,31 @@ +#version 110 + +// See resources/shaders/140/texture_displacement_uvcheck.vs; GLSL 1.10 compatibility variant. + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat4 volume_world_matrix; +uniform vec2 z_range; +uniform vec4 clipping_plane; + +attribute vec3 v_position; +attribute vec3 v_normal; // .x = per-vertex uv distortion +attribute vec2 v_tex_coord; // precomputed texture uv, used only when use_vertex_uv is set + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; +varying vec4 world_pos; +varying float distortion; +varying vec2 vertex_uv; + +void main() +{ + model_pos = vec4(v_position, 1.0); + world_pos = volume_world_matrix * model_pos; + + gl_Position = projection_matrix * view_model_matrix * model_pos; + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + distortion = v_normal.x; + vertex_uv = v_tex_coord; +} diff --git a/resources/shaders/140/texture_displacement_shaded.fs b/resources/shaders/140/texture_displacement_shaded.fs new file mode 100644 index 0000000000..1d8bee10fa --- /dev/null +++ b/resources/shaders/140/texture_displacement_shaded.fs @@ -0,0 +1,513 @@ +#version 140 + +// Fast, geometry-free preview of texture displacement: perturbs the *shading* normal from the +// height texture's local gradient, faded out by the per-vertex paint weight. The +// true, exact result is what "Bake" produces via libslic3r/TextureDisplacement.cpp on the CPU. +// +// The bake displaces each surface point along its normal by H = +/- depth_mm * (h(uv) - midlevel), +// with uv from the layer's projection. The perturbed normal is the analytic +// +// N' = normalize(N - (dH/da) * T - (dH/db) * B) +// +// over any orthonormal surface tangent pair (T, B), where the two slopes are real mm-per-mm +// derivatives. Two things have to be right for the preview's apparent depth to match the bake's: +// the tangent frame the gradient is expressed in, and the uv->mm scale that turns a texel +// difference into a slope. Getting the scale wrong is a uniform flattening (a raw texel difference +// is dh over one texel step, not over one mm); getting the frame wrong tilts the relief along the +// wrong axes. +// +// Two projection paths: +// * Triplanar (use_vertex_uv = 0): uv and the tangent axes are derived in-shader from the dominant +// normal axis, mirroring libslic3r's project_planar()/apply_uv_transform(), and the slope is +// formed analytically (there is a closed-form uv, so 1 uv unit is exactly tiling_scale mm). This +// path also runs a parallax step before shading, see below. +// +// Parallax. Perturbing the normal alone shades only, so the pattern is welded to the base surface: it +// does not shift as the camera orbits and it does not get any deeper as depth_mm grows, which is +// exactly when the preview stops reading as real geometry. The triplanar path therefore shades at the +// point the *displaced* surface would show at this pixel rather than at the pixel's own base position. +// +// Two cheaper formulations were tried first and both are wrong here, which is worth recording: +// * Solving Q = P + V * (H(Q) / dot(V, n)) by fixed-point iteration. Geometrically exact, but the +// divisor goes to zero edge-on, and an unbounded step is not a small error - the sample lands a +// large fraction of a tile away and the iteration oscillates instead of converging. It reads as a +// *second, flat copy* of the pattern ghosted over the real one. Clamping the step to one tile does +// not help either: a tile-sized shift lands on the neighbouring tile, which is the same pattern. +// * Offset limiting (Welsh): step along the tangential part of V, whose length caps the shift at one +// depth. Stable and cheap, but it understates parallax by exactly the factor that matters - the +// relief still flattens as soon as the camera tilts, which is the complaint it was meant to fix. +// +// So this ray-marches instead (parallax occlusion mapping). A point at ray parameter s, i.e. P + V * s, +// sits at height s * dot(V, n) above the undisplaced surface. The displaced surface lives in a shell +// between the extreme values of amp * (h - midlevel); the march starts at the top of that shell, where +// the ray is outside the surface by construction, and steps inward until the ray height falls below the +// sampled height. That crossing *is* the visible point - no divergence, no ghosting, and parallax stays +// correct at any angle. The hit is interpolated between the last two samples, which is what keeps +// PARALLAX_STEPS low enough to afford. The march is skipped when sweeping the shell would move the +// sample point less than half a texel (the head-on case), so the common view pays almost nothing. +// +// The gradient/shading below is evaluated at the resulting uv, so the relief both slides correctly +// under camera motion and visibly deepens with depth_mm. What it still cannot do is change the +// model's silhouette or cast shadows; for that, switch the View row to Normal. +// * Precomputed uv (use_vertex_uv = 1, used for LSCM): uv comes per-vertex from the CPU (the LSCM +// unwrap with island placement + tiling/rotation/offset already folded in), and the perturbed +// normal is built with Mikkelsen's method -- the surface gradient taken straight from the +// screen-space derivatives of the sampled height and position. This makes no uv->mm scale +// assumption, which matters because an LSCM map is conformal, not isometric: the local mm-per-uv +// varies across the chart, so a single global 1/tiling factor (what an earlier version used) got +// the apparent depth wrong. This path is also what makes the fast preview follow the UV editor: +// move an island and its uv -- hence its relief -- moves with it. + +#define INTENSITY_CORRECTION 0.6 + +#define PARALLAX_STEPS 24 +// Explicit LOD: the march samples inside non-uniform control flow, where implicit +// derivatives are undefined. +#define H_AT(uv) textureLod(height_tex, uv, 0.0).r + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform vec4 uniform_color; +// The printable palette, in **CIELAB** as well as RGB, and how many entries are real. Lab because the +// match has to be perceptual - the same reason the CPU side uses CIEDE2000 - and converting the +// palette once on the CPU is what lets the fragment shader match with a plain squared distance. +// Count 0 means nothing is colouring, and every fragment falls back to uniform_color as before. +uniform vec3 palette_lab[64]; +uniform vec3 palette_rgb[64]; +uniform int palette_count; +uniform bool pure_only; // match against single filaments only (flat-colour image) +// How each entry prints. A pure entry is one filament (a == b); a mix interleaves filaments a and b, +// num parts of a in every den, and the print shows that interleave rather than the entry's average +// colour. The fragment resolves it exactly as GLGizmoTextureDisplacement::make_mix_resolver() does +// per triangle on the CPU, so the preview shows the pattern the bake will print. +uniform int palette_a[64]; +uniform int palette_b[64]; +uniform int palette_num[64]; +uniform int palette_den[64]; +uniform vec3 filament_rgb[16]; +uniform int filament_count; +uniform int mix_mode; // ColorMixMode: 0 Z bands, 1 XY dither, 2 auto +uniform float layer_height; // mm; one Z band per print layer +uniform float dither_cell; // mm; one XY dither cell +uniform sampler2D color_tex; // the layer's colour image, sampled at the same uv as the height +uniform bool has_color_tex; +uniform bool volume_mirrored; + +uniform mat4 view_model_matrix; +uniform mat3 view_normal_matrix; + +uniform sampler2D height_tex; +uniform vec2 height_tex_texel; // (1/width, 1/height) of height_tex +uniform float depth_mm; +uniform float tiling_scale; +// Height map width / height. Scales the v axis so a non-square image keeps its proportions +// instead of being squeezed into a square tile - mirrors libslic3r's apply_uv_transform(). +uniform float tex_aspect; +uniform float rotation_rad; +uniform vec2 uv_offset; +uniform bool invert; +uniform float midlevel; // the height that means "don't move"; needed by the parallax step +uniform vec3 eye_model_pos; // camera position in the texture frame (world minus tex_anchor) +uniform vec3 tex_anchor; // the volume's origin in world space: the texture frame's origin +uniform bool use_vertex_uv; // true: sample at vertex_uv with a derived tangent frame (LSCM) +// A 2x3 affine (columns packed as lin = (m00, m01, m10, m11), tr = (m02, m12)) applied to the uv of +// the island currently being dragged in the UV editor (island_active > 0.5). Identity when nothing is +// dragged, so this whole path is a no-op then. Lets a UV island drag move the relief on the model with +// only a uniform update +uniform vec4 island_delta_lin; +uniform vec2 island_delta_tr; +// Which projection to reconstruct in-shader: 0 Triplanar, 1 Cylindrical, 2 Spherical (the low three +// TextureProjectionMethod values; LSCM and ViewProjected arrive through use_vertex_uv and leave this +// at 0). The two wrapping projections wrap around the *whole painted patch*, so its centroid - and, +// for Cylindrical, its axis - are properties no single fragment can derive. They come from the CPU, +// in this same texture frame, computed with the bake's own texture_displacement_patch_frame(). +uniform int projection_mode; +uniform vec3 patch_center; +uniform vec3 patch_axis; + +in vec3 clipping_planes_dots; +in vec4 model_pos; +in vec4 world_pos; +in float weight; +in float island_active; +in vec2 vertex_uv; + +out vec4 out_color; + +// The cylinder's own frame, built exactly as libslic3r's project_cylindrical() builds it - including +// the handedness, which comes out left-handed for an axis of +Z. Copied rather than "corrected", so +// the preview wraps the texture the same way round as the bake. +void cylinder_frame(out vec3 up, out vec3 right, out vec3 fwd) +{ + up = (length(patch_axis) > 1e-8) ? normalize(patch_axis) : vec3(0.0, 0.0, 1.0); + vec3 arbitrary = (abs(up.z) < 0.9) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + right = normalize(cross(up, arbitrary)); + fwd = normalize(cross(right, up)); +} + +// The raw, millimetre-valued projection of `p` (a position in the texture frame), before the layer's +// tiling/rotation/aspect/offset - a term-for-term transcription of libslic3r's project_planar(), +// project_cylindrical() and project_spherical(). `n` is read by the planar mode only. +vec2 projection_raw(vec3 p, vec3 n) +{ + if (projection_mode == 1) { // Cylindrical: (arc length around, distance along) + vec3 up, right, fwd; + cylinder_frame(up, right, fwd); + vec3 rel = p - patch_center; + float x = dot(rel, right); + float y = dot(rel, fwd); + return vec2(atan(y, x) * sqrt(x * x + y * y), dot(rel, up)); + } + if (projection_mode == 2) { // Spherical: (longitude, latitude) * radius + vec3 rel = p - patch_center; + float radius = length(rel); + if (radius < 1e-8) + return vec2(0.0); + vec3 dir = rel / radius; + return vec2(atan(dir.y, dir.x), asin(clamp(dir.z, -1.0, 1.0))) * radius; + } + vec3 an = abs(n); // Triplanar: drop the dominant normal axis + return (an.x >= an.y && an.x >= an.z) ? p.yz : ((an.y >= an.x && an.y >= an.z) ? p.xz : p.xy); +} + +// The two surface directions projection_raw()'s u and v run along at `p`, plus how many raw units one +// millimetre of travel along each of them covers - the factor that turns the uv-space height gradient +// into a real mm-per-mm slope. For the planar projection both axes are world axes and the factor is 1. +// Cylindrical and Spherical are arc-length parametrized, so it is 1 there too, except for the +// spherical longitude, whose circle shrinks by cos(latitude) toward the poles. Exact where the surface +// really is the cylinder/sphere the projection assumes - the same assumption libslic3r makes. +void projection_axes(vec3 p, vec3 n, out vec3 t, out vec3 b, out vec2 units_per_mm) +{ + units_per_mm = vec2(1.0, 1.0); + if (projection_mode == 1) { + vec3 up, right, fwd; + cylinder_frame(up, right, fwd); + vec3 rel = p - patch_center; + vec2 xy = vec2(dot(rel, right), dot(rel, fwd)); + float r = length(xy); + t = (r > 1e-6) ? (fwd * xy.x - right * xy.y) / r : right; // circumferential: u runs along it + b = up; // v is the distance along the axis + return; + } + if (projection_mode == 2) { + vec3 rel = p - patch_center; + float r = length(rel); + vec3 dir = (r > 1e-8) ? rel / r : vec3(0.0, 0.0, 1.0); + float c = length(dir.xy); // cos(latitude) + t = (c > 1e-6) ? vec3(-dir.y, dir.x, 0.0) / c : vec3(1.0, 0.0, 0.0); + b = cross(dir, t); // increasing latitude, unit length + units_per_mm = vec2(1.0 / max(c, 1e-3), 1.0); + return; + } + vec3 an = abs(n); + if (an.x >= an.y && an.x >= an.z) { // planar = p.yz + t = vec3(0.0, 1.0, 0.0); + b = vec3(0.0, 0.0, 1.0); + } else if (an.y >= an.x && an.y >= an.z) { // planar = p.xz + t = vec3(1.0, 0.0, 0.0); + b = vec3(0.0, 0.0, 1.0); + } else { // planar = p.xy + t = vec3(1.0, 0.0, 0.0); + b = vec3(0.0, 1.0, 0.0); + } +} + +vec2 project_uv(vec3 p, vec3 n) +{ + vec2 planar = projection_raw(p, n); + planar *= (tiling_scale > 1e-6) ? (1.0 / tiling_scale) : 1.0; + float cs = cos(rotation_rad); + float sn = sin(rotation_rad); + vec2 r = vec2(planar.x * cs - planar.y * sn, planar.x * sn + planar.y * cs); + // After the rotation, so the rotation stays a rotation rather than becoming a shear. + r.y *= tex_aspect; + return r + uv_offset; +} + +// sRGB -> CIELAB, matching slic3r/Utils/ColorSpaceConvert's RGB2Lab so this picks the same entry the +// bake does. +vec3 srgb_to_lab(vec3 c) +{ + vec3 v = vec3(c.r > 0.04045 ? pow((c.r + 0.055) / 1.055, 2.4) : c.r / 12.92, + c.g > 0.04045 ? pow((c.g + 0.055) / 1.055, 2.4) : c.g / 12.92, + c.b > 0.04045 ? pow((c.b + 0.055) / 1.055, 2.4) : c.b / 12.92); + vec3 xyz = vec3(dot(v, vec3(0.4124, 0.3576, 0.1805)) / 0.95047, + dot(v, vec3(0.2126, 0.7152, 0.0722)), + dot(v, vec3(0.0193, 0.1192, 0.9505)) / 1.08883); + vec3 f = vec3(xyz.x > 0.008856 ? pow(xyz.x, 1.0 / 3.0) : (7.787 * xyz.x) + 16.0 / 116.0, + xyz.y > 0.008856 ? pow(xyz.y, 1.0 / 3.0) : (7.787 * xyz.y) + 16.0 / 116.0, + xyz.z > 0.008856 ? pow(xyz.z, 1.0 / 3.0) : (7.787 * xyz.z) + 16.0 / 116.0); + return vec3(116.0 * f.y - 16.0, 500.0 * (f.x - f.y), 200.0 * (f.y - f.z)); +} + +// Nearest printable colour to a sampled one. Quantizing per *fragment* rather than per facet is the +// whole point of this path: it shows the image at the texture's resolution instead of the mesh's, +// which is what you need while choosing a texture and placing it. The Normal view is where the +// facet-resolution truth - what actually bakes - is shown. +// +// Squared distance in Lab (CIE76) rather than the CPU's CIEDE2000: the two agree except on near-ties, +// and CIEDE2000 per fragment across 64 entries is not worth its cost in a preview. +int nearest_palette_entry(vec3 rgb) +{ + vec3 lab = srgb_to_lab(rgb); + int best = 0; + int best_pure = -1; + float bd = 1.0e20; + float bd_pure = 1.0e20; + for (int i = 0; i < 64; ++i) { + if (i >= palette_count) + break; + if (pure_only && palette_a[i] != palette_b[i]) + continue; // a flat-colour image never takes a mix (see the bake) + vec3 d = lab - palette_lab[i]; + float d2 = dot(d, d); + if (palette_a[i] == palette_b[i] && d2 < bd_pure) { + bd_pure = d2; + best_pure = i; + } + if (d2 < bd) { + bd = d2; + best = i; + } + } + // The same bias make_palette_quantizer() applies (PREFER_PURE_DE = 10): a mix is an interleave, so + // it is only worth taking when it beats the nearest single filament by a visible step. Without it + // this picked a mix for almost every fragment - with four filaments the palette is 4 pure entries + // against 30 mixes - while the bake picked a single filament for most of them, so the preview + // interleaved the whole wall where the bake interleaves only patches. Compared on the distances + // rather than their squares, so the threshold means the same thing as it does on the CPU (up to + // CIE76 against CIEDE2000, the approximation already noted above). + if (best_pure >= 0 && palette_a[best] != palette_b[best] && sqrt(bd_pure) - sqrt(bd) < 10.0) + best = best_pure; + return best; +} + +// One 2x2 Bayer cell, {0, 2; 3, 1}, for x and y in {0, 1}. +float bayer2(float x, float y) { return 2.0 * x + 3.0 * y - 4.0 * x * y; } + +// The colour the printer lays down at world point `pos` for palette entry `index`: its filament, or +// for a mix whichever of its two filaments this point falls on. Mirrors make_mix_resolver() on the +// CPU, floors on the band/cell size included. All the modular arithmetic is done in floats with +// mod(), which wraps negative coordinates the way the CPU's ((v % n) + n) % n does and needs no +// integer % (not available on every GLSL 1.10 target). +vec3 printed_color(int index, vec3 pos, vec3 normal, vec3 footprint) +{ + int a = palette_a[index]; + int b = palette_b[index]; + if (a < 0 || a >= filament_count || b < 0 || b >= filament_count) + return palette_rgb[index]; // no filament to resolve to: the entry's own colour + if (a == b) + return filament_rgb[a]; + float num = float(palette_num[index]); + float den = float(palette_den[index]); + // Auto: bands where the surface is steeper than ~45 degrees, the dominant filament elsewhere. + if (mix_mode == 2 && abs(normal.z) >= 0.7) + return filament_rgb[(num * 2.0 >= den) ? a : b]; + + // Pre-filter. The interleave is an ordered dither the eye is meant to blend away, and no dither + // blends when it is drawn at less than a few pixels per period - it aliases, which is what turned + // every upright wall into horizontal streaks: the Z band cycle is den * layer_height (around a + // millimetre), and every pixel of a row on a vertical wall shares one z, so each row came out as a + // 1-bit threshold of the image at that row's phase. `footprint` is mm of world position per pixel, + // so this is zoom- and resolution-correct rather than a tuned constant: where the print's own + // pattern is finer than this view can resolve, show what the print looks like from here, which is + // the entry's perceptual average. The Normal view remains where the per-facet truth lives. + float period = (mix_mode == 1) ? 2.0 * max(dither_cell, 0.01) : den * max(layer_height, 0.01); + float px = (mix_mode == 1) ? max(footprint.x, footprint.y) : footprint.z; + float sharp = clamp(period / max(4.0 * px, 1e-6) - 0.5, 0.0, 1.0); + if (sharp <= 0.0) + return palette_rgb[index]; + + vec3 picked; + if (mix_mode == 1) { + // Ordered 4x4 Bayer over floor(x / cell), floor(y / cell). The CPU's table + // 0 8 2 10 + // 12 4 14 6 + // 3 11 1 9 + // 15 7 13 5 + // is 4 * bayer2(x % 2, y % 2) + bayer2(x / 2, y / 2), which needs no array (GLSL 1.10 has + // no constant arrays). + float cell = max(dither_cell, 0.01); + float gx = mod(floor(pos.x / cell), 4.0); + float gy = mod(floor(pos.y / cell), 4.0); + float bayer = 4.0 * bayer2(mod(gx, 2.0), mod(gy, 2.0)) + bayer2(floor(gx / 2.0), floor(gy / 2.0)); + picked = filament_rgb[(num / den > (bayer + 0.5) / 16.0) ? a : b]; + } else { + // Z bands: one per band height, the band's phase in the a/b cycle picks the filament. Both + // operands are integer-valued, so the half keeps "phase < num" exact under float rounding. + float slot = floor(pos.z / max(layer_height, 0.01)); + float phase = mod(slot, den); + picked = filament_rgb[(phase < num - 0.5) ? a : b]; + } + return mix(palette_rgb[index], picked, sharp); +} + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + // Everything below runs in world millimetres, like the bake: a tile is tiling_scale mm on the + // printed part whatever the instance's scale or rotation, so the preview has to project from the + // world position and perturb the world normal. + vec3 triangle_normal = normalize(cross(dFdx(world_pos.xyz), dFdy(world_pos.xyz))); + vec3 tex_pos = world_pos.xyz - tex_anchor; // the frame the texture is projected in, as the bake does + // World mm per pixel, for pre-filtering the interleave in printed_color(). Taken here because the + // albedo branch at the end of main() is non-uniform control flow, where derivatives are undefined. + vec3 pos_fwidth = fwidth(world_pos.xyz); + if (volume_mirrored) + triangle_normal = -triangle_normal; + + // Where the colour is read from. Both branches below already compute the uv this fragment's + // *height* came from - including the parallax-marched one on the triplanar path - and the colour + // has to follow it exactly, or the colour would slide off the relief as the camera orbits. + vec2 color_uv = vec2(0.0); + bool have_uv = false; + + if (use_vertex_uv) { + // Precomputed-uv (LSCM) path - Mikkelsen's surface-gradient normal mapping ("Bump Mapping + // Unparametrized Surfaces on the GPU"). The perturbed normal is derived straight from the + // screen-space derivatives of the *sampled height* and the position, so it is scale-exact + // with no uv->mm assumption at all - which is the whole point here: an LSCM map is conformal, + // not isometric, so the local mm-per-uv varies across the chart and the earlier "one global + // 1/tiling factor" got the depth visibly wrong. dFdx(h) captures the true on-screen rate of + // change however the chart is stretched or however fine the tiling is. + // + // use_vertex_uv is a uniform, so this whole branch is uniform control flow and the texture + // derivatives are well defined; the paint weight gates the result by a plain multiply (k) + // rather than a per-fragment branch, keeping it that way. + // The dragged island's uv rides a uniform affine so its relief moves without a rebuild; every + // other vertex (island_active == 0) samples its baked uv unchanged. + vec2 uv = (island_active > 0.5) + ? vec2(dot(island_delta_lin.xy, vertex_uv), dot(island_delta_lin.zw, vertex_uv)) + island_delta_tr + : vertex_uv; + color_uv = uv; + have_uv = true; + float h = texture(height_tex, uv).r; + float k = (invert ? -1.0 : 1.0) * depth_mm * clamp(weight, 0.0, 1.0); + vec3 sigmaS = dFdx(world_pos.xyz); + vec3 sigmaT = dFdy(world_pos.xyz); + vec3 R1 = cross(sigmaT, triangle_normal); + vec3 R2 = cross(triangle_normal, sigmaS); + float det = dot(sigmaS, R1); + float dHdx = k * dFdx(h); + float dHdy = k * dFdy(h); + if (abs(det) > 1e-12) + triangle_normal = normalize(triangle_normal - (dHdx * R1 + dHdy * R2) / det); + } else if (weight > 0.0) { + // Triplanar path: uv and the tangent axes are reconstructed in-shader from the dominant + // normal component (see header). The gradient is expressed analytically because there is a + // closed-form uv here, unlike the LSCM case. + vec3 t, b; + vec2 units_per_mm; + projection_axes(tex_pos, triangle_normal, t, b, units_per_mm); + + // Parallax occlusion mapping: march the view ray through the height shell and shade at the + // first point where it drops below the displaced surface (see header). + float amp = (invert ? -1.0 : 1.0) * depth_mm * clamp(weight, 0.0, 1.0); + vec3 view_dir = normalize(eye_model_pos - tex_pos); + float v_dot_n = dot(view_dir, triangle_normal); + vec2 uv = project_uv(tex_pos, triangle_normal); + + // The shell the displaced surface lives inside, as signed heights along the normal. Taken from + // both ends of h in [0, 1] so it stays correct for an inverted layer or a raised midlevel, + // where the surface sits *below* the undisplaced one. + float h_end_a = amp * (0.0 - midlevel); + float h_end_b = amp * (1.0 - midlevel); + float h_hi = max(h_end_a, h_end_b); + float h_lo = min(h_end_a, h_end_b); + // How far, in mm, sweeping the ray across the shell slides the sample point sideways. Below half + // a texel there is no parallax to find and the march would be pure cost - which is the common + // case of looking straight down at a surface. + float sweep = length(view_dir - triangle_normal * v_dot_n) * (h_hi - h_lo) / max(v_dot_n, 1e-4); + if (v_dot_n > 0.05 && sweep > 0.5 * tiling_scale * height_tex_texel.x) { + // A point at ray parameter s (model_pos + view_dir * s) sits at height s * v_dot_n above the + // undisplaced surface. Start at the top of the shell, where the ray is outside the surface + // by construction, and step inward; the crossing is what this pixel actually sees. + float s = h_hi / v_dot_n; + float ds = (h_hi - h_lo) / (v_dot_n * float(PARALLAX_STEPS)); + vec2 prev_uv = project_uv(tex_pos + view_dir * s, triangle_normal); + float prev_gap = h_hi - amp * (H_AT(prev_uv) - midlevel); // >= 0 by construction + for (int i = 0; i < PARALLAX_STEPS; ++i) { + s -= ds; + vec2 cur_uv = project_uv(tex_pos + view_dir * s, triangle_normal); + float gap = s * v_dot_n - amp * (H_AT(cur_uv) - midlevel); + if (gap <= 0.0) { + // Crossed between the last two samples - interpolating the hit is what stops it + // quantising to the step size, and so what keeps the step count affordable. + uv = mix(prev_uv, cur_uv, clamp(prev_gap / max(prev_gap - gap, 1e-6), 0.0, 1.0)); + break; + } + prev_uv = cur_uv; + prev_gap = gap; + } + } + + color_uv = uv; // after the parallax march, so colour and relief stay registered + have_uv = true; + + float hL = texture(height_tex, uv - vec2(height_tex_texel.x, 0.0)).r; + float hR = texture(height_tex, uv + vec2(height_tex_texel.x, 0.0)).r; + float hD = texture(height_tex, uv - vec2(0.0, height_tex_texel.y)).r; + float hU = texture(height_tex, uv + vec2(0.0, height_tex_texel.y)).r; + + // Central difference, per uv unit (not per texel). + vec2 dh_duv = vec2((hR - hL) / (2.0 * height_tex_texel.x), (hU - hD) / (2.0 * height_tex_texel.y)); + + // uv -> mm is 1/tiling_scale for the triplanar projection, so this turns the uv-space + // gradient into a real surface slope. + float inv_tiling = (tiling_scale > 1e-6) ? (1.0 / tiling_scale) : 1.0; + float amplitude = (invert ? -1.0 : 1.0) * depth_mm * inv_tiling * clamp(weight, 0.0, 1.0); + // uv was rotated by project_uv() while t/b are the unrotated model axes, so rotate the + // gradient back into the axes' frame. + float cs = cos(rotation_rad); + float sn = sin(rotation_rad); + // One uv unit is tiling_scale mm along u but tiling_scale / tex_aspect mm along v, so the v + // component of the gradient carries the extra factor before being rotated back into t/b. + vec2 g = vec2(dh_duv.x, dh_duv.y * tex_aspect); + // ...and back out of raw-projection units into millimetres of travel along t / b, which is a + // no-op except for the spherical longitude (see projection_axes()). After the inverse rotation, + // because units_per_mm is expressed in the t/b frame rather than in uv. + vec2 slope = amplitude * vec2(g.x * cs + g.y * sn, -g.x * sn + g.y * cs) * units_per_mm; + + vec3 gradient = slope.x * t + slope.y * b; + gradient -= triangle_normal * dot(triangle_normal, gradient); + triangle_normal = normalize(triangle_normal - gradient); + } + + vec3 eye_normal = normalize(view_normal_matrix * triangle_normal); + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + vec2 intensity = vec2(0.0); + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec3 position = (view_model_matrix * model_pos).xyz; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Diffuse albedo: the image's colour at this fragment, snapped to the nearest printable colour - + // and, where that is a mix, the filament the interleave puts here, so the pattern that prints shows. + // Only the albedo - the specular term (intensity.y) stays white - so a coloured fragment reads as + // the same material under the same light, and the relief this preview exists to show is unaffected. + vec3 albedo = uniform_color.rgb; + if (palette_count > 0 && has_color_tex && have_uv && weight > 0.0) + // tex_pos, not world_pos: the bake resolves the interleave in the bake frame (world + // orientation and scale about the volume's origin, see texture_displacement_bake_frame()), so + // measuring z from the bed instead shifted the band phase by the volume origin's height - a + // different filament in the same place than the bake produces. + albedo = printed_color(nearest_palette_entry(texture(color_tex, color_uv).rgb), tex_pos, triangle_normal, pos_fwidth); + out_color = vec4(vec3(intensity.y) + albedo * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/140/texture_displacement_shaded.vs b/resources/shaders/140/texture_displacement_shaded.vs new file mode 100644 index 0000000000..cd629acedc --- /dev/null +++ b/resources/shaders/140/texture_displacement_shaded.vs @@ -0,0 +1,44 @@ +#version 140 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +uniform mat4 volume_world_matrix; +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +in vec3 v_position; +// GLModel's P3N3T2 layout (position + normal + texcoord), reused so this mesh builds and renders +// like any other GLModel rather than needing a bespoke vertex buffer. The two spare channels carry +// what the shaded preview actually needs per vertex: +// v_normal.x -- the active layer's paint weight, 0 (untouched) or 1 (painted). +// v_normal.y -- 1 for a vertex of the island currently being dragged in the UV editor, else 0. +// The fragment shader applies island_delta to those vertices' uv, so a UV drag is a +// single uniform update rather than a whole-mesh rebuild (like Adjust placement). +// v_tex_coord -- the precomputed texture uv for this vertex, valid only when use_vertex_uv is set +// (i.e. the LSCM projection, where uv can't be reconstructed in the shader). The +// triplanar path ignores it and projects in the fragment shader instead. +in vec3 v_normal; +in vec2 v_tex_coord; + +out vec3 clipping_planes_dots; +out vec4 model_pos; +out vec4 world_pos; +out float weight; +out float island_active; +out vec2 vertex_uv; + +void main() +{ + model_pos = vec4(v_position, 1.0); + world_pos = volume_world_matrix * model_pos; + + gl_Position = projection_matrix * view_model_matrix * model_pos; + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + weight = v_normal.x; + island_active = v_normal.y; + vertex_uv = v_tex_coord; +} diff --git a/resources/shaders/140/texture_displacement_uvcheck.fs b/resources/shaders/140/texture_displacement_uvcheck.fs new file mode 100644 index 0000000000..e6fc8036da --- /dev/null +++ b/resources/shaders/140/texture_displacement_uvcheck.fs @@ -0,0 +1,127 @@ +#version 140 + +// UV-check overlay for the texture-displacement gizmo, drawn over the painted patch so the LSCM +// unwrap can be sanity-checked on the real 3D surface (mode set by the `mode` uniform): +// mode 0 - Checker: a procedural checkerboard sampled at the layer's uv. Even squares that stay +// square everywhere on the model mean the unwrap is low-distortion; squares that smear or +// shear reveal exactly where it stretches. Same uv the bake samples, so what you see is +// where the texture actually lands. +// mode 1 - Distortion heatmap: the per-vertex area-distortion carried in `distortion`, blue +// (compressed) -> green (ideal) -> red (stretched). +// Both are lit with the same cheap two-light diffuse the shaded preview uses, so the surface still +// reads as 3D. + +#define INTENSITY_CORRECTION 0.6 +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) +#define INTENSITY_AMBIENT 0.3 +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform mat3 view_normal_matrix; +uniform bool volume_mirrored; + +uniform int mode; // 0 checker, 1 distortion +uniform float checker_freq; // checker squares per uv unit (one uv unit == one texture tile) +uniform float tiling_scale; +uniform vec3 tex_anchor; // the volume's origin in world space +uniform float rotation_rad; +uniform vec2 uv_offset; +uniform bool use_vertex_uv; +// The in-shader projection (0 Triplanar, 1 Cylindrical, 2 Spherical) and the painted patch's frame the +// wrapping ones wrap around, in the texture frame - the same uniforms, and the same formulas, as +// texture_displacement_shaded.fs, so the checker reports the projection the bake will actually use. +uniform int projection_mode; +uniform vec3 patch_center; +uniform vec3 patch_axis; +// Height map width / height, as apply_uv_transform() applies it. Without it the checker diverged from +// the bake for any non-square texture, in every in-shader projection. +uniform float tex_aspect; + +in vec3 clipping_planes_dots; +in vec4 model_pos; +in vec4 world_pos; +in float distortion; +in vec2 vertex_uv; + +out vec4 out_color; + +void cylinder_frame(out vec3 up, out vec3 right, out vec3 fwd) +{ + up = (length(patch_axis) > 1e-8) ? normalize(patch_axis) : vec3(0.0, 0.0, 1.0); + vec3 arbitrary = (abs(up.z) < 0.9) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + right = normalize(cross(up, arbitrary)); + fwd = normalize(cross(right, up)); +} + +// Term for term libslic3r's project_planar() / project_cylindrical() / project_spherical(), in mm. +vec2 projection_raw(vec3 p, vec3 n) +{ + if (projection_mode == 1) { + vec3 up, right, fwd; + cylinder_frame(up, right, fwd); + vec3 rel = p - patch_center; + float x = dot(rel, right); + float y = dot(rel, fwd); + return vec2(atan(y, x) * sqrt(x * x + y * y), dot(rel, up)); + } + if (projection_mode == 2) { + vec3 rel = p - patch_center; + float radius = length(rel); + if (radius < 1e-8) + return vec2(0.0); + vec3 dir = rel / radius; + return vec2(atan(dir.y, dir.x), asin(clamp(dir.z, -1.0, 1.0))) * radius; + } + vec3 an = abs(n); + return (an.x >= an.y && an.x >= an.z) ? p.yz : ((an.y >= an.x && an.y >= an.z) ? p.xz : p.xy); +} + +vec2 project_uv(vec3 p, vec3 n) +{ + vec2 planar = projection_raw(p, n); + planar *= (tiling_scale > 1e-6) ? (1.0 / tiling_scale) : 1.0; + float cs = cos(rotation_rad); + float sn = sin(rotation_rad); + vec2 r = vec2(planar.x * cs - planar.y * sn, planar.x * sn + planar.y * cs); + r.y *= tex_aspect; // after the rotation, so the rotation stays a rotation rather than a shear + return r + uv_offset; +} + +// Blue -> cyan -> green -> yellow -> red over t in [0,1]. +vec3 heatmap(float t) +{ + t = clamp(t, 0.0, 1.0); + return clamp(vec3(1.5 - abs(4.0 * t - 3.0), + 1.5 - abs(4.0 * t - 2.0), + 1.5 - abs(4.0 * t - 1.0)), 0.0, 1.0); +} + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + // World space anchored at the volume's origin, like the bake and the shaded preview. + vec3 triangle_normal = normalize(cross(dFdx(world_pos.xyz), dFdy(world_pos.xyz))); + vec3 tex_pos = world_pos.xyz - tex_anchor; + if (volume_mirrored) + triangle_normal = -triangle_normal; + + vec3 base; + if (mode == 1) { + base = heatmap(distortion); + } else { + vec2 uv = use_vertex_uv ? vertex_uv : project_uv(tex_pos, triangle_normal); + vec2 c = floor(uv * checker_freq); + float check = mod(c.x + c.y, 2.0); + // Two distinct greys, plus a faint tint on one set so orientation is readable at a glance. + base = (check < 0.5) ? vec3(0.22, 0.23, 0.26) : vec3(0.82, 0.83, 0.86); + } + + vec3 eye_normal = normalize(view_normal_matrix * triangle_normal); + float intensity = INTENSITY_AMBIENT + max(dot(eye_normal, LIGHT_TOP_DIR), 0.0) * LIGHT_TOP_DIFFUSE + + max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0) * LIGHT_FRONT_DIFFUSE; + out_color = vec4(base * intensity, 1.0); +} diff --git a/resources/shaders/140/texture_displacement_uvcheck.vs b/resources/shaders/140/texture_displacement_uvcheck.vs new file mode 100644 index 0000000000..79e858e0d7 --- /dev/null +++ b/resources/shaders/140/texture_displacement_uvcheck.vs @@ -0,0 +1,36 @@ +#version 140 + +// Vertex stage for the UV-check overlay (checker / distortion heatmap) drawn over the painted patch +// by GLGizmoTextureDisplacement. Reuses GLModel's P3N3T2 layout so it needs no bespoke buffer: +// v_normal.x - per-vertex UV distortion (uv-area / surface-area ratio, remapped so 0.5 = ideal); +// only the distortion mode reads it. +// v_tex_coord - precomputed texture uv, valid only when use_vertex_uv is set (LSCM); the checker +// mode reconstructs uv in the fragment shader otherwise. + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat4 volume_world_matrix; +uniform vec2 z_range; +uniform vec4 clipping_plane; + +in vec3 v_position; +in vec3 v_normal; +in vec2 v_tex_coord; + +out vec3 clipping_planes_dots; +out vec4 model_pos; +out vec4 world_pos; +out float distortion; +out vec2 vertex_uv; + +void main() +{ + model_pos = vec4(v_position, 1.0); + world_pos = volume_world_matrix * model_pos; + + gl_Position = projection_matrix * view_model_matrix * model_pos; + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + distortion = v_normal.x; + vertex_uv = v_tex_coord; +} diff --git a/resources/textures/displacement/Bark.png b/resources/textures/displacement/Bark.png new file mode 100644 index 0000000000..a48233d01e Binary files /dev/null and b/resources/textures/displacement/Bark.png differ diff --git a/resources/textures/displacement/Basket Weave.png b/resources/textures/displacement/Basket Weave.png new file mode 100644 index 0000000000..4459d87e6b Binary files /dev/null and b/resources/textures/displacement/Basket Weave.png differ diff --git a/resources/textures/displacement/Bricks weathered.png b/resources/textures/displacement/Bricks weathered.png new file mode 100644 index 0000000000..a20d979ec8 Binary files /dev/null and b/resources/textures/displacement/Bricks weathered.png differ diff --git a/resources/textures/displacement/Bricks.png b/resources/textures/displacement/Bricks.png new file mode 100644 index 0000000000..f89431370b Binary files /dev/null and b/resources/textures/displacement/Bricks.png differ diff --git a/resources/textures/displacement/Bubbles.png b/resources/textures/displacement/Bubbles.png new file mode 100644 index 0000000000..d04c58bd7d Binary files /dev/null and b/resources/textures/displacement/Bubbles.png differ diff --git a/resources/textures/displacement/Camouflage.png b/resources/textures/displacement/Camouflage.png new file mode 100644 index 0000000000..c0cde6accf Binary files /dev/null and b/resources/textures/displacement/Camouflage.png differ diff --git a/resources/textures/displacement/Carbon Fibre.png b/resources/textures/displacement/Carbon Fibre.png new file mode 100644 index 0000000000..53212f39a0 Binary files /dev/null and b/resources/textures/displacement/Carbon Fibre.png differ diff --git a/resources/textures/displacement/Chainmail.png b/resources/textures/displacement/Chainmail.png new file mode 100644 index 0000000000..7939d5b4a0 Binary files /dev/null and b/resources/textures/displacement/Chainmail.png differ diff --git a/resources/textures/displacement/Chevron.png b/resources/textures/displacement/Chevron.png new file mode 100644 index 0000000000..0a387439e2 Binary files /dev/null and b/resources/textures/displacement/Chevron.png differ diff --git a/resources/textures/displacement/Cobblestone.png b/resources/textures/displacement/Cobblestone.png new file mode 100644 index 0000000000..f9f7ed0035 Binary files /dev/null and b/resources/textures/displacement/Cobblestone.png differ diff --git a/resources/textures/displacement/Colour Bricks.png b/resources/textures/displacement/Colour Bricks.png new file mode 100644 index 0000000000..a8b574f14b Binary files /dev/null and b/resources/textures/displacement/Colour Bricks.png differ diff --git a/resources/textures/displacement/Cracked Earth.png b/resources/textures/displacement/Cracked Earth.png new file mode 100644 index 0000000000..9876500318 Binary files /dev/null and b/resources/textures/displacement/Cracked Earth.png differ diff --git a/resources/textures/displacement/Diamond Plate.png b/resources/textures/displacement/Diamond Plate.png new file mode 100644 index 0000000000..0b474a6921 Binary files /dev/null and b/resources/textures/displacement/Diamond Plate.png differ diff --git a/resources/textures/displacement/Fine Knurl.png b/resources/textures/displacement/Fine Knurl.png new file mode 100644 index 0000000000..dddd2480a0 Binary files /dev/null and b/resources/textures/displacement/Fine Knurl.png differ diff --git a/resources/textures/displacement/Grid.png b/resources/textures/displacement/Grid.png new file mode 100644 index 0000000000..14bd166a2c Binary files /dev/null and b/resources/textures/displacement/Grid.png differ diff --git a/resources/textures/displacement/Hammered.png b/resources/textures/displacement/Hammered.png new file mode 100644 index 0000000000..45fac6009b Binary files /dev/null and b/resources/textures/displacement/Hammered.png differ diff --git a/resources/textures/displacement/Herringbone.png b/resources/textures/displacement/Herringbone.png new file mode 100644 index 0000000000..d773b9f615 Binary files /dev/null and b/resources/textures/displacement/Herringbone.png differ diff --git a/resources/textures/displacement/Hex Tiles.png b/resources/textures/displacement/Hex Tiles.png new file mode 100644 index 0000000000..2c924d18ec Binary files /dev/null and b/resources/textures/displacement/Hex Tiles.png differ diff --git a/resources/textures/displacement/Hexagons.png b/resources/textures/displacement/Hexagons.png new file mode 100644 index 0000000000..accc9f5fb3 Binary files /dev/null and b/resources/textures/displacement/Hexagons.png differ diff --git a/resources/textures/displacement/Honeycomb.png b/resources/textures/displacement/Honeycomb.png new file mode 100644 index 0000000000..d428a5d2b3 Binary files /dev/null and b/resources/textures/displacement/Honeycomb.png differ diff --git a/resources/textures/displacement/Knurl.png b/resources/textures/displacement/Knurl.png new file mode 100644 index 0000000000..373e2badd6 Binary files /dev/null and b/resources/textures/displacement/Knurl.png differ diff --git a/resources/textures/displacement/Leather.png b/resources/textures/displacement/Leather.png new file mode 100644 index 0000000000..0c16daac63 Binary files /dev/null and b/resources/textures/displacement/Leather.png differ diff --git a/resources/textures/displacement/Mosaic Tiles.png b/resources/textures/displacement/Mosaic Tiles.png new file mode 100644 index 0000000000..e5e30e0bc2 Binary files /dev/null and b/resources/textures/displacement/Mosaic Tiles.png differ diff --git a/resources/textures/displacement/Noise.png b/resources/textures/displacement/Noise.png new file mode 100644 index 0000000000..c945e9ca8c Binary files /dev/null and b/resources/textures/displacement/Noise.png differ diff --git a/resources/textures/displacement/Perforated.png b/resources/textures/displacement/Perforated.png new file mode 100644 index 0000000000..5ea3435f14 Binary files /dev/null and b/resources/textures/displacement/Perforated.png differ diff --git a/resources/textures/displacement/Pyramids.png b/resources/textures/displacement/Pyramids.png new file mode 100644 index 0000000000..bb83b97b84 Binary files /dev/null and b/resources/textures/displacement/Pyramids.png differ diff --git a/resources/textures/displacement/Quilt.png b/resources/textures/displacement/Quilt.png new file mode 100644 index 0000000000..f0a07b31b5 Binary files /dev/null and b/resources/textures/displacement/Quilt.png differ diff --git a/resources/textures/displacement/Ripples.png b/resources/textures/displacement/Ripples.png new file mode 100644 index 0000000000..d06c6a58da Binary files /dev/null and b/resources/textures/displacement/Ripples.png differ diff --git a/resources/textures/displacement/Roof Tiles.png b/resources/textures/displacement/Roof Tiles.png new file mode 100644 index 0000000000..ed28294cb6 Binary files /dev/null and b/resources/textures/displacement/Roof Tiles.png differ diff --git a/resources/textures/displacement/Rope.png b/resources/textures/displacement/Rope.png new file mode 100644 index 0000000000..da6c6c1ffa Binary files /dev/null and b/resources/textures/displacement/Rope.png differ diff --git a/resources/textures/displacement/Sand Ripples.png b/resources/textures/displacement/Sand Ripples.png new file mode 100644 index 0000000000..7b4cd77312 Binary files /dev/null and b/resources/textures/displacement/Sand Ripples.png differ diff --git a/resources/textures/displacement/Scales.png b/resources/textures/displacement/Scales.png new file mode 100644 index 0000000000..6976dfad9d Binary files /dev/null and b/resources/textures/displacement/Scales.png differ diff --git a/resources/textures/displacement/Slate.png b/resources/textures/displacement/Slate.png new file mode 100644 index 0000000000..b63853a2d7 Binary files /dev/null and b/resources/textures/displacement/Slate.png differ diff --git a/resources/textures/displacement/Star Tiles.png b/resources/textures/displacement/Star Tiles.png new file mode 100644 index 0000000000..e1406e6f26 Binary files /dev/null and b/resources/textures/displacement/Star Tiles.png differ diff --git a/resources/textures/displacement/Stone Wall.png b/resources/textures/displacement/Stone Wall.png new file mode 100644 index 0000000000..f5239f92f9 Binary files /dev/null and b/resources/textures/displacement/Stone Wall.png differ diff --git a/resources/textures/displacement/Studs.png b/resources/textures/displacement/Studs.png new file mode 100644 index 0000000000..1f9baaa7e8 Binary files /dev/null and b/resources/textures/displacement/Studs.png differ diff --git a/resources/textures/displacement/Tartan.png b/resources/textures/displacement/Tartan.png new file mode 100644 index 0000000000..a5c321daa3 Binary files /dev/null and b/resources/textures/displacement/Tartan.png differ diff --git a/resources/textures/displacement/Terrazzo.png b/resources/textures/displacement/Terrazzo.png new file mode 100644 index 0000000000..0b817546bb Binary files /dev/null and b/resources/textures/displacement/Terrazzo.png differ diff --git a/resources/textures/displacement/Triangles.png b/resources/textures/displacement/Triangles.png new file mode 100644 index 0000000000..f9f21d88e5 Binary files /dev/null and b/resources/textures/displacement/Triangles.png differ diff --git a/resources/textures/displacement/Waffle.png b/resources/textures/displacement/Waffle.png new file mode 100644 index 0000000000..06b5de6377 Binary files /dev/null and b/resources/textures/displacement/Waffle.png differ diff --git a/resources/textures/displacement/Waves.png b/resources/textures/displacement/Waves.png new file mode 100644 index 0000000000..71a262435b Binary files /dev/null and b/resources/textures/displacement/Waves.png differ diff --git a/resources/textures/displacement/Weave.png b/resources/textures/displacement/Weave.png new file mode 100644 index 0000000000..022c423b81 Binary files /dev/null and b/resources/textures/displacement/Weave.png differ diff --git a/resources/textures/displacement/Wood Grain.png b/resources/textures/displacement/Wood Grain.png new file mode 100644 index 0000000000..e65ce88d65 Binary files /dev/null and b/resources/textures/displacement/Wood Grain.png differ diff --git a/resources/textures/displacement/Wood Planks.png b/resources/textures/displacement/Wood Planks.png new file mode 100644 index 0000000000..b0e02f0b02 Binary files /dev/null and b/resources/textures/displacement/Wood Planks.png differ diff --git a/resources/web/model/model.js b/resources/web/model/model.js index b401bea75b..3d7c2fc8ad 100644 --- a/resources/web/model/model.js +++ b/resources/web/model/model.js @@ -214,9 +214,9 @@ function ShowModelInfo( pModel ) SendWXDebugInfo("Model Name: "+sModelName); - $('#ModelName').html(sModelName); + $('#ModelName').text(sModelName); $('#ModelName').attr('title',sModelName); - $('#ModelAuthorName').html(sModelAuthor); + $('#ModelAuthorName').text(sModelAuthor); switch(UploadType) { @@ -268,7 +268,7 @@ function ShowModelInfo( pModel ) break; } - $('#Model_Desc').html( html_decode(sModelDesc) ); + $('#Model_Desc').empty().append( SanitizeDescHtml( html_decode(sModelDesc) ) ); let ModelPreviewList=pModel.preview_img; let TotalPreview=ModelPreviewList.length; @@ -281,16 +281,15 @@ function ShowModelInfo( pModel ) if(TotalPreview>0) { - let htmlPreview=''; + $('#ModelPreviewList').empty(); for(let pn=0;pn'; + $('#ModelPreviewList').append( $('
').append( $('').attr('src',FTmpPath) ) ); } - $('#ModelPreviewList').html(htmlPreview); $('#Model_Preview_Image').viewer({ title: false, fullsreen: false, @@ -410,7 +409,8 @@ function ConstructFileHtml( ID, pItem ) { let fTotal=pItem.length; - let strHtml=''; + let pBoard=$('#'+ID+' .FileListBoard'); + pBoard.empty(); for( let f=0;f').attr('src',ImgPath); + let pMenu=$('
'); if( strClass!='ImageIcon' ) { - strHtml+='
'+ - '
'+ - '
'+ - '
'+tName+'
'+ - '
'+ - '
'+ - '
'; + pMenu.on('click', function(){ OnClickOpenFile(tPath); }); } else { ImgID++; let TmpImgID="AF"+ImgID; - strHtml+='
'+ - '
'+ - '
'+ - '
'+tName+'
'+ - '
'+ - '
'+ - '
'; + pIconImg.attr('id',TmpImgID); + pMenu.on('click', function(){ OnClickOpenImage(TmpImgID); }); } + + let pFileItem=$('
'); + pFileItem.append( $('
').addClass(strClass).append(pIconImg) ); + pFileItem.append( $('
').append( $('
').text(tName).attr('title',tName) ) ); + pFileItem.append( pMenu ); + pBoard.append( pFileItem ); } - $('#'+ID+' .FileListBoard').html(strHtml); - if( fTotal>0 ) $('#'+ID).show(); } +// Descriptions are untrusted 3MF metadata that may carry rich-text HTML (e.g. from MakerWorld). +// Rebuild them from an inert parse, keeping only plain formatting tags and http(s) links and images. +var DescAllowedTags=['P','BR','B','STRONG','I','EM','U','S','STRIKE','DEL','INS','SUB','SUP','SMALL','MARK', + 'Q','ABBR','KBD','WBR','H1','H2','H3','H4','H5','H6','UL','OL','LI','DL','DT','DD','BLOCKQUOTE','PRE','CODE', + 'HR','SPAN','DIV','FIGURE','FIGCAPTION','TABLE','CAPTION','THEAD','TBODY','TFOOT','TR','TH','TD','A','IMG']; +// Plain attributes kept per tag; the numeric ones must be plain non-negative integers. +var DescAllowedAttrs={'IMG':['alt','title','width','height'],'TD':['colspan','rowspan'],'TH':['colspan','rowspan'],'OL':['start']}; +var DescNumericAttrs=['width','height','colspan','rowspan','start']; +// Dropped together with their content; any other unknown tag is unwrapped to its children. +var DescDroppedTags=['SCRIPT','STYLE','TEMPLATE','NOSCRIPT','TEXTAREA','TITLE','IFRAME','FRAME','OBJECT','EMBED','SVG','MATH']; + +function IsHttpUrl( strUrl ) +{ + // The scheme must be written as is, so nothing the URL parser would strip can precede or split it. + if( typeof strUrl!='string' || !/^https?:/i.test(strUrl) ) + return false; + try + { + let sProtocol=new URL(strUrl).protocol; + return sProtocol=='http:' || sProtocol=='https:'; + } + catch(e) + { + return false; + } +} + +// Images load as soon as the page opens, so only https sources are kept: no plain-http requests to the local network. +function IsHttpsUrl( strUrl ) +{ + return IsHttpUrl(strUrl) && new URL(strUrl).protocol=='https:'; +} + +// Embedded YouTube players become a plain link to the video. +function GetYouTubeEmbedUrl( pNode ) +{ + let sSrc=pNode.getAttribute('src'); + if( !IsHttpUrl(sSrc) ) + return null; + let pUrl=new URL(sSrc); + return ( pUrl.origin=='https://www.youtube.com' && pUrl.pathname.indexOf('/embed/')==0 ) ? pUrl.href : null; +} + +function CopyDescNodes( pSrc, pDst ) +{ + for( let pNode=pSrc.firstChild;pNode!=null;pNode=pNode.nextSibling ) + { + if( pNode.nodeType==Node.TEXT_NODE ) + { + pDst.appendChild( document.createTextNode(pNode.nodeValue) ); + continue; + } + if( pNode.nodeType!=Node.ELEMENT_NODE ) + continue; + + let sTag=pNode.nodeName.toUpperCase(); + if( sTag=='IFRAME' ) + { + let sVideoUrl=GetYouTubeEmbedUrl(pNode); + if( sVideoUrl!=null ) + { + let pLink=document.createElement('A'); + pLink.setAttribute('href',sVideoUrl); + pLink.textContent=sVideoUrl; + pDst.appendChild(pLink); + } + continue; + } + if( $.inArray(sTag,DescDroppedTags)>=0 ) + continue; + if( $.inArray(sTag,DescAllowedTags)<0 ) + { + CopyDescNodes(pNode,pDst); + continue; + } + + let pElem=document.createElement(sTag); + if( sTag=='A' && IsHttpUrl(pNode.getAttribute('href')) ) + pElem.setAttribute('href',pNode.getAttribute('href')); + else if( sTag=='IMG' ) + { + if( !IsHttpsUrl(pNode.getAttribute('src')) ) + continue; + pElem.setAttribute('src',pNode.getAttribute('src')); + } + $.each( DescAllowedAttrs[sTag]||[], function(i,sAttr){ + let sValue=pNode.getAttribute(sAttr); + if( sValue!=null && ( $.inArray(sAttr,DescNumericAttrs)<0 || /^\d+$/.test(sValue) ) ) + pElem.setAttribute(sAttr,sValue); + }); + CopyDescNodes(pNode,pElem); + pDst.appendChild(pElem); + } +} + +function SanitizeDescHtml( strHtml ) +{ + let pFragment=document.createDocumentFragment(); + // A DOMParser document is inert: it runs no scripts and loads no resources. + let pDoc=new DOMParser().parseFromString(strHtml,'text/html'); + if( pDoc && pDoc.body ) + CopyDescNodes(pDoc.body,pFragment); + return pFragment; +} + function ShowProfilelInfo( pProfile ) { //==========Profile Info========== @@ -483,10 +583,10 @@ function ShowProfilelInfo( pProfile ) let sProfileAuthor=decodeURIComponent(pProfile.author); let sProfileDesc=decodeURIComponent(pProfile.description); - $('#ProfileName').html(sProfileName); - $('#ProfileAuthor').html(sProfileAuthor); + $('#ProfileName').text(sProfileName); + $('#ProfileAuthor').text(sProfileAuthor); - $('#Profile_Desc').html( html_decode(sProfileDesc) ); + $('#Profile_Desc').empty().append( SanitizeDescHtml( html_decode(sProfileDesc) ) ); let ProfilePreviewList=pProfile.preview_img; let TotalPreview=ProfilePreviewList.length; @@ -499,15 +599,14 @@ function ShowProfilelInfo( pProfile ) if(TotalPreview>0) { - let htmlPreview=''; + $('#ProfilePreviewList').empty(); for(let pn=0;pn'; + $('#ProfilePreviewList').append( $('
').append( $('').attr('src',FTmpPath) ) ); } - $('#ProfilePreviewList').html(htmlPreview); $('#Profile_Preview_Image').viewer({ title: false, fullsreen: false, diff --git a/scripts/CAD/README.md b/scripts/CAD/README.md index 861b77a976..a5c6836e29 100644 --- a/scripts/CAD/README.md +++ b/scripts/CAD/README.md @@ -33,6 +33,21 @@ part of `libslic3r_tests` and run under `ctest` on every platform like any other unit test. This script exists for the local loop, where it is a two-minute round trip instead of a full application build. +## Generated sources + +Two checked-in files are emitted from data that lives here, so the source and the thing +compiled against it cannot drift apart: + +| Generator | Source | Output | +|---|---|---| +| `gen_offer_table.py` | `tool_atlas.json` — every offer verb with its row, key, icon, accepted selections and refusal string | `src/slic3r/GUI/CAD/DesignOffer.hpp` | +| `mate-glyph/emit_glyph_table.py` | `mate-glyph/bear_outline.json`, measured off `mate-glyph/bear.step` by `extract_outline.py` (needs FreeCAD) | the `kBear…` tables in `DesignSketchTool.cpp` | + +`python3 scripts/CAD/gen_offer_table.py` rewrites the header and `--check` proves the +checked-in one matches the atlas — `run-all-checks.sh` runs the check as its first rung, +which is what makes the header's "GENERATED — DO NOT EDIT" enforceable. Edit the atlas, +never the header. + ## Build and run | Script | Purpose | @@ -48,6 +63,6 @@ Two constraints that are not obvious and have each cost a session: - **A window manager is required.** Without one, windows are never focused, and an unfocused GTK app ignores synthetic keys — which looks exactly like a code bug. -`docs/rig_build_traps.md` documents these and three more, with symptoms and exact +`scripts/CAD/rig_build_traps.md` documents these and three more, with symptoms and exact recovery commands. Read it before debugging a configure or link failure one of these scripts reports. diff --git a/scripts/CAD/build-gui-incremental.sh b/scripts/CAD/build-gui-incremental.sh index 539a21c973..f87113fdaf 100755 --- a/scripts/CAD/build-gui-incremental.sh +++ b/scripts/CAD/build-gui-incremental.sh @@ -15,7 +15,7 @@ # On success the binary is inside the persistent volume at # /OrcaSlicer/build/package/bin/orca-slicer (copy it out with a follow-up # `docker run --rm -v orcacad_buildcache:/b alpine cp ...` or via this script's tail). -# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md +# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): scripts/CAD/rig_build_traps.md set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" diff --git a/scripts/CAD/build-gui.sh b/scripts/CAD/build-gui.sh index 0a1a86dd5c..edf93a5ca0 100755 --- a/scripts/CAD/build-gui.sh +++ b/scripts/CAD/build-gui.sh @@ -5,7 +5,7 @@ # NEVER build inside the GUI container (snapmaker-gui / orcacad-gui). Its baked /OrcaSlicer tree # is the Jun-13 Snapmaker-derived source, so a `cmake .` in there silently reconfigures the # shared build dir as project(Snapmaker_Orca) and this fork's targets vanish. That is Trap 1 of -# five; all of them, with symptoms and exact recovery commands, are in docs/rig_build_traps.md. +# five; all of them, with symptoms and exact recovery commands, are in scripts/CAD/rig_build_traps.md. # Read that file before debugging a configure or link failure this script reports. # # Usage: @@ -92,7 +92,7 @@ docker run --rm \ # A target-only build writes src/Release/, but this fork's start-headless-gui.sh may default BIN to the # PACKAGED path that only build_linux.sh refreshes — launching with the default would then run a -# stale binary. Pass BIN explicitly. See docs/rig_build_traps.md. +# stale binary. Pass BIN explicitly. See scripts/CAD/rig_build_traps.md. echo "=== launch the rig on the binary just built ===" echo " docker exec -e BIN=/OrcaSlicer/build/src/Release/$BIN ${PREFIX}-gui /OrcaSlicer/scripts/CAD/start-headless-gui.sh" exit "$rc" diff --git a/docs/CAD/ux/mockups/gen_offer_table.py b/scripts/CAD/gen_offer_table.py similarity index 80% rename from docs/CAD/ux/mockups/gen_offer_table.py rename to scripts/CAD/gen_offer_table.py index 9744f9288b..442be27697 100644 --- a/docs/CAD/ux/mockups/gen_offer_table.py +++ b/scripts/CAD/gen_offer_table.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 -"""Emit the C++ offer table from docs/ux/tool_atlas.json. +"""Emit the C++ offer table from scripts/CAD/tool_atlas.json. - python3 docs/ux/mockups/gen_offer_table.py + python3 scripts/CAD/gen_offer_table.py # rewrite the header + python3 scripts/CAD/gen_offer_table.py --check # verify the checked-in header -The map exists ONCE. The mockups and the shipping menu read the same rows in the same -order from the same file, so a drawing and the product cannot drift apart — which is the -only way row constancy (charter 4.1) survives contact with a codebase. +The map exists ONCE: the atlas is the only place a verb's row, key, icon and refusal +string are written down, so the menu the user sees cannot drift from the table the code +is compiled against. Output: src/slic3r/GUI/CAD/DesignOffer.hpp, checked in and never hand-edited. """ @@ -14,15 +15,9 @@ import json import os import sys -HERE = os.path.dirname(os.path.abspath(__file__)) -UX = os.path.dirname(HERE) -# One dirname more than you would expect: this generator lives at docs/CAD/ux/mockups/, -# not docs/ux/mockups/, since the design docs moved into the CAD subfolder (bbd1989e1e). -# With the old count REPO resolved to docs/, so OUT pointed at docs/src/.../DesignOffer.hpp, -# which does not exist -- and --check then diffed the real generated table against an empty -# file and reported the whole 189-line header as a difference. -REPO = os.path.dirname(os.path.dirname(os.path.dirname(UX))) -ATLAS = os.path.join(UX, "tool_atlas.json") +HERE = os.path.dirname(os.path.abspath(__file__)) # scripts/CAD +REPO = os.path.dirname(os.path.dirname(HERE)) +ATLAS = os.path.join(HERE, "tool_atlas.json") OUT = os.path.join(REPO, "src", "slic3r", "GUI", "CAD", "DesignOffer.hpp") # selection id -> C++ enumerator @@ -42,15 +37,40 @@ def cstr(s): return '"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"' +def validate(A): + """Refuse an atlas the header cannot represent, naming every fault at once. + + An unknown slot or selection would surface as a bare ValueError from .index() below, and a + duplicate verb id would not surface at all: DesignPanel::mcp_run_verb looks a verb up by id + and takes the first match, so the second row would be unreachable from the offer. + """ + slot_ids = {s["id"] for s in A["slots"]} + sel_ids = {s["id"] for s in A["selections"]} + errs, seen = [], set() + for v in A["verbs"]: + if v["slot"] not in slot_ids: + errs.append(f'{v["id"]}: unknown slot {v["slot"]!r}') + for a in v["accepts"]: + if a not in sel_ids: + errs.append(f'{v["id"]}: accepts unknown selection {a!r}') + if v["id"] in seen: + errs.append(f'{v["id"]}: duplicate verb id') + seen.add(v["id"]) + for s in sel_ids - set(ENUM): + errs.append(f"selection {s!r} has no OfferSel enumerator") + if errs: + sys.exit("tool_atlas.json is inconsistent:\n " + "\n ".join(errs)) + + def main(): A = json.load(open(ATLAS, encoding="utf-8")) + validate(A) sels = [s["id"] for s in A["selections"]] - assert all(s in ENUM for s in sels), [s for s in sels if s not in ENUM] slots = [s["id"] for s in A["slots"]] lines = [ "// GENERATED FILE — DO NOT EDIT.", - "// Source: docs/ux/tool_atlas.json Generator: docs/ux/mockups/gen_offer_table.py", + "// Source: scripts/CAD/tool_atlas.json Generator: scripts/CAD/gen_offer_table.py", "//", "// The object-driven tool offer (charter 4.1): every verb has ONE row index, that index", "// is the same in every selection it appears in, and verbs that do not apply are shown", diff --git a/docs/CAD/design/mate-connectors/bear.step b/scripts/CAD/mate-glyph/bear.step similarity index 100% rename from docs/CAD/design/mate-connectors/bear.step rename to scripts/CAD/mate-glyph/bear.step diff --git a/docs/CAD/design/mate-connectors/bear_outline.json b/scripts/CAD/mate-glyph/bear_outline.json similarity index 100% rename from docs/CAD/design/mate-connectors/bear_outline.json rename to scripts/CAD/mate-glyph/bear_outline.json diff --git a/docs/CAD/design/mate-connectors/emit_glyph_table.py b/scripts/CAD/mate-glyph/emit_glyph_table.py similarity index 100% rename from docs/CAD/design/mate-connectors/emit_glyph_table.py rename to scripts/CAD/mate-glyph/emit_glyph_table.py diff --git a/docs/CAD/design/mate-connectors/extract_outline.py b/scripts/CAD/mate-glyph/extract_outline.py similarity index 100% rename from docs/CAD/design/mate-connectors/extract_outline.py rename to scripts/CAD/mate-glyph/extract_outline.py diff --git a/docs/CAD/rig_build_traps.md b/scripts/CAD/rig_build_traps.md similarity index 100% rename from docs/CAD/rig_build_traps.md rename to scripts/CAD/rig_build_traps.md diff --git a/scripts/CAD/run-all-checks.sh b/scripts/CAD/run-all-checks.sh index 1c0388ac89..8a99a3b6cb 100755 --- a/scripts/CAD/run-all-checks.sh +++ b/scripts/CAD/run-all-checks.sh @@ -54,10 +54,9 @@ run_in_rig() { # copy the script in fresh, then run it ther # says. The header calls itself GENERATED and had been hand-edited anyway — which cost four rows # that existed only in the header, one row wired to the wrong action, and a count of 91 for a # 92-row array, so the last verb was unreachable (z8rs, ziam). -# docs/CAD/, not docs/: SoftFever moved the design docs into the CAD subfolder -# (bbd1989e1e) and this line kept the old path, so the rung failed on a missing file -# rather than on anything about the table. The other fork still has docs/ux/. -step "offer table matches the atlas" python3 docs/CAD/ux/mockups/gen_offer_table.py --check +# The atlas and its generator live beside this script, in scripts/CAD/: they are build inputs +# for a checked-in header, not documentation, so they do not belong under docs/. +step "offer table matches the atlas" python3 scripts/CAD/gen_offer_table.py --check step "kernel suite" scripts/CAD/run-kernel-tests.sh --vol "${KVOL:-orcacad_kerneltest}" diff --git a/scripts/CAD/run-kernel-tests.sh b/scripts/CAD/run-kernel-tests.sh index ef4356cb65..cc52a2a00b 100755 --- a/scripts/CAD/run-kernel-tests.sh +++ b/scripts/CAD/run-kernel-tests.sh @@ -19,7 +19,7 @@ # working tree to a per-volume staging dir on that host and re-runs this same script # there, so the verification contract is identical either way. Drop --host once the image # is present locally. -# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md +# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): scripts/CAD/rig_build_traps.md set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" diff --git a/docs/CAD/ux/tool_atlas.json b/scripts/CAD/tool_atlas.json similarity index 99% rename from docs/CAD/ux/tool_atlas.json rename to scripts/CAD/tool_atlas.json index 94709f2057..224b118c9e 100644 --- a/docs/CAD/ux/tool_atlas.json +++ b/scripts/CAD/tool_atlas.json @@ -1,6 +1,6 @@ { "_comment": [ - "Source of truth for the object-driven tool offer (see docs/cad_ux_guidelines.md 4.1).", + "Source of truth for the object-driven tool offer (see docs/HLSD/design-tab.md).", "Every verb, the selections it accepts, the document state it needs, and its fixed", "compass address. Extracted from the code, not from memory:", " verbs + shortcuts + refusal messages -> src/slic3r/GUI/CAD/DesignPanel.cpp (feat_dropdown", @@ -8,8 +8,8 @@ " kernel coverage -> src/libslic3r/CAD/CadDocument.hpp (enum CadFeatureType)", " headless coverage -> src/slic3r/GUI/CAD/McpControl.cpp (method == \"...\")", " selection kinds -> src/slic3r/GUI/CAD/DesignCanvas.hpp (the on_*_selected callbacks)", - "gen_offer_mockups.py reads this file; the eventual C++ offer table is generated from it", - "too, so the map exists once." + "gen_offer_table.py emits src/slic3r/GUI/CAD/DesignOffer.hpp from this file, so the map", + "exists once. Edit the atlas and regenerate; never hand-edit the header." ], "slots": [ { diff --git a/scripts/generate_displacement_textures.py b/scripts/generate_displacement_textures.py new file mode 100644 index 0000000000..0bb34c2223 --- /dev/null +++ b/scripts/generate_displacement_textures.py @@ -0,0 +1,517 @@ +#!/usr/bin/env python3 +"""Generates the displacement textures shipped in resources/textures/displacement/. + +Every texture is procedural - periodic functions and wrap-around noise on a unit tile - so the images +tile seamlessly in both directions and carry no third-party material. Grey PNGs are height maps +(white = raised). The colour PNGs are RGB where the luminance is the height, which is what +decode_height_texture() reads, so they displace and colour at the same time. + + python3 scripts/generate_displacement_textures.py [--size 1024] [--out resources/textures/displacement] + +Needs numpy and Pillow. Regenerating overwrites the files this script owns and nothing else. +""" +import argparse, os +import numpy as np +from PIL import Image + +SS = 2 # supersampling factor; the final image is the box-filtered average + +# --------------------------------------------------------------------------------------------- +# helpers: everything works on u, v in [0, 1) with period 1 on the tile +# --------------------------------------------------------------------------------------------- +def grid(n): + s = n * SS + v, u = np.meshgrid((np.arange(s) + 0.5) / s, (np.arange(s) + 0.5) / s, indexing='ij') + return u, v + +def down(img): + s = img.shape[0] // SS + return img.reshape(s, SS, s, SS).mean(axis=(1, 3)) + +def norm(h): + h = h - h.min(); m = h.max() + return h / m if m > 0 else h + +def smoothstep(e0, e1, x): + t = np.clip((x - e0) / (e1 - e0), 0.0, 1.0) + return t * t * (3 - 2 * t) + +def value_noise(u, v, freq, seed): + """Tileable value noise: a random lattice of `freq` cells with wrap-around, smooth interpolation.""" + rng = np.random.default_rng(seed) + lat = rng.random((freq, freq)) + x = u * freq; y = v * freq + x0 = np.floor(x).astype(int); y0 = np.floor(y).astype(int) + fx = x - x0; fy = y - y0 + fx = fx * fx * (3 - 2 * fx); fy = fy * fy * (3 - 2 * fy) + x1 = (x0 + 1) % freq; y1 = (y0 + 1) % freq; x0 %= freq; y0 %= freq + a = lat[y0, x0]; b = lat[y0, x1]; c = lat[y1, x0]; d = lat[y1, x1] + return (a * (1 - fx) + b * fx) * (1 - fy) + (c * (1 - fx) + d * fx) * fy + +def fbm(u, v, freq, seed, octaves=4, gain=0.5): + out = np.zeros_like(u); amp = 1.0; total = 0.0 + for o in range(octaves): + out += amp * value_noise(u, v, freq * 2 ** o, seed + o); total += amp; amp *= gain + return out / total + +def wrapped_points(n, seed, jitter=0.35): + """n x n jittered lattice points on the unit tile (periodic).""" + rng = np.random.default_rng(seed) + gx, gy = np.meshgrid((np.arange(n) + 0.5) / n, (np.arange(n) + 0.5) / n) + pts = np.stack([gx.ravel(), gy.ravel()], 1) + (rng.random((n * n, 2)) - 0.5) * (jitter / n) + return pts % 1.0 + +def voronoi(u, v, pts): + """Distance to the nearest and second-nearest point on the torus, and the nearest point's index.""" + d1 = np.full(u.shape, 9.0); d2 = np.full(u.shape, 9.0); idx = np.zeros(u.shape, int) + for i, (px, py) in enumerate(pts): + dx = u - px; dx -= np.round(dx); dy = v - py; dy -= np.round(dy) + d = np.sqrt(dx * dx + dy * dy) + closer = d < d1 + d2 = np.where(closer, d1, np.minimum(d2, d)); d1 = np.where(closer, d, d1); idx = np.where(closer, i, idx) + return d1, d2, idx + +def tri_wave(x): + return np.abs(2 * (x - np.floor(x + 0.5))) # 0..1 triangle wave, period 1 + +# --------------------------------------------------------------------------------------------- +# the textures +# --------------------------------------------------------------------------------------------- +def diamond_plate(u, v): + # Raised diamonds in two offset rows, bevelled; the classic tread plate. + n = 4 + h = np.zeros_like(u) + for ox, oy in ((0.0, 0.0), (0.5, 0.5)): + x = (u * n + ox) % 1 - 0.5; y = (v * n + oy) % 1 - 0.5 + d = np.abs(x) / 0.36 + np.abs(y) / 0.18 # a long diamond, 2:1 + h = np.maximum(h, smoothstep(1.0, 0.72, d)) + h += 0.06 * fbm(u, v, 32, 11) + return norm(h) + +def hex_cells(u, v, nx): + """Distance to the nearest hexagon centre, normalised so the hexagon's edge is at 1, plus a cell id. + nx hexagons across; the rows are stretched by at most ~2 % so a whole number fit the tile.""" + W = 1.0 / nx # hexagon width (flat-to-flat, pointy-top layout) + H = 2 * W / np.sqrt(3) # ideal corner-to-corner height + ny = 2 * max(1, int(round(1.0 / (1.5 * H)))) # rows per tile, even: the two staggered lattices + H = 1.0 / (0.75 * ny) # stretched so the rows tile exactly + best = np.full(u.shape, 9.0); cid = np.zeros(u.shape, int) + for k, (ox, oy) in enumerate(((0.0, 0.0), (0.5, 0.5))): + cx = (np.round(u / W - ox) + ox) * W; cy = (np.round(v / (1.5 * H) - oy) + oy) * 1.5 * H + dx = u - cx + dy = (v - cy) * (2 * W / np.sqrt(3)) / H # undo the row stretch: regular-hex units + ax = np.abs(dx) / (W / 2); ay = np.abs(dy) / (W / 2) + d = np.maximum(ax, (ax + ay * np.sqrt(3)) / 2) # hexagon SDF, edge at 1 + ix = np.round(u / W - ox).astype(int) % nx; iy = np.round(v / (1.5 * H) - oy).astype(int) % (ny // 2) + this = (ix * 7 + iy * 13 + k * 3) % 1009 # periodic, so a cell's colour matches across the seam + cid = np.where(d < best, this, cid); best = np.minimum(best, d) + return best, cid + +def honeycomb(u, v): + d, _ = hex_cells(u, v, 7) + return norm(smoothstep(1.0, 0.86, d)) + +def knurl(u, v): + n = 24 + a = tri_wave((u + v) * n); b = tri_wave((u - v) * n) + return norm(1 - np.maximum(a, b)) # pyramids + +def scales(u, v): + n = 8 + h = np.zeros_like(u) + # rows of circles, each row offset by half a scale and drawn over the row below + for row in range(-1, 2 * n + 1): + cy = row / (2 * n); ox = 0.5 if row % 2 else 0.0 + x = (u * n + ox) % 1 - 0.5; y = v - cy + y -= np.round(y) + r = np.sqrt((x / 1.0) ** 2 + (y * n) ** 2) + inside = r < 0.5 + dome = np.sqrt(np.clip(0.25 - r * r, 0, None)) * 2 # spherical cap + ramp = 0.4 + 0.6 * np.clip((0.5 * n * -y) / 0.5 + 0.5, 0, 1) # thicker at the exposed edge + cand = np.where(inside, 0.35 + 0.65 * dome * ramp, 0) + h = np.where(inside & (y * n <= 0.02), cand, h) + return norm(h) + +def herringbone(u, v): + # 2:1 bricks in the domino herringbone, turned 45 degrees. In cell coordinates (x, y) the brick a + # cell belongs to follows from (i - j) mod 4: 0/1 pair horizontally, 2/3 pair vertically. An even + # cell count per tile edge keeps that rule periodic. + n = 4 + x = (u + v) * n; y = (u - v) * n + i = np.floor(x); j = np.floor(y); fx = x - i; fy = y - j + k = ((i - j) % 4 + 4) % 4 + bx = np.where(k == 0, fx / 2, np.where(k == 1, 0.5 + fx / 2, fx)) + by = np.where(k == 2, 0.5 + fy / 2, np.where(k == 3, fy / 2, fy)) + # local coordinates on a 2x1 brick: the long axis is x for k in {0,1}, y for k in {2,3} + long_ = np.where(k < 2, bx, by); short = np.where(k < 2, by, bx) + gap_l = 0.03; gap_s = 0.06 + m = smoothstep(0, gap_l, long_) * smoothstep(0, gap_l, 1 - long_) * smoothstep(0, gap_s, short) * smoothstep(0, gap_s, 1 - short) + return norm(0.85 * m + 0.15 * m * fbm(u, v, 16, 5)) + +def cobblestone(u, v): + pts = wrapped_points(6, 21, 0.55) + d1, d2, idx = voronoi(u, v, pts) + edge = d2 - d1 + rng = np.random.default_rng(22); tops = rng.random(len(pts)) * 0.25 + 0.75 + h = smoothstep(0.0, 0.05, edge) * (0.55 + 0.45 * np.sqrt(np.clip(1 - (d1 / 0.11) ** 2, 0, None))) + h *= tops[idx] + h += 0.08 * fbm(u, v, 48, 23) + return norm(h) + +def leather(u, v): + pts = wrapped_points(22, 31, 0.9) + d1, d2, idx = voronoi(u, v, pts) + grooves = 1 - smoothstep(0.0, 0.012, d2 - d1) + h = 1 - 0.55 * grooves - 0.25 * fbm(u, v, 12, 33) - 0.1 * fbm(u, v, 96, 34) + return norm(h) + +def carbon_fibre(u, v): + n = 8 + x = u * n; y = v * n + cx = np.floor(x); cy = np.floor(y) + over = ((cx + cy) % 4) < 2 # 2x2 twill + fx = x % 1; fy = y % 1 + warp = 1 - 0.5 * (2 * np.abs(fx - 0.5)) ** 2 + 0.06 * np.sin(fy * 2 * np.pi * 14) + weft = 1 - 0.5 * (2 * np.abs(fy - 0.5)) ** 2 + 0.06 * np.sin(fx * 2 * np.pi * 14) + h = np.where(over, warp, weft * 0.92) + return norm(h) + +def chevron(u, v): + n = 6 + h = tri_wave(v * n * 2 + tri_wave(u * n) * 1.0) + return norm(1 - smoothstep(0.35, 0.65, h)) + +def ripples(u, v): + # Rings spreading from a few points on the torus, fading with distance - rain on water. + pts = wrapped_points(3, 81, 1.0) + h = np.zeros_like(u) + rng = np.random.default_rng(82) + for (px, py), f, ph in zip(pts, rng.random(len(pts)) * 6 + 10, rng.random(len(pts)) * 6.28): + dx = u - px; dx -= np.round(dx); dy = v - py; dy -= np.round(dy) + r = np.sqrt(dx * dx + dy * dy) + h += np.exp(-r / 0.22) * np.cos(2 * np.pi * r * f + ph) + return norm(h) + +def hammered(u, v): + pts = wrapped_points(9, 41, 0.8) + d1, d2, idx = voronoi(u, v, pts) + rng = np.random.default_rng(42); rad = rng.random(len(pts)) * 0.04 + 0.07 + dent = np.clip(1 - (d1 / rad[idx]) ** 2, 0, None) + return norm(1 - 0.8 * dent + 0.05 * fbm(u, v, 64, 43)) + +def perforated(u, v): + n = 8 + x = (u * n) % 1 - 0.5; y = (v * n) % 1 - 0.5 + r = np.sqrt(x * x + y * y) + return norm(smoothstep(0.30, 0.34, r)) + +def rope(u, v): + n = 6 # ropes per tile, running along v + x = (u * n) % 1 - 0.5 + body = np.sqrt(np.clip(0.25 - x * x, 0, None)) * 2 + twist = 0.5 + 0.5 * np.sin(2 * np.pi * (v * 12 + x * 1.6)) + return norm(body * (0.65 + 0.35 * twist)) + +def stone_wall(u, v): + rows = 5 + y = v * rows; row = np.floor(y); fy = y % 1 + rng = np.random.default_rng(51) + h = np.zeros_like(u) + for r in range(rows): + # stones of varying width along the row, periodic in u + widths = rng.random(6) * 0.6 + 0.7; widths *= 1.0 / widths.sum() + edges = np.concatenate([[0], np.cumsum(widths)]) + rng.random() * 0.3 + xu = (u + 0.0) % 1 + in_row = row == r + for i in range(len(widths)): + a = edges[i] % 1; w = widths[i] + dx = (xu - a) % 1 + inside = dx < w + gap = 0.035 + m = smoothstep(0, gap, dx) * smoothstep(0, gap, w - dx) * smoothstep(0, 0.12, fy) * smoothstep(0, 0.12, 1 - fy) + top = 0.7 + 0.3 * rng.random() + h = np.where(in_row & inside, m * top, h) + h = h * (0.85 + 0.15 * fbm(u, v, 24, 52)) + 0.04 * fbm(u, v, 96, 53) + return norm(h) + +def weathered_bricks(u, v): + # Running bond with some play in it: every row has its own offset and brick lengths, the bricks have + # rounded corners and chipped bevelled edges, a slight tilt each, and a mottled, pitted face over a + # gritty recessed mortar. + rows, per_row = 10, 4 + rng = np.random.default_rng(181) + y = v * rows; row = np.floor(y).astype(int) % rows; fy = y - np.floor(y) + offs = (np.arange(rows) % 2) * 0.5 / per_row + (rng.random(rows) - 0.5) * 0.35 / per_row + lens = rng.random((rows, per_row)) * 0.3 + 0.85 + edges = np.concatenate([np.zeros((rows, 1)), np.cumsum(lens / lens.sum(1, keepdims=True), 1)], 1) + x = (u - offs[row]) % 1 + k = np.zeros_like(row) + for i in range(1, per_row): + k += x >= edges[row, i] + a = edges[row, k]; b = edges[row, k + 1] + # rounded-rectangle distance, in tile units so the corners stay round, negative inside the brick + g, rad = 0.006, 0.012 + px = np.abs(x - (a + b) / 2) - ((b - a) / 2 - g - rad) + py = np.abs((fy - 0.5) / rows) - (0.5 / rows - g - rad) + d = np.hypot(np.maximum(px, 0), np.maximum(py, 0)) + np.minimum(np.maximum(px, py), 0) - rad + # ragged edges plus the odd bite out of an arris + d += 0.005 * (fbm(u, v, 40, 182, octaves=3) - 0.5) + 0.006 * smoothstep(0.66, 0.78, fbm(u, v, 24, 183, octaves=3)) + t = np.clip(-d / 0.014, 0, 1) + shoulder = np.sqrt(1 - (1 - t) ** 2) # rounded bevel + bid = row * per_row + k + per = rng.random((rows * per_row, 5)) + # each brick sits at its own height and leans a little + face = 0.82 + 0.1 * per[bid, 0] + 0.04 * ((per[bid, 1] - 0.5) * (x - (a + b) / 2) / ((b - a) / 2) + + (per[bid, 2] - 0.5) * (fy - 0.5) * 2) + # mottled face: domain-warped noise shifted per brick so neighbours don't share a pattern + su = (u + per[bid, 3]) % 1; sv = (v + per[bid, 4]) % 1 + wu = su + 0.08 * fbm(u, v, 6, 184, octaves=3); wv = sv + 0.08 * fbm(u, v, 6, 185, octaves=3) + mottle = smoothstep(0.3, 0.7, fbm(wu, wv, 6, 186, octaves=5, gain=0.55)) + # shallow pits that deepen gradually from the rim; the warp keeps their outlines off the noise lattice + pn = fbm(wu + 0.02 * fbm(u, v, 32, 190, octaves=2), wv, 48, 187, octaves=3) + pits = smoothstep(0.62, 0.82, pn) ** 2 * smoothstep(0.8, 0.86, fbm(u, v, 8, 188, octaves=2)) + face += 0.3 * (mottle - 0.5) - 0.16 * pits + mortar = 0.06 + 0.06 * fbm(u, v, 64, 189, octaves=3) + return norm(mortar + (face - mortar) * shoulder) + +# ---- colour textures: (rgb in 0..1, height = luminance by construction) +def lum(rgb): + return 0.299 * rgb[..., 0] + 0.587 * rgb[..., 1] + 0.114 * rgb[..., 2] + +def colour_bricks(u, v): + n = 6 + y = v * n; row = np.floor(y); x = u * n * 2 + 0.5 * (row % 2) + bx = x % 1; by = y % 1 + gap = 0.07 + m = smoothstep(0, gap, bx) * smoothstep(0, gap, 1 - bx) * smoothstep(0, gap * 2, by) * smoothstep(0, gap * 2, 1 - by) + rng = np.random.default_rng(61) + cell = (np.floor(x).astype(int) * 7 + row.astype(int) * 13) % 97 + tone = rng.random(97)[cell] + # brick reds of varying warmth over a dark grey mortar + brick = np.stack([0.70 + 0.2 * tone, 0.30 + 0.12 * tone, 0.22 + 0.06 * tone], -1) + brick *= (0.85 + 0.15 * fbm(u, v, 48, 62))[..., None] + mortar = np.array([0.30, 0.29, 0.27]) + rgb = brick * m[..., None] + mortar * (1 - m[..., None]) + return rgb + +def mosaic(u, v): + n = 8 + x = (u * n) % 1; y = (v * n) % 1 + gap = 0.08 + m = smoothstep(0, gap, x) * smoothstep(0, gap, 1 - x) * smoothstep(0, gap, y) * smoothstep(0, gap, 1 - y) + rng = np.random.default_rng(71) + cell = (np.floor(u * n).astype(int) * 31 + np.floor(v * n).astype(int) * 17) % 64 + pal = np.array([[0.90, 0.85, 0.70], [0.20, 0.45, 0.75], [0.85, 0.35, 0.25], [0.35, 0.65, 0.40]]) + tile = pal[rng.integers(0, 4, 64)[cell]] + grout = np.array([0.18, 0.18, 0.18]) + return tile * m[..., None] + grout * (1 - m[..., None]) + +def hex_tiles(u, v): + d, cid = hex_cells(u, v, 7) + m = smoothstep(1.0, 0.9, d) + pal = np.array([[0.95, 0.93, 0.88], [0.25, 0.55, 0.60], [0.80, 0.55, 0.20]]) + rng = np.random.default_rng(91) + tile = pal[rng.integers(0, 3, 1009)[cid]] + grout = np.array([0.15, 0.15, 0.16]) + return tile * m[..., None] + grout * (1 - m[..., None]) + + +def wood_planks(u, v): + n = 4 # planks across, running along v; staggered ends + x = u * n; col = np.floor(x); fx = x - col + rng = np.random.default_rng(101) + y = v * 2 + rng.random(n)[col.astype(int) % n] # each plank column has its own end offset + fy = y % 1 + gap = 0.04 + m = smoothstep(0, gap, fx) * smoothstep(0, gap, 1 - fx) * smoothstep(0, gap * 1.5, fy) * smoothstep(0, gap * 1.5, 1 - fy) + # grain: stretched noise along the plank, per plank phase + grain = fbm((u * 1.0 + rng.random(n)[col.astype(int) % n]) % 1, v, 6, 102, octaves=5) + rings = 0.5 + 0.5 * np.sin(2 * np.pi * (fx * 3 + grain * 2.5)) + return norm(m * (0.75 + 0.25 * rings)) + +def basket_weave(u, v): + n = 4 + x = u * n; y = v * n + cx = np.floor(x); cy = np.floor(y); fx = x % 1; fy = y % 1 + horiz = (cx + cy) % 2 == 0 + strips = 3 # strips per cell + along = np.where(horiz, fx, fy); across = np.where(horiz, fy, fx) + strip = (across * strips) % 1 + body = np.sqrt(np.clip(1 - (2 * strip - 1) ** 2, 0, None)) # rounded strip + ends = smoothstep(0, 0.06, along) * smoothstep(0, 0.06, 1 - along) + return norm(0.35 + 0.65 * body * ends) + +def chainmail(u, v): + n = 6 + h = np.zeros_like(u) + for ox, oy in ((0.0, 0.0), (0.5, 0.5)): + x = (u * n + ox) % 1 - 0.5; y = (v * n + oy) % 1 - 0.5 + r = np.sqrt(x * x + y * y) + ring = np.exp(-((r - 0.36) / 0.09) ** 2) + h = np.maximum(h, ring) + return norm(h) + +def pyramids(u, v): + n = 8 + x = np.abs((u * n) % 1 - 0.5); y = np.abs((v * n) % 1 - 0.5) + return norm(0.5 - np.maximum(x, y)) + +def waffle(u, v): + n = 6 + x = (u * n) % 1; y = (v * n) % 1 + gap = 0.12 + m = smoothstep(0, gap, x) * smoothstep(0, gap, 1 - x) * smoothstep(0, gap, y) * smoothstep(0, gap, 1 - y) + return norm(m) + +def bubbles(u, v): + rng = np.random.default_rng(111) + h = np.zeros_like(u) + for (px, py), r in zip(wrapped_points(7, 112, 0.9), rng.random(49) * 0.05 + 0.03): + dx = u - px; dx -= np.round(dx); dy = v - py; dy -= np.round(dy) + d2 = dx * dx + dy * dy + h = np.maximum(h, np.sqrt(np.clip(r * r - d2, 0, None)) / 0.08) + return norm(h) + +def cracked_earth(u, v): + pts = wrapped_points(7, 121, 0.7) + d1, d2, idx = voronoi(u, v, pts) + crack = 1 - smoothstep(0.0, 0.03, d2 - d1) + plates = 0.8 + 0.2 * fbm(u, v, 24, 122) + curl = 1 - 0.35 * np.clip(1 - d1 / 0.12, 0, 1) # plates curl up at the edges + return norm(plates * (2 - curl) * (1 - 0.9 * crack)) + +def sand_ripples(u, v): + n = 8 + wob = 0.06 * np.sin(2 * np.pi * u * 2) + 0.03 * fbm(u, v, 4, 131) + h = 0.5 + 0.5 * np.sin(2 * np.pi * (v * n + wob)) + h = h ** 1.6 # sharp crests, soft troughs + return norm(h + 0.05 * fbm(u, v, 64, 132)) + +def bark(u, v): + grooves = fbm((u * 3) % 1, v, 4, 141, octaves=4) # the ridges below stretch it along v + ridges = np.abs(np.sin(2 * np.pi * (u * 9 + grooves * 1.5))) + return norm(ridges ** 0.7 * (0.7 + 0.3 * fbm(u, v, 12, 142)) + 0.1 * fbm(u, v, 48, 143)) + +def slate(u, v): + h = fbm(u, v, 3, 151, octaves=6, gain=0.55) + steps = np.floor(h * 6) / 6 + 0.4 * (h * 6 - np.floor(h * 6)) / 6 # cleaved layers + return norm(steps + 0.05 * fbm(u, v, 48, 152)) + +def triangles(u, v): + n = 6 + x = u * n; y = v * n * np.sqrt(3) / 1.5 # rows of equilateral triangles + row = np.floor(y); fy = y - row + xs = x + 0.5 * (row % 2) + fx = xs % 1 + up = fx < 1 - fy # which triangle of the rhombus + # distance to the nearest edge of the triangle, in either orientation + d_up = np.minimum(np.minimum(fy, fx - 0 * fy), (1 - fy - fx)) + d_dn = np.minimum(np.minimum(1 - fy, 1 - fx), (fx + fy - 1)) + d = np.where(up, d_up, d_dn) + return norm(smoothstep(0.0, 0.08, d)) + +def roof_tiles(u, v): + n = 6 + h = np.zeros_like(u) + for row in range(-1, 2 * n + 1): + cy = row / (2 * n); ox = 0.5 if row % 2 else 0.0 + x = (u * n + ox) % 1 - 0.5; y = v - cy; y -= np.round(y) + yy = y * n * 2 # 0 at the row's exposed edge, rising toward the covered end + inside = (yy >= -0.05) & (yy < 1.0) + arch = np.cos(x * np.pi) * 0.6 + 0.4 + cand = np.where(inside, 0.3 + 0.7 * arch * (1 - 0.35 * yy), 0) + h = np.where(inside & (cand > 0), cand, h) + return norm(h) + +def star_tiles(u, v): + # 8-point stars and crosses (the classic Islamic star-and-cross tiling) + n = 4 + x = (u * n) % 1 - 0.5; y = (v * n) % 1 - 0.5 + a = np.abs(x); b = np.abs(y) + star = np.maximum(np.maximum(a, b), (a + b) / np.sqrt(2) * 1.15) + m = smoothstep(0.42, 0.36, star) + # the crosses between the stars sit on the half-offset lattice + x2 = (u * n + 0.5) % 1 - 0.5; y2 = (v * n + 0.5) % 1 - 0.5 + a2 = np.abs(x2); b2 = np.abs(y2) + cross = np.minimum(np.maximum(a2 / 0.12, b2 / 0.30), np.maximum(a2 / 0.30, b2 / 0.12)) + m2 = smoothstep(1.0, 0.85, cross) * 0.8 + return norm(np.maximum(m, m2)) + +def terrazzo(u, v): + base = np.array([0.82, 0.80, 0.76]) + rgb = np.broadcast_to(base, u.shape + (3,)).copy() * (0.95 + 0.05 * fbm(u, v, 32, 161))[..., None] + rng = np.random.default_rng(162) + pal = np.array([[0.85, 0.30, 0.25], [0.20, 0.35, 0.55], [0.25, 0.25, 0.25], [0.95, 0.90, 0.80], [0.80, 0.60, 0.20]]) + for (px, py), r, c, ang in zip(wrapped_points(12, 163, 1.0), rng.random(144) * 0.02 + 0.012, rng.integers(0, 5, 144), rng.random(144) * 3.14): + dx = u - px; dx -= np.round(dx); dy = v - py; dy -= np.round(dy) + ca, sa = np.cos(ang), np.sin(ang) + ex = (dx * ca - dy * sa) / (r * 1.4); ey = (dx * sa + dy * ca) / r + inside = (np.abs(ex) + np.abs(ey) * 0.7 + np.maximum(np.abs(ex), np.abs(ey)) * 0.5) < 1.0 + rgb[inside] = pal[c] * 0.92 # chips sit a touch below the matrix: darker = lower + return rgb + +def camouflage(u, v): + pal = np.array([[0.36, 0.42, 0.24], [0.55, 0.50, 0.32], [0.22, 0.26, 0.17], [0.60, 0.58, 0.45]]) + a = fbm(u, v, 3, 171, octaves=4); b = fbm(u, v, 3, 172, octaves=4); c = fbm(u, v, 5, 173, octaves=3) + idx = (a > 0.55).astype(int) + 2 * (b > 0.5).astype(int) + idx = np.where(c > 0.72, 3, idx) + rgb = pal[idx].astype(float) + return rgb * (0.94 + 0.06 * fbm(u, v, 48, 174))[..., None] + +def tartan(u, v): + n = 2 + def stripes(t): + t = (t * n) % 1 + band = np.zeros_like(t) + for a, w, val in ((0.0, 0.32, 1), (0.32, 0.06, 2), (0.38, 0.24, 0), (0.62, 0.06, 2), (0.68, 0.32, 1)): + band = np.where((t >= a) & (t < a + w), val, band) + return band + pal = np.array([[0.12, 0.25, 0.20], [0.55, 0.12, 0.14], [0.90, 0.80, 0.30]]) + su = stripes(u).astype(int); sv = stripes(v).astype(int) + weave = ((np.floor(u * 400) + np.floor(v * 400)) % 2) == 0 # the two thread directions alternate + rgb = np.where(weave[..., None], pal[su], pal[sv]).astype(float) + return rgb * (0.9 + 0.1 * (0.5 + 0.5 * np.sin(2 * np.pi * (u + v) * 200)))[..., None] + +GREY = { + 'Diamond Plate': diamond_plate, 'Honeycomb': honeycomb, 'Fine Knurl': knurl, 'Scales': scales, + 'Herringbone': herringbone, 'Cobblestone': cobblestone, 'Leather': leather, 'Carbon Fibre': carbon_fibre, + 'Chevron': chevron, 'Ripples': ripples, 'Hammered': hammered, 'Perforated': perforated, 'Rope': rope, + 'Stone Wall': stone_wall, 'Wood Planks': wood_planks, 'Basket Weave': basket_weave, 'Chainmail': chainmail, + 'Pyramids': pyramids, 'Waffle': waffle, 'Bubbles': bubbles, 'Cracked Earth': cracked_earth, + 'Sand Ripples': sand_ripples, 'Bark': bark, 'Slate': slate, 'Triangles': triangles, 'Roof Tiles': roof_tiles, + 'Star Tiles': star_tiles, 'Bricks weathered': weathered_bricks, +} +COLOUR = {'Colour Bricks': colour_bricks, 'Mosaic Tiles': mosaic, 'Hex Tiles': hex_tiles, 'Terrazzo': terrazzo, + 'Camouflage': camouflage, 'Tartan': tartan} + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('--size', type=int, default=1024) + ap.add_argument('--out', default='resources/textures/displacement') + ap.add_argument('--sheet', default='') + args = ap.parse_args() + os.makedirs(args.out, exist_ok=True) + u, v = grid(args.size) + thumbs = [] + for name, fn in GREY.items(): + img = (np.clip(down(fn(u, v)), 0, 1) * 255 + 0.5).astype(np.uint8) + Image.fromarray(img, 'L').save(os.path.join(args.out, name + '.png'), optimize=True) + thumbs.append((name, np.stack([img] * 3, -1))) + print('wrote', name) + for name, fn in COLOUR.items(): + rgb = fn(u, v) + rgb = np.stack([down(rgb[..., c]) for c in range(3)], -1) + img = (np.clip(rgb, 0, 1) * 255 + 0.5).astype(np.uint8) + Image.fromarray(img, 'RGB').save(os.path.join(args.out, name + '.png'), optimize=True) + thumbs.append((name, img)) + print('wrote', name, '(colour)') + if args.sheet: + t = 256; cols = 7; rows = (len(thumbs) + cols - 1) // cols + sheet = Image.new('RGB', (cols * t, rows * t), (40, 40, 40)) + for i, (name, img) in enumerate(thumbs): + im = Image.fromarray(img).resize((t, t), Image.LANCZOS) + sheet.paste(im, ((i % cols) * t, (i // cols) * t)) + sheet.save(args.sheet); print('sheet', args.sheet) + +if __name__ == '__main__': + main() diff --git a/scripts/orca_profile_tool.py b/scripts/orca_profile_tool.py index 29863f8d1a..f7f622c8c0 100755 --- a/scripts/orca_profile_tool.py +++ b/scripts/orca_profile_tool.py @@ -6,6 +6,7 @@ usage: python scripts/orca_profile_tool.py [options] commands: check validate the whole tree -- what CI runs + fix-variant resize the variant arrays check rejects generate-id write the filament_id / setting_id each profile's identity implies normalize rewrite profile files into their canonical shape trim delete profile files no .json list references @@ -89,6 +90,7 @@ parent in the OFL map. filament_vendor / filament_type resolve the same way. """ import argparse +import functools import json import os import posixpath @@ -179,6 +181,99 @@ VECTOR_KEYS = { "filament_type", } +PRINT_CONFIG_CPP = os.path.normpath( + os.path.join(SCRIPTS_DIR, "..", "src", "libslic3r", "PrintConfig.cpp")) + + +@functools.lru_cache(maxsize=None) +def _variant_scheme(): + """Per config preset type: the key listing the preset's own variants, and the + stride of every key sized by it. + + Read from the four variant key sets in PrintConfig.cpp, the std::set + initializers DynamicPrintConfig::get_parameter_size sizes by, so membership is + the engine's own and not guessable from names. Each holds one value per variant; + printer_options_with_variant_2, the machine_max_* limits, holds a (normal, + silent) pair per variant, stride 2. + """ + with open(PRINT_CONFIG_CPP, encoding="utf-8") as f: + source = f.read() + + def members(name): + match = re.search(r"std::set\s+" + name + r"\s*=\s*\{(.*?)\};", + source, re.DOTALL) + if match is None: + raise RuntimeError(f"{PRINT_CONFIG_CPP} no longer defines {name}") + # An initializer can carry a commented-out entry (filament_extruder_id). + body = re.sub(r"//[^\n]*|/\*.*?\*/", "", match.group(1), flags=re.DOTALL) + return sorted(set(re.findall(r'"([^"\n]+)"', body))) + + return { + "machine": ("printer_extruder_variant", { + **dict.fromkeys(members("printer_options_with_variant_1"), 1), + **dict.fromkeys(members("printer_options_with_variant_2"), 2)}), + "process": ("print_extruder_variant", + dict.fromkeys(members("print_options_with_variant"), 1)), + "filament": ("filament_extruder_variant", + dict.fromkeys(members("filament_options_with_variant"), 1)), + } + + +@functools.lru_cache(maxsize=None) +def _variant_names(): + """The parts a variant string is built from, read from PrintConfig.cpp. + + A variant is selected by exact string compare of " ", so what is legal is the two enum maps the engine builds that string from, + not the list of strings some profile happens to ship. Returns (extruder types, + writable volume types, variant-name rewrites, extruder_type rewrites): the volume + types minus RUNTIME_VOLUME_TYPES, and the spellings PrintConfigDef::handle_legacy + rewrites in the six variant keys. The loader still accepts such a spelling, but a + profile must write the enum name, so the rewrite only names that name in the error; + it is read rather than restated because it belongs to the engine too. + """ + with open(PRINT_CONFIG_CPP, encoding="utf-8") as f: + source = f.read() + + def enum_map(name): + match = re.search(r"t_config_enum_values\s+" + name + r"\s*=\s*\{(.*?)\};", + source, re.DOTALL) + if match is None: + raise RuntimeError(f"{PRINT_CONFIG_CPP} no longer defines {name}") + body = re.sub(r"//[^\n]*|/\*.*?\*/", "", match.group(1), flags=re.DOTALL) + return set(re.findall(r'"([^"\n]+)"', body)) + + def rewrites(anchor): + """The (old, new) ReplaceString pairs of handle_legacy's branch for one key. + + An absent branch means the loader rewrites nothing, which is a defined answer + rather than a broken parse: every legacy name is then reported as unknown. + """ + match = re.search(r'opt_key == "' + anchor + r'"\s*\)\s*\{(.*?)\}', + source, re.DOTALL) + return ({} if match is None else + dict(re.findall(r'ReplaceString\(value,\s*"([^"]+)",\s*"([^"]+)"\)', + match.group(1)))) + + return (enum_map("s_keys_map_ExtruderType"), + enum_map("s_keys_map_NozzleVolumeType") - RUNTIME_VOLUME_TYPES, + rewrites("extruder_variant_list"), + rewrites("extruder_type")) + + +# What a preset that writes no variant layout takes: the default extruder_type and +# nozzle volume type (PrintConfig.cpp defaults for extruder_type and +# default_nozzle_volume_type), one such variant per extruder on a machine +# (extend_extruder_variant) and a single one on a process or filament. +DEFAULT_EXTRUDER_TYPE = "Direct Drive" +DEFAULT_NOZZLE_VOLUME_TYPE = "Standard" +DEFAULT_VARIANT = f"{DEFAULT_EXTRUDER_TYPE} {DEFAULT_NOZZLE_VOLUME_TYPE}" + +# A nozzle volume type the engine computes for a hybrid extruder at runtime, and no +# profile ever writes: s_keys_map_NozzleVolumeType carries it for the several +# sub-nozzles of one extruder, which no single variant string can name. +RUNTIME_VOLUME_TYPES = {"Hybrid"} + OF_ID_RE = re.compile(r"^OF[0-9A-Za-z]{6}$") # Filament name = preset base name: strip the first "@..." suffix. The space before # "@" is optional because names like "Afinia PLA@HS" exist. @@ -1248,6 +1343,482 @@ def check_vector_type_keys(profiles_dir, vendor): return error_count +@functools.lru_cache(maxsize=None) +def load_vendor_configs(profiles_dir, vendor): + """name -> (tree-relative file, data) per config preset type, from the bundle's + index lists - the per-kind maps the loader resolves inherits and include in. + + Cached because every vendor's filaments may reach OrcaFilamentLibrary. Unreadable + files are check_name_consistency's to report; when two indexed files claim one + name the first wins, as std::map::emplace keeps the first insertion. + """ + configs = {sub: {} for sub in PROFILE_SUBDIRS} + try: + index = load_json(os.path.join(str(profiles_dir), vendor + ".json")) + except (OSError, ValueError): + return configs + for section in PROFILE_TYPES: + for entry in index.get(section + "_list", []): + sub_path = entry.get("sub_path", "") + try: + data = load_json(os.path.join(str(profiles_dir), vendor, sub_path)) + except (OSError, ValueError): + continue + if isinstance(data, dict) and data.get("type") in configs and data.get("name"): + configs[data["type"]].setdefault(data["name"], (f"{vendor}/{sub_path}", data)) + return configs + + +def compose_config(name, presets, ofl_presets, cache, in_ofl=False, seen=frozenset()): + """A preset's config as the loader composes it: the parent's composed config, + then each `include` in the order listed, then its own keys - later layers win. + + Each key maps to (value, path): the value as the winning file wrote it, width + included, and the tree-relative files it passes through on the way to this + preset, from that file down to this one. `inherits` resolves in the bundle + first, then in OrcaFilamentLibrary (filaments only) and stays there once it + enters; `include` never leaves the includer's bundle. A name that resolves to + nothing, or a cycle, contributes nothing - the loader's own error paths leave + the preset without it too. + """ + if (in_ofl, name) in cache: + return cache[(in_ofl, name)] + bundle = ofl_presets if in_ofl else presets + if name not in bundle and not in_ofl and name in ofl_presets: + bundle, in_ofl = ofl_presets, True + if name not in bundle or name in seen: + return {} + seen = seen | {name} + rel, data = bundle[name] + config = {} + if data.get("inherits"): + config.update( + compose_config(data["inherits"], presets, ofl_presets, cache, in_ofl, seen)) + include = data.get("include") or [] + for included in ([include] if isinstance(include, str) else include): + if included in bundle: + config.update(compose_config(included, presets, ofl_presets, cache, in_ofl, seen)) + config = {key: (value, path + (rel,)) for key, (value, path) in config.items()} + config.update((key, (value, (rel,))) for key, value in data.items()) + cache[(in_ofl, name)] = config + return config + + +def _as_list(value): + return value if isinstance(value, list) else [value] + + +def _per_extruder(values, i): + """Entry i of a per-extruder vector, padded the way the loader pads: by its first value.""" + return values[i] if i < len(values) else values[0] + + +def _check_printer_layout(rel, config): + """A machine's extruder_variant_list, printer_extruder_variant, printer_extruder_id, + extruder_type and default_nozzle_volume_type agree with each other, the loader's + defaults standing in for whatever the composed config leaves out. + + A machine that writes none of the three list keys takes one default variant + "Direct Drive Standard" per extruder, so there is nothing to check. Otherwise + printer_extruder_variant is extruder_variant_list flattened extruder-major and + printer_extruder_id gives each of its entries its 1-based extruder (extruder 1 + everywhere when absent); every variant starts with its extruder's extruder_type + ("Direct Drive" when absent); the default_nozzle_volume_type ("Standard" when + absent) is one the extruder lists. A list without the pair leaves the loader on + the default single variant; a pair without the list gives the sidebar no variant + switch, and with single_extruder_multi_material off the loader replaces it with + one default variant per extruder. Returns (errors, warnings). + """ + menu = config.get("extruder_variant_list") + variant = config.get("printer_extruder_variant") + if menu is None and variant is None: + return 0, 0 + errors = warnings = 0 + extruders = len(_as_list(config.get("nozzle_diameter", [""]))) + types = _as_list(config.get("extruder_type", [DEFAULT_EXTRUDER_TYPE])) + volume_types = _as_list(config.get("default_nozzle_volume_type", [DEFAULT_NOZZLE_VOLUME_TYPE])) + semm_off = str(_as_list(config.get("single_extruder_multi_material", ["1"]))[0]) \ + .lower() in ("0", "false") + flat, ids = [], [] + if menu is not None: + menu = _as_list(menu) + if len(menu) != extruders: + print_error(f"{rel}: extruder_variant_list has {len(menu)} entries for {extruders} " + f"extruder(s) (nozzle_diameter); it holds one entry per extruder") + errors += 1 + for i, entry in enumerate(menu): + variants = entry.split(",") + flat += variants + ids += [str(i + 1)] * len(variants) + extruder_type = _per_extruder(types, i) + if not all(v.startswith(extruder_type + " ") for v in variants): + print_error(f'{rel}: extruder_variant_list entry {i + 1} "{entry}" holds a ' + f"variant that does not start with extruder {i + 1}'s " + f'extruder_type "{extruder_type}"') + errors += 1 + if f"{extruder_type} {_per_extruder(volume_types, i)}" not in variants: + print_error(f'{rel}: default_nozzle_volume_type "{_per_extruder(volume_types, i)}" is ' + f'not a nozzle volume type extruder {i + 1} lists ("{entry}")') + errors += 1 + if variant is not None: + variant = _as_list(variant) + written_ids = config.get("printer_extruder_id") + pair_ids = ["1"] * len(variant) if written_ids is None else _as_list(written_ids) + if len(pair_ids) != len(variant): + print_error(f"{rel}: printer_extruder_id has {len(pair_ids)} entries for the " + f"{len(variant)} entries of printer_extruder_variant") + errors += 1 + if menu is not None and variant is not None: + if variant != flat: + print_error(f"{rel}: printer_extruder_variant {json.dumps(variant)} is not " + f"extruder_variant_list flattened extruder-major {json.dumps(flat)}") + errors += 1 + elif pair_ids != ids: + print_error(f"{rel}: printer_extruder_id {json.dumps(pair_ids)}" + f"{' (absent, so extruder 1 everywhere)' if written_ids is None else ''} " + f"does not give each entry of printer_extruder_variant its 1-based " + f"extruder {json.dumps(ids)}") + errors += 1 + elif menu is not None: + if len(flat) > 1: + print_error(f"{rel}: extruder_variant_list offers {len(flat)} variants but the " + f"preset writes no printer_extruder_variant/printer_extruder_id, so the " + f'loader sizes every variant array to the single default variant ' + f'"{DEFAULT_VARIANT}" and no other variant has a value; write the pair') + errors += 1 + else: + crowded = [i for i in dict.fromkeys(pair_ids) if pair_ids.count(i) > 1] + if crowded: + print_error(f"{rel}: printer_extruder_variant lists several variants for extruder " + f"{crowded[0]} but the preset writes no extruder_variant_list, so the " + f"sidebar offers no variant switch and the extra variants are unreachable") + errors += 1 + elif semm_off and variant != [DEFAULT_VARIANT] * extruders: + print_warning(f"{rel}: with single_extruder_multi_material off the loader replaces " + f"printer_extruder_variant {json.dumps(variant)} by one " + f'"{DEFAULT_VARIANT}" per extruder, because extruder_variant_list is ' + f"absent; write the list or drop the pair") + warnings += 1 + return errors, warnings + + +def _variant_length(ptype, config): + """(variant length, reason) of a config as compose_config gives it, after + inherits and include. + + The variant length is the length of the preset's *_extruder_variant list. A + machine without one has the variants its extruder_variant_list offers, and + without that list one default "Direct Drive Standard" variant per extruder + (len(nozzle_diameter)) - the list's default in extend_extruder_variant. A process + or filament without its list has the single default variant. The reason says + which of these gave the length, and is empty when the list is written. + """ + list_key = _variant_scheme()[ptype][0] + if list_key in config: + return len(_as_list(config[list_key][0])), "" + if ptype != "machine": + return 1, f"no {list_key}, so the single default variant" + if "extruder_variant_list" in config: + menu = _as_list(config["extruder_variant_list"][0]) + return (sum(len(entry.split(",")) for entry in menu), + f"no {list_key}, so the variants extruder_variant_list offers") + extruders = len(_as_list(config["nozzle_diameter"][0])) if "nozzle_diameter" in config else 1 + return extruders, f"no {list_key}, so one default variant per extruder" + + +def _variant_presets(profiles_dir, vendor): + """Yield (ptype, rel, data, config, variant length, reason) for every machine, + process and filament preset of the bundle, bases included: data as its file + holds it, config as compose_config gives it, and the variant length and reason + as _variant_length does. + """ + presets = load_vendor_configs(profiles_dir, vendor) + library = {} if vendor == OFL else load_vendor_configs(profiles_dir, OFL)["filament"] + for ptype in _variant_scheme(): + ofl_presets = library if ptype == "filament" else {} + cache = {} + for name, (rel, data) in sorted(presets[ptype].items(), key=lambda item: item[1][0]): + config = compose_config(name, presets[ptype], ofl_presets, cache) + yield (ptype, rel, data, config, *_variant_length(ptype, config)) + + +def indexed_sub_paths(profiles_dir, vendor): + """The sub_paths a bundle's index lists, normalized, or None with no index. + + The loader reads what .json references and nothing else, so a file no list + names never loads and its contents are not worth judging; "filament/./X.json" + names the same file as "filament/X.json". A bundle with no readable index is + check_name_consistency's to report. Returns a set of sub_paths, or None. + """ + try: + library = load_json(os.path.join(profiles_dir, vendor + ".json")) + except (ValueError, OSError): + return None + listed = set() + for section in PROFILE_TYPES: + for entry in library.get(section + "_list", []): + if entry.get("sub_path"): + listed.add(posixpath.normpath(entry["sub_path"].replace("\\", "/"))) + return listed + + +def _variant_entries(key, value): + """(where, variant string) of every entry of a variant list key, as the loader + reads it: extruder_variant_list holds one ","-joined menu per extruder, the other + three one variant per array entry.""" + if key == "extruder_variant_list": + return [(f"extruder {i}", variant) + for i, entry in enumerate(_as_list(value), 1) + for variant in str(entry).split(",")] + return [(f"entry {i}", str(variant)) + for i, variant in enumerate(_as_list(value), 1)] + + +def _check_variant_string(rel, key, where, variant): + """Report one variant string that is not " " + in the engine's enum names. Returns the error count, 0 or 1. + + Legality is the two enum maps _variant_names reads, in every bundle: a variant + outside them is dead - nothing selects it, nothing rejects it, and it still counts + toward the variant length every array is sized by, so the values tuned for it + silently never reach the G-code. A legacy name the loader rewrites in these keys + is an error too, naming the enum name to write instead. + """ + extruder_types, volume_types, legacy, _extruder_legacy = _variant_names() + + if not variant: + print_error(f"{rel}: {key} {where} is empty; every entry names one variant, " + f'" "') + return 1 + # Longest first, so an extruder type that is a prefix of another cannot win. + extruder = next((t for t in sorted(extruder_types, key=len, reverse=True) + if variant.startswith(t + " ")), None) + if extruder is None: + # "DirectDrive" is rewritten in extruder_type alone, so a variant string + # carrying it is dead. + print_error(f'{rel}: {key} {where} holds "{variant}", which no extruder can ' + f"select: it does not start with an extruder type the enum has " + f'({", ".join(sorted(extruder_types))}); a variant is ' + f'" "') + return 1 + volume = variant[len(extruder) + 1:] + if volume in volume_types: + return 0 + if volume in legacy: + print_error(f'{rel}: {key} {where} holds the legacy variant "{variant}"; the ' + f'loader still rewrites "{volume}" to "{legacy[volume]}", but a ' + f'profile writes the enum name: "{extruder} {legacy[volume]}"') + elif volume in RUNTIME_VOLUME_TYPES: + print_error(f'{rel}: {key} {where} holds "{variant}", which no extruder can ' + f"select: Hybrid names the sub-nozzles of one hybrid extruder at " + f"runtime, never a nozzle volume type a profile writes") + else: + print_error(f'{rel}: {key} {where} holds "{variant}", which no extruder can ' + f'select: "{volume}" is not a nozzle volume type the enum has ' + f'({", ".join(sorted(volume_types))}), so nothing selects the variant ' + f"and the values tuned for it never reach the G-code") + return 1 + + +def _variant_repeats(data): + """One message per variant a preset's own lists name twice. + + The lookup returns the first equal string, so a repeat is a variant nothing + selects, and the value written beside it sits at an index no extruder reads. A + process's variant is the (extruder id, variant) pair, so one string on two + extruders is two pairs rather than a repeat; with print_extruder_id absent or + short every pair reads as extruder 1, which check_variant_arrays warns about once + per preset instead. + """ + messages = [] + if "filament_extruder_variant" in data: + variants = [str(v) for v in _as_list(data["filament_extruder_variant"])] + messages += [ + f'filament_extruder_variant lists "{v}" {variants.count(v)} times; a ' + f"filament's variants are matched by exact string, so the repeat is a " + f"variant nothing selects and its value sits at an index no extruder reads" + for v in sorted({v for v in variants if variants.count(v) > 1})] + if "extruder_variant_list" in data: + for i, entry in enumerate(_as_list(data["extruder_variant_list"]), 1): + variants = str(entry).split(",") + messages += [ + f'extruder_variant_list extruder {i} lists "{v}" ' + f"{variants.count(v)} times; the sidebar offers it once, so the repeat " + f"is a variant nothing selects and the arrays hold a value no extruder " + f"reads" + for v in sorted({v for v in variants if variants.count(v) > 1})] + if "print_extruder_variant" in data and "print_extruder_id" in data: + ids = _as_list(data["print_extruder_id"]) + variants = _as_list(data["print_extruder_variant"]) + if len(ids) == len(variants): + pairs = [(str(i), str(v)) for i, v in zip(ids, variants)] + messages += [ + f'print_extruder_variant lists the pair (extruder {i}, "{v}") ' + f"{pairs.count((i, v))} times; a variant is found by that pair, so the " + f"repeat is unreachable" + for i, v in sorted({p for p in pairs if pairs.count(p) > 1})] + return messages + + +def _check_variant_seed(rel, option, value, allowed, legacy, runtime=frozenset()): + """Report the values of an enum option a variant string is composed from. + + extruder_type and the nozzle volume type (nozzle_volume_type, seeded by + default_nozzle_volume_type) are the two halves of every variant string, and all + three are enum options: an unknown value fails the validator's load of the whole + bundle, while the app silently loads the option's default instead, which is worth + naming precisely here. A legacy name the loader rewrites, and a name in `runtime` + the engine computes for itself, are errors too. Returns the error count. + """ + errors = 0 + for name in ([] if value is None else _as_list(value)): + name = str(name) + if name in allowed: + continue + if name in legacy: + print_error(f'{rel}: {option} spells the legacy name "{name}"; the loader ' + f'still rewrites it to "{legacy[name]}", but a profile writes the ' + f"enum name") + elif name in runtime: + print_error(f'{rel}: {option} names "{name}", which the engine computes ' + f"for a hybrid extruder at runtime; no profile writes it") + else: + print_error(f'{rel}: {option} "{name}" is not one of ' + f'({", ".join(sorted(allowed))}); the option is an enum, so an ' + f"unknown value fails loading the whole bundle in the validator " + f"and silently becomes the default in the app") + errors += 1 + return errors + + +def check_variant_names(profiles_dir, vendor): + """Every variant string and extruder or nozzle volume type a preset writes is an + enum name the engine has. + + check_variant_arrays judges how many values a variant key holds; this judges what + the variants are called, the other half of the same scheme. It reads the four list + keys, extruder_type, nozzle_volume_type and default_nozzle_volume_type of every + preset the bundle's index references - bases included, since a base's list is what + sizes its children's arrays - and reports as errors, in every bundle alike: + + * a variant string the two enums cannot build (dead variant), a legacy spelling + the loader still rewrites in these keys included (_check_variant_string); + * a variant list naming one variant twice: the lookup returns the first equal + string, so the repeat is unreachable. A filament list takes variant strings, a + menu takes them per extruder, and a process takes (extruder id, variant) pairs, + where one string on two extruders is two pairs, not a repeat; + * an extruder_type, nozzle_volume_type or default_nozzle_volume_type that is not + an enum name a profile writes (_check_variant_seed). + + Key/value types elsewhere are check_vector_type_keys' and the validator's; a file + no list references is skipped, check_index_coverage having reported it. Returns + the error count. + """ + extruder_types, volume_types, legacy, extruder_legacy = _variant_names() + errors = 0 + listed = indexed_sub_paths(profiles_dir, vendor) + if listed is None: + return 0 + vendor_dir = os.path.join(profiles_dir, vendor) + + for path, _sub in iter_profile_files(vendor_dir): + if os.path.basename(path) in NON_PROFILE_FILES: + continue + sub_path = posixpath.normpath( + os.path.relpath(path, vendor_dir).replace(os.sep, "/")) + if sub_path not in listed: + continue + try: + data = load_json(path) + except (ValueError, OSError): + # Parse failures are reported by the checks that walk the same files. + continue + if not isinstance(data, dict): + continue + rel = f"{vendor}/{sub_path}" + + for key in ("extruder_variant_list", "printer_extruder_variant", + "print_extruder_variant", "filament_extruder_variant"): + if key in data: + for where, variant in _variant_entries(key, data[key]): + errors += _check_variant_string(rel, key, where, variant) + + # A list naming one variant twice, and the two enum values a variant string is + # composed from. + for message in _variant_repeats(data): + print_error(f"{rel}: {message}") + errors += 1 + errors += _check_variant_seed(rel, "extruder_type", data.get("extruder_type"), + extruder_types, extruder_legacy) + for option in ("nozzle_volume_type", "default_nozzle_volume_type"): + errors += _check_variant_seed(rel, option, data.get(option), volume_types, + legacy, RUNTIME_VOLUME_TYPES) + return errors + + +def check_variant_arrays(profiles_dir, vendor, strict=False): + """Every variant array an instantiated preset writes is exactly its + variant length x stride wide, and a printer's variant layout keys agree. + + Only instantiated presets are judged, each at the variant length of its composed + config (_variant_length's); a base is not, since what it writes counts only where + it reaches a preset that does not override it. A full-width array holds one + value per variant; any other width is an error, one value included and whatever + the values. A key the preset does not write takes what reaches it - the default, + or an array it inherits or includes - which the loader sizes to the preset, and + is not checked. With strict, every instantiated preset also holds each key that + reaches it at its own width, so a preset with other variants than the file its + array comes from restates the array. The machine_max_* limits hold + a (normal, silent) pair per variant. A process that lists variants pairs each + with its extruder id (extruder 1 everywhere when absent); a machine's layout keys + are held to _check_printer_layout, which reports a printer_extruder_id that does + not fit a written printer_extruder_variant, as the process check below does for + print_extruder_id. Returns (errors, warnings). + """ + errors = warnings = 0 + for ptype, rel, data, config, variant_length, reason in _variant_presets(profiles_dir, + vendor): + if data.get("instantiation") != "true": + continue + list_key, strides = _variant_scheme()[ptype] + listed = list_key in config + for key, stride in sorted(strides.items()): + if key not in config or (listed and key in ("printer_extruder_id", + "print_extruder_id")): + continue + if key not in data and not strict: + continue + value, path = config[key] + width, need = len(_as_list(value)), variant_length * stride + if width == need: + continue + print_error(f'{rel}: "{key}" has {width} values for variant length {variant_length}' + f"{' (' + reason + ')' if reason else ''} at stride {stride}, " + f"which takes {need}" + f"{'' if key in data else ' (it comes from ' + path[0] + ')'}") + errors += 1 + config = {key: value for key, (value, _path) in config.items()} + if ptype == "machine": + new_errors, new_warnings = _check_printer_layout(rel, config) + errors += new_errors + warnings += new_warnings + elif ptype == "process" and listed: + variants = _as_list(config[list_key]) + if "print_extruder_id" in config: + ids = _as_list(config["print_extruder_id"]) + if len(ids) != variant_length: + print_error(f"{rel}: print_extruder_id has {len(ids)} entries for the " + f"{variant_length} entries of print_extruder_variant; the two " + f"list the (extruder id, variant) pairs, one per entry") + errors += 1 + elif len(set(variants)) < len(variants): + print_warning(f"{rel}: print_extruder_variant repeats a variant but " + f"print_extruder_id is absent, so every entry defaults to " + f"extruder 1 and the repeated variant is unreachable") + warnings += 1 + return errors, warnings + + def check_conflict_keys(profiles_dir, vendor): """A renamed option and its old spelling must not co-exist in one profile. @@ -1348,9 +1919,12 @@ def check_normalized(profiles_dir, vendor): # check # --------------------------------------------------------------------------- -def check_profiles(profiles_dir=PROFILES_DIR, vendors=None): +def check_profiles(profiles_dir=PROFILES_DIR, vendors=None, strict=False): """Validate the whole profile tree. Returns the error count. + strict holds every preset's inherited and included variant arrays to its + own width too (check_variant_arrays). + The per-vendor checks honour `vendors`; the setting_id and filament_id checks are cross-vendor properties a narrowed run cannot answer, so they always cover the whole tree. With no `vendors`, every bundle is checked except the `user` directory @@ -1389,6 +1963,10 @@ def check_profiles(profiles_dir=PROFILES_DIR, vendors=None): warnings_found += new_warnings errors_found += check_vector_type_keys(profiles_dir, vendor) + errors_found += check_variant_names(profiles_dir, vendor) + new_errors, new_warnings = check_variant_arrays(profiles_dir, vendor, strict) + errors_found += new_errors + warnings_found += new_warnings errors_found += check_filament_id_length(profiles_dir, vendor) new_errors, gaps = check_index_coverage(profiles_dir, vendor) @@ -1493,6 +2071,49 @@ def delete_key_line(text, key, old_value=None): return text, 0 +_JSON_WS = re.compile(r"[ \t\r\n]*") + + +def _json_members(text): + """(key, key start, value start, value end) of each member of the top-level + JSON object in text, in file order.""" + decoder = json.JSONDecoder() + members = [] + i = _JSON_WS.match(text, text.index("{") + 1).end() + while text[i] != "}": + key_start = i + key, i = decoder.raw_decode(text, i) + i = _JSON_WS.match(text, _JSON_WS.match(text, i).end() + 1).end() # past the ':' + _value, end = decoder.raw_decode(text, i) + members.append((key, key_start, i, end)) + i = _JSON_WS.match(text, end).end() + i = _JSON_WS.match(text, i + (text[i] == ",")).end() + return members + + +def set_array_value(text, key, values): + """Write values as the "key" array, byte-preserving the rest. + + An existing array keeps its one-line or one-value-per-line layout; a preset + without the key gets it as its last member, one value per line, in the file's + own indentation and line ending. Returns (text, 1). + """ + items = [json.dumps(v, ensure_ascii=False) for v in values] + members = _json_members(text) + for name, _key_start, start, end in reversed(members): # json.load keeps the last + if name == key: + m = re.fullmatch(r"\[(\r?\n)([ \t]*).*(\r?\n)([ \t]*)\]", text[start:end], re.DOTALL) + array = ("[" + ", ".join(items) + "]" if m is None else + "[" + m[1] + ("," + m[1]).join(m[2] + item for item in items) + + m[3] + m[4] + "]") + return text[:start] + array + text[end:], 1 + _name, key_start, _start, end = members[-1] + indent = text[text.rfind("\n", 0, key_start) + 1:key_start] + nl = "\r\n" if "\r\n" in text else "\n" + array = "[" + nl + ("," + nl).join(indent * 2 + item for item in items) + nl + indent + "]" + return text[:end] + "," + nl + indent + json.dumps(key) + ": " + array + text[end:], 1 + + def insert_filament_id(text, new_id): """Insert a `"filament_id"` line before `instantiation`, else after `name`.""" return insert_key_line(text, "filament_id", new_id, @@ -1908,6 +2529,21 @@ def create_ordered_profile(profile, priority_fields): # The keys that identify a preset, hoisted to the top of every rewritten file. NORMALIZE_FIELD_ORDER = ("type", "name", "renamed_from", "inherits", "from", "setting_id", "filament_id", "instantiation") + + +def identity_block_misplaced(keys): + """The identifying keys are not a correctly ordered prefix of `keys`. + + create_ordered_profile hoists them, so this is the one part of the canonical + shape a rewrite is guaranteed to change. Without asking, normalize would only + ever apply the hoist as a side effect of some other rule firing, which leaves + a file that breaks this rule reported as already normalized. + """ + present = [k for k in keys if k in NORMALIZE_FIELD_ORDER] + return (keys[:len(present)] != present + or present != [k for k in NORMALIZE_FIELD_ORDER if k in keys]) + + # Settings a filament profile must not pin: they belong to the process. FILAMENT_DROP_FIELDS = ("initial_layer_print_speed", "outer_wall_speed", "inner_wall_speed", "infill_speed", "top_surface_speed", @@ -1967,6 +2603,11 @@ def _normalize_profile(data, sub): del data[field] changes.append(f"remove {field}") + # Last, because it describes the file as written rather than its contents, and + # create_ordered_profile does the hoisting when the file is written. + if identity_block_misplaced(list(data)): + changes.append("put the identifying keys first") + return changes @@ -2304,6 +2945,128 @@ def update_profile_indexes(profiles_dir=PROFILES_DIR, vendors=None, profile_type return changed, errors +# --------------------------------------------------------------------------- +# fix-variant +# --------------------------------------------------------------------------- + +# The members of the variant sets that name the variants rather than hold values. +VARIANT_LAYOUT_KEYS = {"printer_extruder_variant", "printer_extruder_id", "print_extruder_variant", + "print_extruder_id", "filament_extruder_variant"} + + +def _fit_width(values, need, stride): + """values cut to need, or padded by repeating the last value - the last + (normal, silent) pair at stride 2, after dropping a trailing half pair; a lone + value fills every entry, normal and silent alike.""" + if len(values) > need: + return values[:need] + if len(values) == 1: + return values * need + values = values[:len(values) - len(values) % stride] + return values + values[-stride:] * ((need - len(values)) // stride) + + +def fix_variant_arrays(profiles_dir=PROFILES_DIR, vendors=None, dry_run=False, strict=False): + """Resize every variant array check_variant_arrays rejects to its + width: extra values are dropped, missing ones repeat the last. The variant lists + and extruder ids are layout, not values, and are left to check. + + An array an instantiated preset writes is resized in place, to the preset's + width; bases are left alone and no key is added. With strict, a key that then + reaches an instantiated preset at another width is written, resized, into the + most general file on the way down to the preset whose own width it fits and whose + instantiated presets taking it all need that width - a base only the presets with + a variant list inherit, say - else into the preset's own file. Presets of every bundle count towards that agreement; only + files of `vendors` are touched. Returns (files changed, errors). + """ + profiles_dir = str(profiles_dir) + names = list_vendor_names(profiles_dir) + scope = set(vendors or names) + files = {rel: data for vendor in names + for configs in load_vendor_configs(profiles_dir, vendor).values() + for rel, data in configs.values()} + verb = "would " if dry_run else "" + changed, errors = set(), 0 + + def fit(rel, key, values, need, stride): + fitted = _fit_width(values, need, stride) + if not fitted: + print_error(f'{rel}: "{key}" cannot be resized from {len(values)} to {need} values') + return fitted + + # Each preset's own arrays first, then (strict) what reaches the presets; a write + # into a preset hands its children a new source, which the next pass judges. The + # in-memory configs take each write so a dry run sees it too. + for _ in range(8): + own = {} # file -> its own variant length + users = defaultdict(list) # (file, key) -> [(value, path, need, stride)] + writes = defaultdict(dict) # file -> {key: values} + for vendor in names: + for ptype, rel, data, config, variant_length, _reason in _variant_presets( + profiles_dir, vendor): + own[rel] = variant_length + instantiated = data.get("instantiation") == "true" + for key, stride in _variant_scheme()[ptype][1].items(): + if key not in config or key in VARIANT_LAYOUT_KEYS: + continue + value, path = config[key] + values, need = _as_list(value), variant_length * stride + if key in data: + if len(values) != need and instantiated and vendor in scope: + fitted = fit(rel, key, values, need, stride) + if fitted: + writes[rel][key] = fitted + else: + errors += 1 + elif strict and instantiated: + users[(path[0], key)].append((values, path, need, stride)) + if not writes and strict: + for (_source, key), group in users.items(): + for values, path, need, stride in group: + if len(values) == need or path[-1].split("/")[0] not in scope: + continue + target = next((f for f in path if f.split("/")[0] in scope + and own[f] * stride == need + and all(n == need for _v, p, n, _s in group if f in p)), + path[-1]) + fitted = fit(path[-1], key, values, need, stride) + if fitted: + writes[target][key] = fitted + else: + errors += 1 + if not writes or errors: + break + for rel, arrays in sorted(writes.items()): + def apply(text, _arrays=arrays): + for key, values in _arrays.items(): + text, _n = set_array_value(text, key, values) + return text, len(_arrays) + + try: + data = _edit_profile(os.path.join(profiles_dir, *rel.split("/")), apply, dry_run, + "variant array resize") + except (OSError, RuntimeError, ValueError) as e: + print_error(str(e)) + errors += 1 + continue + print_info(f"{verb}resize {rel}: " + ", ".join( + f"{key} {len(_as_list(files[rel][key])) if key in files[rel] else 'added'}" + f" -> {len(values)}" for key, values in arrays.items())) + files[rel].update(arrays) + changed.add(rel) + if any(data.get(key) != values for key, values in arrays.items()): + print_error(f"{rel}: the variant array resize did not take effect") + errors += 1 + if errors: + break + else: + print_error("variant array resize did not settle; run check") + errors += 1 + load_vendor_configs.cache_clear() # its configs took the writes above + print_success(f"{len(changed)} profile(s) {'would be ' if dry_run else ''}resized") + return len(changed), errors + + # --------------------------------------------------------------------------- # CLI # --------------------------------------------------------------------------- @@ -2321,6 +3084,10 @@ examples: preview exactly that; writes nothing orca_profile_tool.py generate-id --setting-id --vendor Elegoo setting_id only, and only in that bundle + orca_profile_tool.py fix-variant --vendor Snapmaker --dry-run + preview resizing the variant arrays check rejects in that bundle + orca_profile_tool.py check --strict --vendor BBL + also hold every preset's inherited variant arrays to its own width after adding, renaming or deleting profile files, run in this order: normalize -> update-index -> generate-id -> check @@ -2369,19 +3136,39 @@ def build_parser(): name, parents=parents, help=help_text, description=description, allow_abbrev=False, formatter_class=argparse.RawDescriptionHelpFormatter) + strict_opt = argparse.ArgumentParser(add_help=False) + strict_opt.add_argument("--strict", action="store_true", + help="also hold every preset's inherited and included variant " + "arrays to its own width") + add( - "check", [vendor_opt, profiles_opt], + "check", [vendor_opt, strict_opt, profiles_opt], "validate the whole profile tree -- what CI runs", "Validate the whole profile tree: preset name uniqueness, index coverage\n" "both ways, compatible_printers, default-material references, obsolete,\n" - "conflicting and vector-typed keys, filament_id length, that normalize and\n" - "update-index would leave every bundle alone, and the tree-wide setting_id\n" - "and filament_id state. Exits nonzero on errors.\n" + "conflicting and vector-typed keys, variant names and variant array widths,\n" + "filament_id length, that normalize and update-index would leave every\n" + "bundle alone, and the tree-wide setting_id and filament_id state. Exits\n" + "nonzero on errors.\n" "\n" "--vendor narrows the per-vendor checks only: setting_id uniqueness and the\n" "filament_id state are cross-vendor properties a narrowed run cannot answer,\n" "so they always cover the whole tree.") + add("fix-variant", [vendor_opt, strict_opt, dry_run_opt, profiles_opt], + "resize the variant arrays check rejects", + "Resize every variant array that check reports as the wrong width\n" + "in the selectable preset that writes it: extra values are dropped, missing\n" + "ones repeat the last value (the last normal/silent pair for machine_max_*).\n" + "Bases are left alone and no key is added. The variant lists and extruder\n" + "ids are left to check. Byte-preserving apart from the arrays it writes.\n" + "\n" + "--strict then also writes each key that reaches a preset at another width:\n" + "into the most general file on the way down to the preset that has the\n" + "preset's width and whose presets all agree, else into the preset itself.\n" + "Presets of every bundle count towards that agreement; --vendor limits the\n" + "files written.") + generate_cmd = add( "generate-id", [vendor_opt, dry_run_opt, profiles_opt], "write the id each profile's identity implies", @@ -2461,14 +3248,17 @@ def main(argv=None): profile_types = tuple(getattr(args, "profile_type", []) or ()) or None if args.command == "check": - errors = check_profiles(profiles_dir, vendors) + errors = check_profiles(profiles_dir, vendors, strict=args.strict) return 1 if errors else 0 if args.command == "generate-id": return run_generate_id(profiles_dir, vendors, args.filament_id, args.setting_id, args.dry_run) - if args.command == "normalize": + if args.command == "fix-variant": + _changed, errors = fix_variant_arrays(profiles_dir, vendors, dry_run=args.dry_run, + strict=args.strict) + elif args.command == "normalize": _changed, errors = normalize_profiles(profiles_dir, vendors, profile_types, force=args.force, dry_run=args.dry_run) elif args.command == "trim": diff --git a/scripts/run_unit_tests.sh b/scripts/run_unit_tests.sh index 1d3f0046fd..c4433df04d 100755 --- a/scripts/run_unit_tests.sh +++ b/scripts/run_unit_tests.sh @@ -2,7 +2,8 @@ # This file is made to support the unit tests workflow. # It should only require the directories build/tests, scripts/, and tests/ to function, -# and cmake (with ctest) installed. +# and cmake (with ctest) installed -- plus network access to PyPI whenever numpy has to +# be installed into a freshly built test tree (see below). # (otherwise, update the workflow too, but try to avoid to keep things self-contained) # # Usage: run_unit_tests.sh [TEST_DIR] [BUILD_CONFIG] @@ -18,6 +19,52 @@ cd "${ROOT_DIR}" || exit 1 TEST_DIR="${1:-build/tests}" BUILD_CONFIG="${2:-}" +# The slic3rutils plugin-host tests build numpy arrays through the CPython copied next +# to the test binary (see tests/slic3rutils/CMakeLists.txt), which ships no numpy. +# Install it with the uv staged beside that runtime -- the tool the app installs plugin +# dependencies with -- straight into the interpreter's own site-packages: no pip needed +# in the runtime, no PYTHONPATH. Re-checked every run because a rebuild of the test +# target re-copies the runtime; needs network whenever it installs. Pinned so a numpy +# release cannot change results on its own. +NUMPY_VERSION="2.5.3" + +# Without numpy those tests assert the numpy-absent error path instead, so a local run +# only warns. Under CI it fails the run, which would otherwise stay green while silently +# dropping the array coverage. (The Flatpak leg runs this inside `flatpak build`, whose +# minimal environment has no CI, and its offline build stages no uv, so numpy stays +# best-effort there.) +numpy_unavailable() { + if [ -n "${CI:-}" ]; then + echo "error: $1" >&2 + exit 1 + fi + echo "warning: $1; the numpy-backed binding tests will cover only the numpy-absent path." +} + +has_pinned_numpy() { + "${python_exe}" -c "import sys, numpy; sys.exit(numpy.__version__ != '${NUMPY_VERSION}')" >/dev/null 2>&1 +} + +find_args=("${TEST_DIR}" \( -path '*/python/bin/python3' -o -path '*/python/python.exe' \)) +# Multi-config trees hold one copy per configuration; only bootstrap the one being run. +[ -n "${BUILD_CONFIG}" ] && find_args+=(-path "*/${BUILD_CONFIG}/*") +python_exe="$(find "${find_args[@]}" -print -quit 2>/dev/null)" + +if [ -z "${python_exe}" ]; then + numpy_unavailable "no bundled Python under ${TEST_DIR}" +elif ! has_pinned_numpy; then + uv_exe="${python_exe%/python/*}/tools/uv/uv" + # Builds that bundle no uv (Windows arm64) fall back to one on PATH. + [ -x "${uv_exe}" ] || uv_exe="$(command -v uv)" + echo "Installing numpy ${NUMPY_VERSION} into the embedded test interpreter (${python_exe})..." + if [ -z "${uv_exe}" ]; then + numpy_unavailable "no uv staged beside the tests or on PATH" + elif ! "${uv_exe}" pip install --python "${python_exe}" --only-binary :all: "numpy==${NUMPY_VERSION}" \ + || ! has_pinned_numpy; then + numpy_unavailable "could not install numpy ${NUMPY_VERSION} into ${python_exe}" + fi +fi + # Run the whole suite, excluding tests tagged [NotWorking] and tests labelled RequiresApp, # which run the built orca-slicer binary that this directory does not contain. # --no-tests=error fails the job if the filter matches nothing (instead of passing green). diff --git a/scripts/tests/test_profile_tool.py b/scripts/tests/test_profile_tool.py index 5359b1158b..d32dbd144e 100644 --- a/scripts/tests/test_profile_tool.py +++ b/scripts/tests/test_profile_tool.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Tests for the tree-maintenance half of scripts/orca_profile_tool.py: the -normalize, trim, update-index and check commands, and the subcommand dispatch that -reaches them (stdlib unittest, no external deps). +normalize, trim, update-index, fix-variant and check commands, and the subcommand +dispatch that reaches them (stdlib unittest, no external deps). The id halves are covered by test_filament_id.py and test_setting_id.py. @@ -140,6 +140,28 @@ class TestObsoleteKeys(unittest.TestCase): self.assertEqual(apt.OBSOLETE_KEYS, set(re.findall(r'"([^"\n]+)"', keys))) +class TestVariantScheme(unittest.TestCase): + def test_the_key_sets_are_read_from_the_engine(self): + scheme = apt._variant_scheme() + self.assertEqual(scheme["machine"][1]["retraction_length"], 1) + self.assertEqual(scheme["machine"][1]["machine_max_speed_x"], 2) + self.assertIn("outer_wall_speed", scheme["process"][1]) + self.assertIn("nozzle_temperature", scheme["filament"][1]) + # Commented out of its initializer, so not a member. + self.assertNotIn("filament_extruder_id", scheme["filament"][1]) + for list_key, strides in scheme.values(): + self.assertEqual(strides[list_key], 1) + + def test_the_variant_names_are_read_from_the_engine(self): + extruder_types, volume_types, legacy, extruder_legacy = apt._variant_names() + self.assertEqual(extruder_types, {"Direct Drive", "Bowden"}) + self.assertEqual(volume_types, {"Standard", "High Flow", "TPU High Flow", "E3D High Flow", "Extra High Flow"}) + # Hybrid is an enum value no variant string may name. + self.assertNotIn("Hybrid", volume_types) + self.assertEqual(legacy, {"Normal": "Standard", "Big Traffic": "High Flow"}) + self.assertEqual(extruder_legacy, {"DirectDrive": "Direct Drive"}) + + class TestNormalize(TreeCase): def test_a_missing_type_is_filled_in_from_the_directory(self): self.t.write("V", "filament/A.json", {"name": "A"}) @@ -917,10 +939,330 @@ class TestNormalized(TreeCase): # CLI dispatch # --------------------------------------------------------------------------- +class TestFixVariant(TreeCase): + def test_cooling_arrays_require_one_value_per_declared_variant(self): + keys = ("fan_min_speed", "fan_max_speed", "additional_cooling_fan_speed") + variants = ["Direct Drive Standard", "Direct Drive High Flow", "Bowden Standard"] + for width in (1, 2, 3, 4): + with self.subTest(width=width): + self.preset("filament/F.json", instantiation="true", + filament_extruder_variant=variants, + **{key: ["20"] * width for key in keys}) + apt.load_vendor_configs.cache_clear() + errors, out = self.width_errors() + self.assertEqual(errors, 0 if width == 3 else len(keys), out) + if width != 3: + for key in keys: + self.assertIn(f'"{key}" has {width} values', out) + + def preset(self, rel, **data): + name = os.path.splitext(os.path.basename(rel))[0] + self.t.write("V", rel, {"type": rel.split("/")[0], "name": name, **data}) + self.t.index("V", rel.split("/")[0], name, rel) + + def processes(self, common): + """outer_wall_speed written once in a list-less base, reached by list-less + presets through one base and by two-variant presets through another.""" + dual = ["Direct Drive Standard", "Direct Drive High Flow"] + self.preset("process/common.json", instantiation="false", outer_wall_speed=common) + self.preset("process/single.json", inherits="common", instantiation="false") + self.preset("process/dual.json", inherits="common", instantiation="false", + print_extruder_variant=dual, print_extruder_id=["1", "1"]) + for name, base in (("S1", "single"), ("S2", "single"), ("D1", "dual")): + self.preset(f"process/{name}.json", inherits=base, instantiation="true") + + def width_errors(self, *strict): + buf = io.StringIO() + with contextlib.redirect_stdout(buf): + errors, _warnings = apt.check_variant_arrays(self.t.profiles, "V", bool(strict)) + return errors, buf.getvalue() + + def test_a_machine_without_a_variant_list_has_one_variant_per_extruder(self): + # extruder_variant_list defaults to one "Direct Drive Standard" per extruder. + self.preset("machine/M.json", instantiation="true", nozzle_diameter=["0.4", "0.4"], + retraction_length=["0.8", "1.2"], z_hop=["0.4"], + machine_max_speed_x=["500", "200"]) + errors, out = self.width_errors() + self.assertEqual(errors, 2, out) + self.assertIn('M.json: "z_hop" has 1 values for variant length 2 (no ' + 'printer_extruder_variant, so one default variant per extruder) at stride 1, ' + 'which takes 2', out) + self.assertIn('M.json: "machine_max_speed_x" has 2 values for variant length 2', out) + self.assertNotIn("retraction_length", out) + + def test_one_value_is_an_error_where_the_list_has_more_variants(self): + self.preset("process/P.json", instantiation="true", outer_wall_speed=["30"], + print_extruder_id=["1", "1"], + print_extruder_variant=["Direct Drive Standard", "Direct Drive High Flow"]) + errors, out = self.width_errors() + self.assertEqual(errors, 1, out) + self.assertIn('P.json: "outer_wall_speed" has 1 values for variant length 2 at stride 1, ' + 'which takes 2', out) + + def test_one_value_is_padded_to_every_variant(self): + self.preset("machine/M.json", instantiation="true", nozzle_diameter=["0.4"] * 3, + retraction_length=["0.8"], machine_max_speed_x=["500", "200"]) + rc, out = self.run_command("fix-variant") + self.assertEqual(rc, 0, out) + machine = self.t.read("V", "machine/M.json") + self.assertEqual(machine["retraction_length"], ["0.8"] * 3) + self.assertEqual(machine["machine_max_speed_x"], ["500", "200"] * 3) + self.assertEqual(self.width_errors()[0], 0) + + def test_extruder_ids_are_left_to_check(self): + self.preset("process/P.json", instantiation="true", print_extruder_id=["1"], + print_extruder_variant=["Direct Drive Standard", "Direct Drive High Flow"]) + self.run_command("fix-variant") + self.assertEqual(self.t.read("V", "process/P.json")["print_extruder_id"], ["1"]) + errors, out = self.width_errors() + self.assertEqual(errors, 1, out) + self.assertIn("print_extruder_id has 1 entries for the 2 entries", out) + + def test_a_base_is_judged_only_where_its_array_reaches_a_preset(self): + # A leaf overriding the base's one-value limit passes in both modes. + self.preset("machine/common.json", instantiation="false", machine_max_speed_x=["500"]) + self.preset("machine/M.json", inherits="common", instantiation="true", + machine_max_speed_x=["500", "200"]) + self.assertEqual(self.width_errors()[0], 0) + self.assertEqual(self.width_errors("strict")[0], 0) + + def test_a_shared_array_is_fixed_in_the_base_whose_presets_agree(self): + self.processes(["30", "40"]) + self.assertEqual(self.width_errors()[0], 0) + errors, out = self.width_errors("strict") + self.assertEqual(errors, 2, out) + self.assertIn('process/S1.json: "outer_wall_speed" has 2 values for variant length 1', out) + rc, out = self.run_command("fix-variant", "--strict") + self.assertEqual(rc, 0, out) + self.assertEqual(self.t.read("V", "process/single.json")["outer_wall_speed"], ["30"]) + self.assertEqual(self.t.read("V", "process/common.json")["outer_wall_speed"], + ["30", "40"]) + self.assertNotIn("outer_wall_speed", self.t.read("V", "process/S1.json")) + self.assertEqual(self.width_errors("strict")[0], 0) + + def test_an_inherited_array_is_checked_and_restated_only_when_strict(self): + self.processes(["30"]) + self.assertEqual(self.width_errors()[0], 0) + errors, out = self.width_errors("strict") + self.assertEqual(errors, 1, out) + self.assertIn('process/D1.json: "outer_wall_speed" has 1 values for variant length 2 at ' + 'stride 1, which takes 2 (it comes from V/process/common.json)', out) + before = self.t.bytes_map() + self.run_command("fix-variant") + self.assertEqual(self.t.bytes_map(), before) + rc, out = self.run_command("fix-variant", "--strict") + self.assertEqual(rc, 0, out) + self.assertEqual(self.t.read("V", "process/dual.json")["outer_wall_speed"], ["30", "30"]) + self.assertEqual(self.t.read("V", "process/common.json")["outer_wall_speed"], ["30"]) + self.assertEqual(self.width_errors("strict")[0], 0) + + def test_a_strict_array_never_lands_in_a_file_of_another_width(self): + # common is list-less (width 1) and D2 inherits it directly, so D2 takes it. + self.processes(["30"]) + self.preset("process/D2.json", inherits="common", instantiation="true", + print_extruder_variant=["Direct Drive Standard", "Direct Drive High Flow"], + print_extruder_id=["1", "1"]) + self.run_command("fix-variant", "--strict") + self.assertEqual(self.t.read("V", "process/D2.json")["outer_wall_speed"], ["30", "30"]) + self.assertEqual(self.t.read("V", "process/common.json")["outer_wall_speed"], ["30"]) + self.assertEqual(self.width_errors("strict")[0], 0) + + def test_extra_values_are_dropped_where_they_are_written(self): + self.preset("process/base.json", instantiation="false", outer_wall_speed=["30", "0"]) + self.preset("process/P1.json", inherits="base", instantiation="true", + inner_wall_speed=["40", "0"]) + self.preset("process/P2.json", inherits="base", instantiation="true") + self.run_command("fix-variant") + self.assertEqual(self.t.read("V", "process/P1.json")["inner_wall_speed"], ["40"]) + self.assertEqual(self.t.read("V", "process/base.json")["outer_wall_speed"], ["30", "0"]) + self.run_command("fix-variant", "--strict") + self.assertEqual(self.t.read("V", "process/base.json")["outer_wall_speed"], ["30"]) + self.assertNotIn("outer_wall_speed", self.t.read("V", "process/P1.json")) + + def test_the_rest_of_the_file_keeps_its_bytes(self): + self.t.write_raw("V", "process/P.json", b'{\n "type": "process", "name": "P",\n' + b' "instantiation": "true",\n "outer_wall_speed": ["30", "0"],\n' + b' "inner_wall_speed": [\n "40",\n "0"\n ]\n}\n') + self.t.index("V", "process", "P", "process/P.json") + self.run_command("fix-variant") + self.assertEqual(self.t.raw("V", "process/P.json"), + b'{\n "type": "process", "name": "P",\n' + b' "instantiation": "true",\n "outer_wall_speed": ["30"],\n' + b' "inner_wall_speed": [\n "40"\n ]\n}\n') + + def test_a_dry_run_writes_nothing(self): + self.processes(["30"]) + before = self.t.bytes_map() + rc, out = self.run_command("fix-variant", "--strict", "--dry-run") + self.assertEqual(rc, 0, out) + self.assertIn("would resize V/process/dual.json: outer_wall_speed added -> 2", out) + self.assertEqual(self.t.bytes_map(), before) + + def test_padding_repeats_the_last_value_or_pair(self): + self.assertEqual(apt._fit_width(["a", "b"], 4, 1), ["a", "b", "b", "b"]) + self.assertEqual(apt._fit_width(["a", "b", "c"], 6, 2), ["a", "b"] * 3) + self.assertEqual(apt._fit_width(["a", "b", "c"], 2, 2), ["a", "b"]) + self.assertEqual(apt._fit_width(["a"], 4, 2), ["a"] * 4) + + +class TestVariantNames(TreeCase): + def preset(self, rel, vendor="V", **data): + section = rel.split("/")[0] + name = os.path.splitext(os.path.basename(rel))[0] + self.t.write(vendor, rel, {"type": section, "name": name, **data}) + self.t.index(vendor, section, name, rel) + + def names(self, vendor="V"): + buf = io.StringIO() + with contextlib.redirect_stdout(buf): + errors = apt.check_variant_names(self.t.profiles, vendor) + return errors, buf.getvalue() + + def test_a_legal_variant_layout_passes(self): + self.preset("machine/M.json", instantiation="true", nozzle_diameter=["0.4"], + extruder_type=["Direct Drive"], + extruder_variant_list=["Direct Drive Standard,Direct Drive High Flow"], + printer_extruder_id=["1", "1"], + printer_extruder_variant=["Direct Drive Standard", + "Direct Drive High Flow"], + nozzle_volume_type=["High Flow"], + default_nozzle_volume_type=["Standard"]) + self.preset("process/P.json", instantiation="true", print_extruder_id=["1", "1"], + print_extruder_variant=["Direct Drive Standard", + "Direct Drive High Flow"]) + self.preset("filament/F.json", instantiation="true", + filament_extruder_variant=["Direct Drive Standard", "Bowden High Flow"]) + self.assertEqual(self.names()[0], 0, self.names()[1]) + + def test_a_variant_the_enum_cannot_build_is_an_error(self): + # An unknown volume type, in a list and in a menu, an extruder type that is not + # one, and the legacy extruder spelling that is rewritten in extruder_type alone. + cases = (("process/P1.json", "print_extruder_variant", "Direct Drive Fast", + 'entry 1 holds "Direct Drive Fast"', + "not a nozzle volume type the enum has"), + ("machine/M.json", "extruder_variant_list", + "Direct Drive Standard,Direct Drive Fast", + 'extruder 1 holds "Direct Drive Fast"', + "not a nozzle volume type the enum has"), + ("process/P2.json", "print_extruder_variant", "DD Standard", + 'entry 1 holds "DD Standard"', + "does not start with an extruder type the enum has"), + ("filament/F.json", "filament_extruder_variant", "DirectDrive Standard", + 'entry 1 holds "DirectDrive Standard"', + "does not start with an extruder type the enum has")) + for rel, key, value, _held, _why in cases: + self.preset(rel, instantiation="false", **{key: [value]}) + errors, out = self.names() + self.assertEqual(errors, len(cases), out) + for rel, key, _value, held, why in cases: + self.assertIn(f"V/{rel}: {key} {held}", out) + self.assertIn(why, out) + + def test_the_legacy_names_the_loader_rewrites_are_errors(self): + self.preset("machine/M.json", extruder_type=["DirectDrive"], + nozzle_volume_type=["Big Traffic"], + default_nozzle_volume_type=["Normal"], + printer_extruder_variant=["Direct Drive Big Traffic"]) + errors, out = self.names() + self.assertEqual(errors, 4, out) + self.assertIn('extruder_type spells the legacy name "DirectDrive"; the loader ' + 'still rewrites it to "Direct Drive"', out) + self.assertIn('V/machine/M.json: nozzle_volume_type spells the legacy name ' + '"Big Traffic"', out) + self.assertIn('default_nozzle_volume_type spells the legacy name "Normal"', out) + self.assertIn('holds the legacy variant "Direct Drive Big Traffic"', out) + self.assertIn('a profile writes the enum name: "Direct Drive High Flow"', out) + + def test_an_empty_entry_is_an_error(self): + self.preset("filament/F.json", + filament_extruder_variant=["Direct Drive Standard", ""]) + errors, out = self.names() + self.assertEqual(errors, 1, out) + self.assertIn("filament_extruder_variant entry 2 is empty", out) + + def test_hybrid_is_runtime_only(self): + self.preset("machine/M.json", nozzle_volume_type=["Hybrid"], + default_nozzle_volume_type=["Hybrid"], + printer_extruder_variant=["Direct Drive Hybrid"]) + errors, out = self.names() + self.assertEqual(errors, 3, out) + self.assertIn("Hybrid names the sub-nozzles of one hybrid extruder at runtime", out) + self.assertIn('V/machine/M.json: nozzle_volume_type names "Hybrid"', out) + self.assertIn('default_nozzle_volume_type names "Hybrid"', out) + + def test_bbl_is_held_to_the_enums_like_every_bundle(self): + # E3D High Flow passes because the engine's enum has it; TPU285 is a name no enum has. + self.preset("machine/M.json", vendor="BBL", extruder_type=["Direct Drive"], + extruder_variant_list=["Direct Drive Standard,Direct Drive E3D High Flow"], + printer_extruder_id=["1", "1"], + printer_extruder_variant=["Direct Drive Standard", + "Direct Drive E3D High Flow"]) + self.preset("process/P.json", vendor="BBL", instantiation="true", + print_extruder_variant=["Direct Drive TPU285"]) + errors, out = self.names("BBL") + self.assertEqual(errors, 1, out) + self.assertNotIn('holds "Direct Drive E3D High Flow"', out) + self.assertIn('"TPU285" is not a nozzle volume type the enum has', out) + + def test_a_list_may_not_name_one_variant_twice(self): + self.preset("filament/F.json", + filament_extruder_variant=["Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard"]) + self.preset("machine/M.json", + extruder_variant_list=["Direct Drive Standard,Direct Drive Standard," + "Direct Drive High Flow"]) + self.preset("process/P.json", print_extruder_id=["1", "1", "1"], + print_extruder_variant=["Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard"]) + errors, out = self.names() + self.assertEqual(errors, 3, out) + self.assertIn('filament_extruder_variant lists "Direct Drive Standard" 2 times', out) + self.assertIn('extruder_variant_list extruder 1 lists "Direct Drive Standard" 2 ' + "times", out) + self.assertIn('print_extruder_variant lists the pair (extruder 1, "Direct Drive ' + 'Standard") 2 times', out) + + def test_one_variant_on_two_extruders_is_two_pairs_not_a_repeat(self): + self.preset("process/P.json", print_extruder_id=["1", "2"], + print_extruder_variant=["Direct Drive Standard", + "Direct Drive Standard"]) + self.assertEqual(self.names()[0], 0, self.names()[1]) + + def test_an_unknown_enum_value_fails_the_bundle(self): + self.preset("machine/M.json", extruder_type=["Direct Drive", "Magnetic Drive"], + nozzle_volume_type=["Turbo"], + default_nozzle_volume_type=["Fast Flow"]) + errors, out = self.names() + self.assertEqual(errors, 3, out) + self.assertIn('extruder_type "Magnetic Drive" is not one of (Bowden, Direct Drive)', + out) + self.assertIn('V/machine/M.json: nozzle_volume_type "Turbo" is not one of (E3D High ' + "Flow, Extra High Flow, High Flow, Standard, TPU High Flow)", out) + self.assertIn('default_nozzle_volume_type "Fast Flow" is not one of (E3D High Flow, ' + "Extra High Flow, High Flow, Standard, TPU High Flow)", out) + + def test_a_file_no_list_references_is_not_judged(self): + # It never loads, so its variant names cannot reach anything; + # check_index_coverage reports the file itself. + self.t.write("V", "machine/M.json", {"type": "machine", "name": "M", + "printer_extruder_variant": ["Direct Drive Fast"]}) + self.assertEqual(self.names()[0], 0, self.names()[1]) + + def test_check_runs_it(self): + self.preset("filament/F.json", instantiation="false", + filament_extruder_variant=["Direct Drive Normal"]) + self.run_command("update-index") # so nothing but the name check can fail + rc, out = self.run_command("check") + self.assertEqual(rc, 1, out) + self.assertIn('holds the legacy variant "Direct Drive Normal"', out) + + class TestDispatch(TreeCase): def test_each_command_reaches_its_own_writer(self): self.t.write("V", "filament/A.json", {"type": "filament", "name": "A"}) for command, expected in (("normalize", "normalized"), + ("fix-variant", "resized"), ("trim", "unreferenced"), ("update-index", "vendor index")): with self.subTest(command=command): @@ -931,7 +1273,8 @@ class TestDispatch(TreeCase): def test_an_option_belongs_to_one_command_only(self): for argv in (["trim", "--force"], ["update-index", "--filament-id"], - ["check", "--profile-type", "filament"]): + ["check", "--profile-type", "filament"], + ["normalize", "--strict"]): with self.subTest(argv=argv): with self.assertRaises(SystemExit) as cm, \ contextlib.redirect_stdout(io.StringIO()), \ diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index e7facbdbd8..87352f505e 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -1913,7 +1913,8 @@ int CLI::run(int argc, char **argv) old_printable_width = static_cast(old_printable_bbox.size().x()); old_printable_depth = static_cast(old_printable_bbox.size().y()); } - old_printable_height = (int)(config.opt_float("printable_height")); + if (config.option("printable_height")) + old_printable_height = (int)(config.opt_float("printable_height")); if (config.option("extruder_clearance_height_to_rod")) old_height_to_rod = config.opt_float("extruder_clearance_height_to_rod"); @@ -2116,9 +2117,14 @@ int CLI::run(int argc, char **argv) // One resolver for the whole run, so presets from the same vendor tree share its load. std::unique_ptr system_preset_resolver; - auto resolve_preset = [&ensure_cli_preset_bundle, &system_preset_resolver](const std::string &file, DynamicPrintConfig &config, - std::string &config_type, const std::string &config_from, - bool probe_type, std::string &error) { + auto ensure_system_preset_resolver = [&system_preset_resolver]() -> PresetBundle & { + if (!system_preset_resolver) + system_preset_resolver = std::make_unique(); + return *system_preset_resolver; + }; + auto resolve_preset = [&ensure_cli_preset_bundle, &ensure_system_preset_resolver](const std::string &file, DynamicPrintConfig &config, + std::string &config_type, const std::string &config_from, + bool probe_type, std::string &error) { const auto *inherits = config.option(BBL_JSON_KEY_INHERITS); if (!probe_type && (inherits == nullptr || inherits->value.empty())) return true; @@ -2126,9 +2132,7 @@ int CLI::run(int argc, char **argv) PresetBundle *bundle = nullptr; bool allow_source_manifest = false; if (config_from == "system") { - if (!system_preset_resolver) - system_preset_resolver = std::make_unique(); - bundle = system_preset_resolver.get(); + bundle = &ensure_system_preset_resolver(); allow_source_manifest = true; } else { bundle = ensure_cli_preset_bundle(error); @@ -3120,6 +3124,44 @@ int CLI::run(int argc, char **argv) return 0; }; + // Load the project's printer and process settings as the GUI loads its presets: over the default preset, + // with every key the project does not list as changed, including keys saved before an option existed, + // taken from its current system preset. + auto load_project_preset = [this, &ensure_system_preset_resolver, ¤t_different_settings, filament_count](const std::string &system_name, Preset::Type type) { + if (system_name.empty()) + return; + // Preset bookkeeping the CLI keeps in its own groups, e.g. inherits_group and print_compatible_printers. + static const std::set bookkeeping_keys = {"inherits", "compatible_printers", "compatible_prints", "compatible_printers_condition", + "compatible_prints_condition", "print_settings_id", "printer_settings_id"}; + const size_t index = type == Preset::TYPE_PRINTER ? filament_count + 1 : 0; + PresetBundle &resolver = ensure_system_preset_resolver(); + DynamicPrintConfig system_config; + t_config_option_keys keys; + const DynamicPrintConfig config = Preset::load_external_config(type, + type == Preset::TYPE_PRINTER ? resolver.printers.default_preset_for(m_print_config).config : resolver.prints.default_preset().config, + m_print_config, PresetBundle::project_different_keys(index < current_different_settings.size() ? current_different_settings[index] : std::string()), + [&](const std::string &) -> DynamicPrintConfig * { + std::string error; + if (resolver.resolve_system_preset(system_config, type, system_name, config_substitution_rule, error)) + return &system_config; + BOOST_LOG_TRIVIAL(warning) << boost::format("CLI: system preset '%1%' not resolved (%2%); the project keeps its values") % system_name % error; + return nullptr; + }, &keys); + for (const std::string &key : keys) { + const ConfigOption *opt = config.option(key); + const ConfigOption *old = m_print_config.option(key); + if (bookkeeping_keys.count(key) != 0 || opt == nullptr || (old != nullptr && *old == *opt)) + continue; + BOOST_LOG_TRIVIAL(info) << boost::format("CLI: %1% from '%2%': %3% -> %4%") % key % system_name % (old ? old->serialize() : std::string("(missing)")) % opt->serialize(); + m_print_config.set_key_value(key, opt->clone()); + } + }; + // The --uptodate path refreshes the project from its own system configs. + if (new_printer_name.empty() && load_machine_config.empty()) + load_project_preset(current_printer_system_name, Preset::TYPE_PRINTER); + if (new_process_name.empty() && load_process_config.empty()) + load_project_preset(current_process_system_name, Preset::TYPE_PRINT); + std::vector& different_settings = m_print_config.option("different_settings_to_system", true)->values; std::vector& inherits_group = m_print_config.option("inherits_group", true)->values; inherits_group.resize(filament_count + 2, std::string()); @@ -3476,6 +3518,14 @@ int CLI::run(int argc, char **argv) } new_variant_counts = old_variant_counts; //filament_variant_count = old_variant_counts; + //ORCA: lay the per-variant options out one value per variant of the current filaments before each + // loaded filament replaces its own variants, including an option only a loaded filament + // defines, which otherwise starts as a single default value and never reaches the others. + for (const DynamicPrintConfig &config : load_filaments_config) + for (const std::string &opt_key : filament_options_with_variant) + if (opt_key != "filament_extruder_variant" && config.has(opt_key)) + m_print_config.option(opt_key, true); + normalize_filament_values_to_variants(m_print_config); for (int index = 0; index < load_filaments_config.size(); index++) { DynamicPrintConfig& config = load_filaments_config[index]; int filament_index = load_filaments_index[index]; @@ -3647,6 +3697,25 @@ int CLI::run(int argc, char **argv) } } + //ORCA: a per-variant option the loaded filament does not define keeps the values of the + // variants the filament already had, and a variant new to it takes its first one's. + const int old_start = old_start_indice[filament_index - 1]; + std::vector kept_variant_indice = new_variant_indice; + for (int &i : kept_variant_indice) + if (i < 0) + i = old_start; + for (const std::string &opt_key : filament_options_with_variant) { + if (config.has(opt_key)) + continue; + auto *opt_vec_dst = dynamic_cast(m_print_config.option(opt_key)); + if (opt_vec_dst == nullptr || opt_vec_dst->size() < size_t(old_start + old_variant_count)) + continue; + // set_with_restore_2() pads its source in place + std::unique_ptr old_values(opt_vec_dst->clone()); + opt_vec_dst->set_with_restore_2(static_cast(old_values.get()), kept_variant_indice, old_start, + old_variant_count, true); + } + //update the old index if (old_variant_count != new_variant_count) { @@ -4081,6 +4150,9 @@ int CLI::run(int argc, char **argv) if (printer_technology == ptFFF) { fff_print_config.apply(m_print_config, true); m_print_config.apply(fff_print_config, true); + //ORCA: an option no preset or project defines has just come in as its single default value, and a + // command line override may hold one value per filament. + normalize_filament_values_to_variants(m_print_config); } else { boost::nowide::cerr << "invalid printer_technology " << std::endl; record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH], sliced_info); @@ -7290,9 +7362,9 @@ int CLI::run(int argc, char **argv) colors_out[color_idx] = ColorRGBA(float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, float(rgb_color[3]) / 255.f); } - int gl_major, gl_minor, gl_verbos; - glfwGetVersion(&gl_major, &gl_minor, &gl_verbos); - BOOST_LOG_TRIVIAL(info) << boost::format("opengl version %1%.%2%.%3%")%gl_major %gl_minor %gl_verbos; + int glfw_major, glfw_minor, glfw_revision; + glfwGetVersion(&glfw_major, &glfw_minor, &glfw_revision); + BOOST_LOG_TRIVIAL(info) << boost::format("GLFW version %1%.%2%.%3%") % glfw_major % glfw_minor % glfw_revision; bool thumbnail_opengl_ready = false; glfwSetErrorCallback(glfw_callback); @@ -7304,8 +7376,9 @@ int CLI::run(int argc, char **argv) } else { BOOST_LOG_TRIVIAL(info) << "glfwInit Success."<< std::endl; - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, gl_major); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, gl_minor); + // Request OrcaSlicer's minimum OpenGL version, independently of the GLFW library version. + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_RED_BITS, 8); glfwWindowHint(GLFW_GREEN_BITS, 8); glfwWindowHint(GLFW_BLUE_BITS, 8); @@ -7321,6 +7394,16 @@ int CLI::run(int argc, char **argv) #endif GLFWwindow* window = glfwCreateWindow(640, 480, "base_window", NULL, NULL); +#ifndef __WXMAC__ + if (window == NULL) { + // Some drivers (e.g. older Mesa) only expose compatibility profile 3.0; take whatever they offer. + BOOST_LOG_TRIVIAL(warning) << "Failed to create OpenGL 3.3 compatibility context, retrying with driver default" << std::endl; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); + window = glfwCreateWindow(640, 480, "base_window", NULL, NULL); + } +#endif if (window == NULL) { BOOST_LOG_TRIVIAL(error) << "Failed to create GLFW window; skipping thumbnail rendering for CLI export" << std::endl; diff --git a/src/dev-utils/OrcaSlicer_profile_validator.cpp b/src/dev-utils/OrcaSlicer_profile_validator.cpp index 557dda7eec..c328c565c8 100644 --- a/src/dev-utils/OrcaSlicer_profile_validator.cpp +++ b/src/dev-utils/OrcaSlicer_profile_validator.cpp @@ -20,6 +20,7 @@ #include "libslic3r/Model.hpp" #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Utils.hpp" +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include using namespace Slic3r; @@ -160,37 +162,62 @@ Vec2d place_wipe_tower(DynamicPrintConfig &cfg, const Vec2d ¢er) return rigid ? move : Vec2d::Zero(); } -// Slice one cube that switches from filament 1 to filament 2 partway up, so exactly one -// filament change fires, then export. The change drives the printer's own change_filament_gcode: on a -// single-nozzle machine it rides the AMS prime tower (append_tcr), on a multi-nozzle machine it routes -// through the nozzle swap (set_extruder / append_tcr2) - the engine picks the path from the printer's -// topology, so one model covers both. An undefined placeholder in any shipped custom g-code throws -// Slic3r::PlaceholderParserError from export. -std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl) +// Slice cubes that switch from filament 1 to filament 2 partway up, so a filament change fires, then +// export. The change drives the printer's own change_filament_gcode: on a single-nozzle machine it rides +// the AMS prime tower (append_tcr), on a multi-nozzle machine it routes through the nozzle swap +// (set_extruder / append_tcr2) - the engine picks the path from the printer's topology, so one model +// covers both. The layer-by-layer slice also pauses at z 2 and runs the template custom g-code at z 7, so +// machine_pause_gcode and template_custom_gcode expand, and turns clumping detection on for a printer that +// ships wrapping_detection_gcode. The by-object slice prints two cubes in turn without a prime tower: +// printing_by_object_gcode fires before the second one, and the filament change goes through set_extruder. +// Either way the output file name is built after export, which expands filename_format with the final +// print statistics. An undefined placeholder in any shipped custom g-code throws +// Slic3r::PlaceholderParserError. +std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl, bool by_object) { - const Vec2d center = printable_area_center(cfg); - const Vec2d cube_min = center - Vec2d(5., 5.) + place_wipe_tower(cfg, center); - TriangleMesh m = make_cube(10, 10, 10); - m.translate(static_cast(cube_min.x()), static_cast(cube_min.y()), 0.f); + const Vec2d center = printable_area_center(cfg); + std::vector cube_mins; + if (by_object) { + // By-object printing fires the hook only without a wipe tower, and rules out clumping detection and + // smooth timelapse. No skirt, so the two cubes' own skirts cannot overlap. + cfg.set_key_value("print_sequence", new ConfigOptionEnum(PrintSequence::ByObject)); + cfg.set_key_value("enable_prime_tower", new ConfigOptionBool(false)); + cfg.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false)); + cfg.set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); + cfg.set_key_value("skirt_loops", new ConfigOptionInt(0)); + cube_mins = {center + Vec2d(-20., -5.), center + Vec2d(10., -5.)}; + } else { + // Clumping detection changes the tower footprint, so turn it on before placing the tower. + if (!cfg.opt_string("wrapping_detection_gcode").empty()) + cfg.set_key_value("enable_wrapping_detection", new ConfigOptionBool(true)); + cube_mins = {center - Vec2d(5., 5.) + place_wipe_tower(cfg, center)}; + } Model model; Print print; - ModelObject *obj = model.add_object(); - obj->name = "cube"; // populates [input_filename_base] the way a loaded model does - obj->add_volume(m); - obj->add_instance(); - // Filament 2 is used only above z=4, so the upper layers carry a single filament change. - DynamicPrintConfig range_config; - range_config.set_key_value("extruder", new ConfigOptionInt(2)); - // Every range must carry a layer_height; use the process's own so a fine nozzle (e.g. 0.15 mm - // printing ~0.1 mm layers) isn't forced to a height its extrusion width can't support - that - // trips Flow::with_spacing. - range_config.set_key_value("layer_height", new ConfigOptionFloat(cfg.opt_float("layer_height"))); - obj->layer_config_ranges[{4.0, 10.0}].assign_config(std::move(range_config)); - print.is_BBL_printer() = is_bbl; - obj->ensure_on_bed(); - print.auto_assign_extruders(obj); + for (const Vec2d &cube_min : cube_mins) { + TriangleMesh m = make_cube(10, 10, 10); + m.translate(static_cast(cube_min.x()), static_cast(cube_min.y()), 0.f); + ModelObject *obj = model.add_object(); + obj->name = "cube"; // populates [input_filename_base] the way a loaded model does + obj->add_volume(m); + obj->add_instance(); + // Filament 2 is used only above z=4, so the upper layers carry a single filament change. + DynamicPrintConfig range_config; + range_config.set_key_value("extruder", new ConfigOptionInt(2)); + // Every range must carry a layer_height; use the process's own so a fine nozzle (e.g. 0.15 mm + // printing ~0.1 mm layers) isn't forced to a height its extrusion width can't support - that + // trips Flow::with_spacing. + range_config.set_key_value("layer_height", new ConfigOptionFloat(cfg.opt_float("layer_height"))); + obj->layer_config_ranges[{4.0, 10.0}].assign_config(std::move(range_config)); + obj->ensure_on_bed(); + print.auto_assign_extruders(obj); + } + // Custom g-codes per print_z apply to layer-by-layer printing only (ToolOrdering::assign_custom_gcodes). + if (!by_object) + model.plates_custom_gcodes[model.curr_plate_index].gcodes = {{2., CustomGCode::PausePrint, 1, "", ""}, + {7., CustomGCode::Template, 1, "", ""}}; print.apply(model, cfg); print.validate(); @@ -205,6 +232,7 @@ std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl) in.close(); boost::system::error_code ec; fs::remove(tmp, ec); + print.output_filename(); // names the export as the app does, expanding filename_format return out; } @@ -264,18 +292,125 @@ void install_slice_context_log_sink() logging::core::get()->add_sink(sink); } +// Size the filament slots for the current selection and build the config every slice uses. +DynamicPrintConfig slice_config(PresetBundle &bundle) +{ + // Grow to a 2nd filament so the cube can change colour; never shrink a multi-nozzle printer + // below its nozzle count, or full_config()'s flush-volume matrix no longer matches validate(). + const size_t nozzles = bundle.printers.get_selected_preset().config.option("nozzle_diameter")->size(); + bundle.set_num_filaments((unsigned int) std::max(2, nozzles)); + + // Mirror the app's manual filament->nozzle assignment for a multi-nozzle BBL printer: put each + // filament on its own nozzle and pin the map (fmmManual) so full_config() collapses every filament to + // the variant of the nozzle it actually prints from, and the engine keeps that assignment instead of + // auto-remapping it during process(). Without this the synthetic 2nd filament keeps nozzle 1's variant + // while the auto map moves it to nozzle 2 - harmless, but on the one printer whose nozzles differ in + // type (Direct Drive + Bowden) the mismatched lookup spams [error] lines. Single-nozzle and non-BBL + // printers keep the default map (their toolchange rides the AMS/tool-changer path unchanged). + const bool pin_filament_map = bundle.is_bbl_vendor() && nozzles > 1; + auto &fmap = bundle.project_config.option("filament_map", true)->values; + if (pin_filament_map) { + for (size_t i = 0; i < fmap.size(); ++i) + fmap[i] = int(i % nozzles) + 1; + } + + // A fresh printer selection uses its declared nozzle volumes, just like the + // app. Otherwise a high-flow preset is silently sliced with Standard tuning. + bundle.reset_default_nozzle_volume_type(); + bundle.project_config.option("filament_volume_map", true)->values = + bundle.get_default_nozzle_volume_types_for_filaments(fmap); + + DynamicPrintConfig cfg = bundle.full_config(); + cfg.set_key_value("enable_prime_tower", new ConfigOptionBool(true)); // force a purge tower so the change is detectable + // The map above drives full_config()'s per-filament variant collapse; fmmManual on the sliced config + // stops process() from auto-remapping filaments back onto a different nozzle (which would re-introduce + // the variant mismatch this pinning avoids). + if (pin_filament_map) + cfg.set_key_value("filament_map_mode", new ConfigOptionEnum(fmmManual)); + + // full_config() grows filament_extruder_variant to one entry per filament, but because the synthetic + // 2nd filament is a duplicate of the first (set_num_filaments copies the same preset), it leaves + // filament_self_index at size 1. That makes update_values_to_printer_extruders_for_multiple_filaments + // fail to resolve the 2nd filament's variant - a benign fallback that spams [error] lines. A real + // 2-colour project ships filament_self_index = 1,2,...; mirror that so the sweep log stays clean. The + // slice output is unaffected: the duplicated filament's per-variant values are identical to the first. + if (auto *variants = cfg.option("filament_extruder_variant")) { + auto &self_index = cfg.option("filament_self_index", true)->values; + if (self_index.size() != variants->size()) { + self_index.resize(variants->size()); + for (size_t i = 0; i < self_index.size(); ++i) + self_index[i] = int(i) + 1; + } + } + return cfg; +} + +// Slice the current selection and log any failure against `what` (the printer, and the extra preset if +// any). With an outdir, the g-code is also saved there as ".gcode". Returns the g-code, or an +// empty string on failure. +std::string slice_selection(PresetBundle &bundle, const std::string &what, bool by_object, const std::string &outdir, const std::string &file_base) +{ + try { + const std::string out = slice_two_color_cube_and_export(slice_config(bundle), bundle.is_bbl_vendor(), by_object); + if (!outdir.empty() && !out.empty()) + save_string_file(fs::path(outdir) / (file_base + ".gcode"), out); + if (out.empty() || out.find("G1") == std::string::npos) { + BOOST_LOG_TRIVIAL(error) << what << " produced no g-code"; + return {}; + } + return out; + } catch (const std::exception &ex) { + BOOST_LOG_TRIVIAL(error) << what << " failed to slice: " << ex.what(); + return {}; + } +} + +// The templates a preset carries, as (key, text): every non-empty *_gcode text, and filename_format. Each +// value of a per-variant key counts, though a slice expands only the values of the variants its printer uses. +using Templates = std::set>; +Templates preset_templates(const DynamicPrintConfig &cfg) +{ + Templates out; + for (const std::string &key : cfg.keys()) { + if (key != "filename_format" && !boost::algorithm::ends_with(key, "_gcode")) + continue; + const ConfigOption *opt = cfg.option(key); + if (opt->type() == coString) { + if (const std::string &text = static_cast(opt)->value; !text.empty()) + out.emplace(key, text); + } else if (opt->type() == coStrings) { + for (const std::string &text : static_cast(opt)->values) + if (!text.empty()) + out.emplace(key, text); + } + } + return out; +} + // Slice-and-export a two-colour cube through every shipped printer (optionally scoped to one vendor via // -v). Unlike the static reference/placeholder checks, this expands every custom *_gcode - including // change_filament_gcode at the one filament change - against the printer's fully-resolved config, so -// undefined-placeholder / invalid-flow bugs surface here. Reports every offending printer and returns 1 -// if any failed, 0 otherwise. When outdir is non-empty, each printer's g-code is also written there as -// "__.gcode" for manual inspection. The sweep is SEQUENTIAL by necessity: -// Print::process() keeps process-global state, so slicing printers concurrently in one process races -// even with per-slice Model+Print. Load in validation mode so the vendors are read straight from the -p -// profiles dir (no data_dir/system tree) and -v scoping is honoured for free. +// undefined-placeholder / invalid-flow bugs surface here. PlaceholderParser::check_inactive_branches is +// set for the sweep, so the names in {if} branches a slice does not take must resolve too. +// +// Each printer is sliced with its own default process and filament. Every other compatible system +// process and filament whose templates (filename_format, filament_start_gcode, ...) no slice has expanded +// yet is then sliced once on that printer - a filament that compatible_prints limits to another process +// with that process - so each template text shipped in any system preset is expanded once. That check runs on the first compatible printer the sweep reaches only, in that printer's hook +// contexts: a value-dependent error on another printer, or a hook call site there that sets fewer +// variables (a multi-nozzle tool change, say), is not covered. The first printer shipping each +// printing_by_object_gcode also slices two cubes by object, the only way that hook fires. +// +// Reports every failure and returns 1 if any slice failed, 0 otherwise. When outdir is non-empty, each +// g-code is also written there as "__[__].gcode" for manual inspection. The +// sweep is SEQUENTIAL by necessity: Print::process() keeps process-global state, so slicing printers +// concurrently in one process races even with per-slice Model+Print. Load in validation mode so the +// vendors are read straight from the -p profiles dir (no data_dir/system tree) and -v scoping is honoured +// for free. int slice_all_printers(const std::string &vendor, const std::string &outdir) { install_slice_context_log_sink(); + PlaceholderParser::check_inactive_branches = true; if (!outdir.empty()) { boost::system::error_code ec; @@ -323,7 +458,16 @@ int slice_all_printers(const std::string &vendor, const std::string &outdir) std::cout << "Slicing " << printers.size() << " printer preset(s)" << (vendor.empty() ? "" : " for vendor " + vendor) << "..." << std::endl; - int failures = 0; + Templates covered; // the process and filament templates some slice has expanded + auto cover = [&covered](const Preset &preset) { + const Templates templates = preset_templates(preset.config); + covered.insert(templates.begin(), templates.end()); + }; + auto is_covered = [&covered](const Preset &preset) { + const Templates templates = preset_templates(preset.config); + return std::includes(covered.begin(), covered.end(), templates.begin(), templates.end()); + }; + int failures = 0, extra_processes = 0, extra_filaments = 0, by_object_slices = 0; for (const auto &[vendor_name, printer] : printers) { g_slice_context = vendor_name + " / " + printer; // tag every engine log line from this slice const bool selected = bundle.printers.select_preset_by_name(printer, /*force=*/true); @@ -347,76 +491,115 @@ int slice_all_printers(const std::string &vendor, const std::string &outdir) continue; } - // Grow to a 2nd filament so the cube can change colour; never shrink a multi-nozzle printer - // below its nozzle count, or full_config()'s flush-volume matrix no longer matches validate(). - const size_t nozzles = bundle.printers.get_selected_preset().config.option("nozzle_diameter")->size(); - bundle.set_num_filaments((unsigned int) std::max(2, nozzles)); - - // Mirror the app's manual filament->nozzle assignment for a multi-nozzle BBL printer: put each - // filament on its own nozzle and pin the map (fmmManual) so full_config() collapses every filament to - // the variant of the nozzle it actually prints from, and the engine keeps that assignment instead of - // auto-remapping it during process(). Without this the synthetic 2nd filament keeps nozzle 1's variant - // while the auto map moves it to nozzle 2 - harmless, but on the one printer whose nozzles differ in - // type (Direct Drive + Bowden) the mismatched lookup spams [error] lines. Single-nozzle and non-BBL - // printers keep the default map (their toolchange rides the AMS/tool-changer path unchanged). - const bool pin_filament_map = bundle.is_bbl_vendor() && nozzles > 1; - if (pin_filament_map) { - auto &fmap = bundle.project_config.option("filament_map", true)->values; - for (size_t i = 0; i < fmap.size(); ++i) - fmap[i] = int(i % nozzles) + 1; - } - - DynamicPrintConfig cfg = bundle.full_config(); - cfg.set_key_value("enable_prime_tower", new ConfigOptionBool(true)); // force a purge tower so the change is detectable - // The map above drives full_config()'s per-filament variant collapse; fmmManual on the sliced config - // stops process() from auto-remapping filaments back onto a different nozzle (which would re-introduce - // the variant mismatch this pinning avoids). - if (pin_filament_map) - cfg.set_key_value("filament_map_mode", new ConfigOptionEnum(fmmManual)); - - // full_config() grows filament_extruder_variant to one entry per filament, but because the synthetic - // 2nd filament is a duplicate of the first (set_num_filaments copies the same preset), it leaves - // filament_self_index at size 1. That makes update_values_to_printer_extruders_for_multiple_filaments - // fail to resolve the 2nd filament's variant - a benign fallback that spams [error] lines. A real - // 2-colour project ships filament_self_index = 1,2,...; mirror that so the sweep log stays clean. The - // slice output is unaffected: the duplicated filament's per-variant values are identical to the first. - if (auto *variants = cfg.option("filament_extruder_variant")) { - auto &self_index = cfg.option("filament_self_index", true)->values; - if (self_index.size() != variants->size()) { - self_index.resize(variants->size()); - for (size_t i = 0; i < self_index.size(); ++i) - self_index[i] = int(i) + 1; - } - } - - try { - const std::string out = slice_two_color_cube_and_export(cfg, bundle.is_bbl_vendor()); - if (!outdir.empty() && !out.empty()) { - const fs::path f = fs::path(outdir) / (sanitize_filename(vendor_name) + "__" + sanitize_filename(printer) + ".gcode"); - save_string_file(f, out); - } - if (out.empty() || out.find("G1") == std::string::npos) { - BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer << "\" produced no g-code"; - ++failures; - } else if (out.find("CP TOOLCHANGE START") == std::string::npos) { - // The filament change never rode the tower, so change_filament_gcode was not exercised. - BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer - << "\" sliced but the filament change never fired (no CP TOOLCHANGE START)"; - ++failures; - } - } catch (const std::exception &ex) { - BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer << "\" failed to slice: " << ex.what(); + const std::string print_name = bundle.prints.get_selected_preset_name(); + const std::string filament_name = bundle.filaments.get_selected_preset_name(); + const std::string what = "Printer \"" + printer + "\""; + const std::string file_base = sanitize_filename(vendor_name) + "__" + sanitize_filename(printer); + if (const std::string out = slice_selection(bundle, what, false, outdir, file_base); out.empty()) + ++failures; + else if (out.find("CP TOOLCHANGE START") == std::string::npos) { + // The filament change never rode the tower, so change_filament_gcode was not exercised. + BOOST_LOG_TRIVIAL(error) << what << " sliced but the filament change never fired (no CP TOOLCHANGE START)"; ++failures; } + cover(bundle.prints.get_selected_preset()); + cover(bundle.filaments.get_selected_preset()); + + const std::string &by_object_gcode = bundle.printers.get_selected_preset().config.opt_string("printing_by_object_gcode"); + if (!by_object_gcode.empty() && covered.emplace("printing_by_object_gcode", by_object_gcode).second) { + ++by_object_slices; + g_slice_context = vendor_name + " / " + printer + " / by object"; + if (slice_selection(bundle, what + " printing by object", true, outdir, file_base + "__by_object").empty()) + ++failures; + } + + // The first process of this printer that compatible_prints lets an otherwise incompatible filament + // use, judged as update_compatible() would with that process selected; empty if there is none. + const PresetWithVendorProfile printer_with_vendor = bundle.printers.get_edited_preset_with_vendor_profile(); + auto limiting_process = [&bundle, &printer_with_vendor](const Preset &filament) -> std::string { + const auto *processes = filament.config.option("compatible_prints"); + if (processes == nullptr || processes->values.empty()) + return {}; + const PresetWithVendorProfile filament_with_vendor = bundle.filaments.get_preset_with_vendor_profile(filament); + if (!is_compatible_with_printer(filament_with_vendor, printer_with_vendor)) + return {}; + for (const std::string &name : processes->values) + if (const Preset *process = bundle.prints.find_preset(name); + process != nullptr && process->is_visible && process->is_compatible && + is_compatible_with_print(filament_with_vendor, bundle.prints.get_preset_with_vendor_profile(*process), printer_with_vendor)) + return name; + return {}; + }; + // The compatibility flags are still this printer's, from update_compatible() above, which judged the + // filaments against the printer's own process. A hidden preset cannot be selected, so it is counted, + // not sliced. + std::vector> extras; // (extra preset, process to slice it with) + size_t hidden = 0; + for (const PresetCollection *presets : {&bundle.prints, &bundle.filaments}) + for (const Preset &preset : presets->get_presets()) { + if (!preset.is_system || preset.is_default) + continue; + std::string process; + if (preset.is_compatible) + process = preset.type == Preset::TYPE_PRINT ? preset.name : print_name; + else if (preset.type == Preset::TYPE_FILAMENT) + process = limiting_process(preset); + if (process.empty() || is_covered(preset)) + continue; + if (preset.is_visible) + extras.emplace_back(&preset, process); + else + ++hidden; + } + if (hidden > 0) + BOOST_LOG_TRIVIAL(warning) << "Printer \"" << printer << "\": " << hidden + << " compatible system preset(s) with unexpanded templates are hidden and were not sliced"; + + // Each extra slice swaps one preset into the printer's own selection. update_compatible() is not + // run again: it could swap filament slots. The filament change is not required to ride the tower + // here (a vase-mode process has none): the printer's own slice above already expanded its hooks. + for (const auto &[preset, process] : extras) { + if (is_covered(*preset)) + continue; // an earlier extra slice expanded the same texts + const bool is_print = preset->type == Preset::TYPE_PRINT; + const std::string &filament = is_print ? filament_name : preset->name; + std::string extra = std::string(is_print ? "process" : "filament") + " \"" + preset->name + "\""; + if (!is_print && process != print_name) + extra += " and process \"" + process + "\""; + g_slice_context = vendor_name + " / " + printer + " / " + extra; + if (is_print) + ++extra_processes; + else + ++extra_filaments; + cover(*preset); + bundle.prints.select_preset_by_name(process, /*force=*/true); + bundle.filaments.select_preset_by_name(filament, /*force=*/true); + bundle.filament_presets.assign(1, bundle.filaments.get_selected_preset_name()); + bundle.update_multi_material_filament_presets(); + // select_preset_by_name() falls back to another preset, and still returns true, when it cannot select this one. + if (bundle.prints.get_selected_preset_name() != process || bundle.filaments.get_selected_preset_name() != filament) { + BOOST_LOG_TRIVIAL(error) << what << " could not select " << extra; + ++failures; + continue; + } + if (slice_selection(bundle, what + " with " + extra, false, outdir, file_base + "__" + sanitize_filename(preset->name)).empty()) + ++failures; + } + // Leave the printer's own selection for the next printer to start from, as without the extra slices. + bundle.prints.select_preset_by_name(print_name, /*force=*/true); + bundle.filaments.select_preset_by_name(filament_name, /*force=*/true); } g_slice_context.clear(); + const int slices = int(printers.size()) + extra_processes + extra_filaments + by_object_slices; + std::cout << "Sliced " << printers.size() << " printer preset(s), " << extra_processes << " more process preset(s), " + << extra_filaments << " more filament preset(s) and " << by_object_slices << " printer(s) by object" << std::endl; if (failures > 0) { - std::cout << failures << " of " << printers.size() << " printer preset(s) failed to slice" << std::endl; + std::cout << failures << " of " << slices << " slice(s) failed" << std::endl; std::cout << "Validation failed" << std::endl; return 1; } - std::cout << "All " << printers.size() << " printer preset(s) sliced successfully" << std::endl; + std::cout << "All " << slices << " slice(s) succeeded" << std::endl; std::cout << "Validation completed successfully" << std::endl; return 0; } @@ -435,8 +618,8 @@ int main(int argc, char* argv[]) #endif ("vendor,v", po::value()->default_value(""), "Vendor name. Optional, all profiles present in the folder will be validated if not specified") ("generate_presets,g", po::value()->default_value(false), "Generate user presets for mock test") - ("slice,s", po::bool_switch()->default_value(false), "Slice a two-colour cube through every printer to expand all custom g-code (catches placeholder/flow errors that static checks miss). Off unless this flag is present.") - ("outdir,o", po::value()->default_value(""), "With -s, also save each printer's g-code to this folder (as __.gcode) for manual inspection. Optional.") + ("slice,s", po::bool_switch()->default_value(false), "Slice a two-colour cube through every printer, and through every other system process and filament preset whose templates no printer's own slice expands, so every custom g-code and filename_format shipped is expanded, names in {if} branches not taken included (catches placeholder/flow errors that static checks miss). Off unless this flag is present.") + ("outdir,o", po::value()->default_value(""), "With -s, also save each slice's g-code to this folder (as __[__].gcode) for manual inspection. Optional.") ("check_filament_subtypes,f", po::bool_switch()->default_value(true), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.") ("log_level,l", po::value()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs."); // clang-format on diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index cdcd9b4dec..d67b48c981 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -511,6 +511,10 @@ void AppConfig::set_defaults() set_bool("enable_high_low_temp_mixed_printing", false); } + if (get("remember_print_action").empty()) { + set_bool("remember_print_action", false); + } + if (get("ignore_ext_filament_in_filament_map").empty()){ set_bool("ignore_ext_filament_in_filament_map", false); } diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 9cee5a0e4b..8ba4dfb596 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -131,6 +131,7 @@ double getadhesionCoeff(const PrintObject* printObject) } double adhesionCoeff = 1; for (const ModelVolume* modelVolume : objectVolumes) { + if (modelVolume->is_precise_seam()) continue; // non-printing helper geometry for (auto iter = extrudersFirstLayer.begin(); iter != extrudersFirstLayer.end(); iter++) { if (modelVolume->extruder_id() == *iter) { if (Model::extruderParamsMap.find(modelVolume->extruder_id()) != Model::extruderParamsMap.end()) { diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index e734c036fa..1857412466 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -259,6 +259,8 @@ set(lisbslic3r_sources GCode/RetractWhenCrossingPerimeters.hpp GCode/SeamPlacer.cpp GCode/SeamPlacer.hpp + GCode/PreciseSeam.cpp + GCode/PreciseSeam.hpp #GCodeSender.cpp #GCodeSender.hpp GCode/SmallAreaInfillFlowCompensator.cpp @@ -353,6 +355,7 @@ set(lisbslic3r_sources Optimize/Optimizer.hpp Orient.cpp Orient.hpp + ParallelResolve.hpp ParameterUtils.cpp ParameterUtils.hpp pchheader.cpp @@ -477,6 +480,30 @@ set(lisbslic3r_sources Tesselate.cpp Tesselate.hpp TextConfiguration.hpp + TextureDisplacement.cpp + TextureDisplacement.hpp + TextureBake/TextureBakeIndex.cpp + TextureBake/TextureBakeIndex.hpp + TextureBake/TextureBakeSubdivide.cpp + TextureBake/TextureBakeSubdivide.hpp + TextureBake/TextureBakeRegularize.cpp + TextureBake/TextureBakeRegularize.hpp + TextureBake/TextureBakeRelocate.cpp + TextureBake/TextureBakeRelocate.hpp + TextureBake/TextureBakeFlip.cpp + TextureBake/TextureBakeFlip.hpp + TextureBake/TextureBakeDebug.cpp + TextureBake/TextureBakeDebug.hpp + TextureBake/TextureBakeDisplace.cpp + TextureBake/TextureBakeDisplace.hpp + TextureBake/TextureBakeDecimate.cpp + TextureBake/TextureBakeDecimate.hpp + TextureBake/TextureBakeRepair.cpp + TextureBake/TextureBakeRepair.hpp + TextureBake/TextureBakePipeline.cpp + TextureBake/TextureBakePipeline.hpp + TextureBake/TextureBakeMesh.cpp + TextureBake/TextureBakeMesh.hpp Thread.cpp Thread.hpp Time.cpp diff --git a/src/libslic3r/Color.hpp b/src/libslic3r/Color.hpp index cd1e82d794..3f93dc9194 100644 --- a/src/libslic3r/Color.hpp +++ b/src/libslic3r/Color.hpp @@ -6,6 +6,8 @@ #include #include +#include + namespace Slic3r { using RGB = std::array; using RGBA = std::array; diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 42d6970ad1..427f6e66c9 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -849,6 +849,19 @@ ConfigSubstitutions ConfigBase::load_from_json(const std::string &file, ForwardC return std::move(substitutions_ctxt.substitutions); } +// Case-insensitive compare of a JSON key against a fixed ASCII one, without +// boost::iequals, whose std::locale() takes a lock the whole process shares in the +// MSVC runtime. +static bool ascii_iequals(const std::string &key, const char *literal) +{ + auto lower = [](char c) { return (c >= 'A' && c <= 'Z') ? char(c - 'A' + 'a') : c; }; + size_t i = 0; + for (; i < key.size() && literal[i] != '\0'; ++ i) + if (lower(key[i]) != lower(literal[i])) + return false; + return i == key.size() && literal[i] == '\0'; +} + int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContext& substitution_context, bool load_inherits_to_config, std::map& key_values, std::string& reason) { json j; @@ -916,44 +929,44 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex } //parse the json elements for (auto it = j.begin(); it != j.end(); it++) { - if (boost::iequals(it.key(),BBL_JSON_KEY_VERSION)) { + if (ascii_iequals(it.key(), BBL_JSON_KEY_VERSION)) { key_values.emplace(BBL_JSON_KEY_VERSION, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_IS_CUSTOM)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_IS_CUSTOM)) { //skip it } - else if (boost::iequals(it.key(), BBL_JSON_KEY_NAME)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_NAME)) { key_values.emplace(BBL_JSON_KEY_NAME, it.value()); if (it.value() == "project_settings") is_project_settings = true; } - else if (boost::iequals(it.key(), BBL_JSON_KEY_URL)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_URL)) { key_values.emplace(BBL_JSON_KEY_URL, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_TYPE)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_TYPE)) { key_values.emplace(BBL_JSON_KEY_TYPE, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_SETTING_ID)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_SETTING_ID)) { key_values.emplace(BBL_JSON_KEY_SETTING_ID, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_FILAMENT_ID)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_FILAMENT_ID)) { key_values.emplace(BBL_JSON_KEY_FILAMENT_ID, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_FROM)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_FROM)) { key_values.emplace(BBL_JSON_KEY_FROM, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_DESCRIPTION)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_DESCRIPTION)) { key_values.emplace(BBL_JSON_KEY_DESCRIPTION, it.value()); } - else if (boost::iequals(it.key(), BBL_JSON_KEY_INSTANTIATION)) { + else if (ascii_iequals(it.key(), BBL_JSON_KEY_INSTANTIATION)) { key_values.emplace(BBL_JSON_KEY_INSTANTIATION, it.value()); } - else if (!load_inherits_to_config && boost::iequals(it.key(), BBL_JSON_KEY_INHERITS)) { + else if (!load_inherits_to_config && ascii_iequals(it.key(), BBL_JSON_KEY_INHERITS)) { key_values.emplace(BBL_JSON_KEY_INHERITS, it.value()); } - else if (!load_inherits_to_config && boost::iequals(it.key(), BBL_JSON_KEY_INCLUDES)) { + else if (!load_inherits_to_config && ascii_iequals(it.key(), BBL_JSON_KEY_INCLUDES)) { key_values.emplace(BBL_JSON_KEY_INCLUDES, it.value().dump()); - } else if (boost::iequals(it.key(), ORCA_JSON_KEY_RENAMED_FROM)) { + } else if (ascii_iequals(it.key(), ORCA_JSON_KEY_RENAMED_FROM)) { key_values.emplace(ORCA_JSON_KEY_RENAMED_FROM, it.value()); } else { t_config_option_key opt_key = it.key(); diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 52b16f9458..9818887c1d 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -2702,6 +2702,9 @@ public: virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) = 0; // Collect names of all configuration values maintained by this configuration store. virtual t_config_option_keys keys() const = 0; + // Set this config's options on target member by member, when target is of this config's static type or + // derives from it, and return true. apply() prefers this to looking every key up by name. + virtual bool apply_to(ConfigBase &/*target*/) const { return false; } protected: // Verify whether the opt_key has not been obsoleted or renamed. @@ -2753,7 +2756,8 @@ public: // Apply all keys of other ConfigBase defined by this->def() to this ConfigBase. // An UnknownOptionException is thrown in case some option keys of other are not defined by this->def(), // or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set. - void apply(const ConfigBase &other, bool ignore_nonexistent = false) { this->apply_only(other, other.keys(), ignore_nonexistent); } + void apply(const ConfigBase &other, bool ignore_nonexistent = false) + { if (! other.apply_to(*this)) this->apply_only(other, other.keys(), ignore_nonexistent); } // Apply explicitely enumerated keys of other ConfigBase defined by this->def() to this ConfigBase. // An UnknownOptionException is thrown in case some option keys are not defined by this->def(), // or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set. diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index c740dd2b4b..c9a108573d 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "FillBase.hpp" #include "FillGyroid.hpp" @@ -123,44 +124,41 @@ static inline double f(double x, double z_sin, double z_cos, bool vertical, bool } } +// Repeats one period of a wave from the last sample at or before x_min to the first one at or after x_max. static inline Polyline make_wave( - const std::vector& one_period, double width, double height, double offset, double scaleFactor, - double z_cos, double z_sin, bool vertical, bool flip) + const std::vector& one_period, double x_min, double x_max, double offset, double scaleFactor, bool vertical) { - std::vector points = one_period; - double period = points.back()(0); - if (width != period) // do not extend if already truncated - { - points.reserve(one_period.size() * size_t(floor(width / period))); - points.pop_back(); + const double period = one_period.back().x(); + // The last sample of a period is the first one of the next. + const size_t n = one_period.size() - 1; + double x0 = std::floor(x_min / period) * period; + size_t i = 0; + while (i + 1 < n && x0 + one_period[i + 1].x() <= x_min) + ++i; - size_t n = points.size(); - do { - points.emplace_back(points[points.size()-n].x() + period, points[points.size()-n].y()); - } while (points.back()(0) < width - EPSILON); - - points.emplace_back(Vec2d(width, f(width, z_sin, z_cos, vertical, flip))); - } - - // and construct the final polyline to return: Polyline polyline; - polyline.points.reserve(points.size()); - for (auto& point : points) { - point(1) += offset; - point(1) = std::clamp(double(point.y()), 0., height); + polyline.points.reserve(size_t((x_max - x0) / period + 1.) * n + 1); + for (;;) { + Vec2d point(x0 + one_period[i].x(), one_period[i].y() + offset); + const bool last = point.x() >= x_max; if (vertical) std::swap(point(0), point(1)); polyline.points.emplace_back((point * scaleFactor).cast()); + if (last) + break; + if (++i == n) { + i = 0; + x0 += period; + } } - return polyline; } -static std::vector make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip, double tolerance) +static std::vector make_one_period(double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip, double tolerance) { std::vector points; double dx = M_PI_2; // exact coordinates on main inflexion lobes - double limit = std::min(2*M_PI, width); + double limit = 2*M_PI; points.reserve(coord_t(ceil(limit / tolerance / 3))); for (double x = 0.; x < limit - EPSILON; x += dx) { @@ -239,7 +237,8 @@ static inline double compute_omega_factor(double density_adjusted, double line_s return std::clamp(raw, 1.0, 2.0); } -static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height) +// Waves covering bbox, with the pattern anchored at origin. +static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, const BoundingBox &bbox, const Point &origin) { const double scaleFactor = scale_(line_spacing) / density_adjusted; @@ -254,29 +253,36 @@ static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double const double z_cos = cos(z); bool vertical = (std::abs(z_sin) <= std::abs(z_cos)); + // Range to cover in pattern units, with the waves running along x. + Vec2d lo = (bbox.min - origin).cast() / scaleFactor; + Vec2d hi = (bbox.max - origin).cast() / scaleFactor; double lower_bound = 0.; - double upper_bound = height; bool flip = true; if (vertical) { flip = false; lower_bound = -M_PI; - upper_bound = width - M_PI_2; - std::swap(width,height); + std::swap(lo(0), lo(1)); + std::swap(hi(0), hi(1)); } - std::vector one_period_odd = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip, tolerance); // creates one period of the waves, so it doesn't have to be recalculated all the time + std::vector one_period_odd = make_one_period(scaleFactor, z_cos, z_sin, vertical, flip, tolerance); // creates one period of the waves, so it doesn't have to be recalculated all the time flip = !flip; // even polylines are a bit shifted - std::vector one_period_even = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip, tolerance); - Polylines result; + std::vector one_period_even = make_one_period(scaleFactor, z_cos, z_sin, vertical, flip, tolerance); - for (double y0 = lower_bound; y0 < upper_bound + EPSILON; y0 += M_PI) { - // creates odd polylines - result.emplace_back(make_wave(one_period_odd, width, height, y0, scaleFactor, z_cos, z_sin, vertical, flip)); - // creates even polylines - y0 += M_PI; - if (y0 < upper_bound + EPSILON) { - result.emplace_back(make_wave(one_period_even, width, height, y0, scaleFactor, z_cos, z_sin, vertical, flip)); + // Every wave spans [offset + f_min, offset + f_max] across. + double f_min = std::numeric_limits::max(); + double f_max = std::numeric_limits::lowest(); + for (const std::vector *one_period : { &one_period_odd, &one_period_even }) + for (const Vec2d &point : *one_period) { + f_min = std::min(f_min, point.y()); + f_max = std::max(f_max, point.y()); } + + Polylines result; + for (int i = int(std::ceil((lo.y() - f_max - lower_bound) / M_PI)); lower_bound + i * M_PI + f_min <= hi.y(); ++i) { + Polyline &wave = result.emplace_back(make_wave(i % 2 == 0 ? one_period_odd : one_period_even, lo.x(), hi.x(), + lower_bound + i * M_PI, scaleFactor, vertical)); + wave.translate(origin); } return result; @@ -302,12 +308,12 @@ void FillGyroid::_fill_surface_single( // Distance between the gyroid waves in scaled coordinates. coord_t distance = coord_t(scale_(this->spacing) / density_adjusted); - // align bounding box to a multiple of our grid module - bb.merge(align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance))); + // Anchor the pattern to our grid module; the 10-line shift keeps its established phase. + const coord_t shift = coord_t(10 * scale_(this->spacing)); + const Point origin = align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance)) - Point(shift, shift); - // Expand the bounding box to avoid artifacts at the edges - coord_t expand = 10 * (scale_(this->spacing)); - bb.offset(expand); + // Keep the pattern ends and the multiline copies outside the contour. + bb.offset(scale_(this->spacing * params.multiline)); // generate pattern Polylines polylines; @@ -327,23 +333,14 @@ void FillGyroid::_fill_surface_single( const float density_factor = std::max(0.001f, float(params.density * DensityAdjust / params.multiline)); const float period = float(2.0 * M_PI) * float(this->spacing) / density_factor; - // bb is already expanded above by 10 * scale_(spacing) for edge artifacts; - // skip a second offset here to avoid raster-area bloat in the marching squares pass. + // A cell of margin for the rings closed along the raster border, and a fixed sampling grid for every region. + const coord_t cell = scaled(marchsq::GyroidField::gsizef); + bb.offset(cell); + bb.merge(align_to_grid(bb.min, Point(cell, cell))); marchsq::GyroidField sf(bb, this->z, period, float(omega)); polylines = marchsq::get_gyroid_polylines(sf, SCALED_SPARSE_INFILL_RESOLUTION); } else { - polylines = make_gyroid_waves( - scale_(this->z), - density_adjusted, - this->spacing, - ceil(bb.size()(0) / distance) + 1., - ceil(bb.size()(1) / distance) + 1.); - - // The parametric generator produces wave coords relative to the grid origin; - // shift them into absolute layer coords. The marching-squares branch above - // already emits absolute coords via GyroidField::to_Point, so it skips this. - for (Polyline &pl : polylines) - pl.translate(bb.min); + polylines = make_gyroid_waves(scale_(this->z), density_adjusted, this->spacing, bb, origin); } // Apply multiline offset if needed diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 55ae50f9bb..998cfd9a7e 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -3094,7 +3094,6 @@ static std::vector cubic_upper_level(double tau, double h, double period, bool FillRectilinear::fill_surface_trapezoidal( const Surface* surface, FillParams params, - const std::initializer_list& sweep_params, Polylines& polylines_out, int Pattern_type) // 0=grid, 1=triangular, 2=stars, 3=cubic { @@ -3126,9 +3125,20 @@ bool FillRectilinear::fill_surface_trapezoidal( expolygon.rotate(-base_angle, rotate_vector.second); } - // Use extended object bounding box for consistent pattern across layers - BoundingBox bb = this->extended_object_bounding_box(); const size_t infill_layer_id = (surface->thickness_layers > 0) ? this->layer_id / surface->thickness_layers : this->layer_id; + // The triangular family turns by 120 degrees every layer, about the origin of the frame it is built in. + const size_t layer_mod = infill_layer_id % 3; + const double angle = layer_mod * 2.0 * M_PI / 3.0; + + // Only build the rows over the surface, seen in the frame they are built in. + Polygon local = expolygon.contour; + if (Pattern_type != 0) { + local.translate(-rotate_vector.second.x(), -rotate_vector.second.y()); + if (layer_mod) + local.rotate(-angle); + } + BoundingBox cover = get_extents(local); + cover.offset(period); switch (Pattern_type) { case 0: // Grid / Trapezoidal @@ -3148,21 +3158,31 @@ bool FillRectilinear::fill_surface_trapezoidal( // Align bounding box to the grid, phased through the box center so separated infills align // each part on itself (grid_center is the origin for a standalone object / feature off). // Captured before the merge, which grows bb and would otherwise shift its center. + BoundingBox bb = this->extended_object_bounding_box(); const Point grid_center = bb.center(); bb.merge(align_to_grid(bb.min, Point(period, period), grid_center)); const coord_t xmin = bb.min.x(); - const coord_t xmax = bb.max.x(); const coord_t ymin = bb.min.y(); - const coord_t ymax = bb.max.y(); + + auto transpose = [&grid_center](const Point &p) { + return Point(grid_center.x() + p.y() - grid_center.y(), grid_center.y() + p.x() - grid_center.x()); + }; + if (infill_layer_id % 2 == 1) + cover = BoundingBox(transpose(cover.min), transpose(cover.max)); + const coord_t row_spacing = period / 2; + const coord_t first_x = xmin + (coord_t(std::floor(double(cover.min.x() - xmin) / period)) - 1) * period; + const coord_t last_x = xmin + (coord_t(std::ceil(double(cover.max.x() - xmin) / period)) + 1) * period; + const coord_t first_row = coord_t(std::floor(double(cover.min.y() - ymin) / row_spacing)) - 1; + const coord_t last_row = coord_t(std::ceil(double(cover.max.y() - ymin) / row_spacing)) + 1; // Create the two base row patterns once Polyline base_row_normal; - base_row_normal.points.reserve(((xmax - xmin) / period + 1) * 5); // 5 points per trapezoid + base_row_normal.points.reserve(((last_x - first_x) / period + 1) * 5); // 5 points per trapezoid Polyline base_row_flipped; - base_row_flipped.points.reserve(((xmax - xmin) / period + 1) * 5); // 5 points per trapezoid + base_row_flipped.points.reserve(((last_x - first_x) / period + 1) * 5); // 5 points per trapezoid - // Build complete rows from xmin to xmax - for (coord_t x = xmin; x < xmax; x += period) { + // Build rows on the same global period grid, limited to the surface cover. + for (coord_t x = first_x; x < last_x; x += period) { // Normal row base_row_normal.points.emplace_back(Point(x, d1 / 2)); // P0 base_row_normal.points.emplace_back(Point(x + d1 / 2, d1 / 2)); // P1 @@ -3178,13 +3198,14 @@ bool FillRectilinear::fill_surface_trapezoidal( } // Pre-allocate polylines - const size_t estimated_rows = ((ymax - ymin) / (period / 2) + 1); + const size_t estimated_rows = size_t(last_row - first_row + 1); polylines.reserve(estimated_rows); - bool flip_vertical = false; + bool flip_vertical = (first_row % 2) != 0; - // Now just copy and translate vertically - for (coord_t y = ymin; y < ymax; y += period / 2) { + // Copy and translate only rows intersecting the surface cover. + for (coord_t row = first_row; row <= last_row; ++row) { + const coord_t y = ymin + row * row_spacing; Polyline pl_row = flip_vertical ? base_row_flipped : base_row_normal; // Translate all points vertically @@ -3200,16 +3221,10 @@ bool FillRectilinear::fill_surface_trapezoidal( // Orca: mirror across the diagonal through grid_center (not the origin), so the swapped // layers stay aligned with the center-phased grid. For a standalone object / feature off, // grid_center is the origin and this is a plain x/y swap. - if (infill_layer_id % 2 == 1) { - for (Polyline& pl : polylines) { - for (Point& p : pl.points) { - const coord_t dx = p.x() - grid_center.x(); - const coord_t dy = p.y() - grid_center.y(); - p.x() = grid_center.x() + dy; - p.y() = grid_center.y() + dx; - } - } - } + if (infill_layer_id % 2 == 1) + for (Polyline& pl : polylines) + for (Point& p : pl.points) + p = transpose(p); break; } @@ -3230,40 +3245,24 @@ bool FillRectilinear::fill_surface_trapezoidal( const coord_t d2_tri = coord_t(2.0 / std::sqrt(3.0) * d1); const coord_t h = coord_t(0.5 * std::sqrt(3.0) * period); // height of triangle - // Align bounding box to the grid - bb.merge(align_to_grid(bb.center(), Point(period,h))); - const size_t layer_mod = infill_layer_id % 3; - const double angle = layer_mod * 2.0 * M_PI / 3.0; - - const Point rotation_center = bb.center(); - const coord_t half_w = bb.size().x() / 2; - const coord_t half_h = bb.size().y() / 2; - - // Compute how many full periods fit in each direction - const coord_t num_periods_x = coord_t(std::ceil(half_w / double(period))); - coord_t num_periods_y =coord_t(std::ceil(half_h / double(h))); - // Ensure an even number of rows so the pattern stays centered - if ((num_periods_y % 2) != 0) - ++num_periods_y; - - // Compute aligned limits (symmetric around the origin) - const coord_t x_min_aligned = -num_periods_x * period; - const coord_t x_max_aligned = num_periods_x * period; - const coord_t y_min_aligned = -num_periods_y * h; - const coord_t y_max_aligned = num_periods_y * h; + // Keep the existing origin-anchored lattice, but generate only nearby tiles. + const coord_t x_min_aligned = (coord_t(std::floor(double(cover.min.x()) / period)) - 1) * period; + const coord_t x_max_aligned = (coord_t(std::ceil(double(cover.max.x()) / period)) + 1) * period; + const coord_t first_row = coord_t(std::floor(double(cover.min.y()) / h)) - 1; + const coord_t last_row = coord_t(std::ceil(double(cover.max.y()) / h)) + 1; // Pre-allocate estimated number of polylines - const size_t estimated_rows = (y_max_aligned - y_min_aligned) / h + 2; - const size_t estimated_polylines = (estimated_rows + 1) * 2; // base line + trapezoid line per row + const size_t estimated_rows = size_t(last_row - first_row + 1); + const size_t estimated_polylines = estimated_rows * 2; // base line + trapezoid line per row polylines.reserve(estimated_polylines); // Create the two base row templates once Polyline base_line_template; base_line_template.points.reserve(2); // 2 points for base line Polyline trapezoid_row_normal; - trapezoid_row_normal.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 5); // 5 points per trapezoid + trapezoid_row_normal.points.reserve(((x_max_aligned - x_min_aligned) / period) * 5); // 5 points per trapezoid Polyline trapezoid_row_shifted; - trapezoid_row_shifted.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 5); // 5 points per trapezoid + trapezoid_row_shifted.points.reserve(((x_max_aligned - x_min_aligned) / period) * 5); // 5 points per trapezoid // Build base line template (from x_min_aligned to x_max_aligned) base_line_template.points.emplace_back(Point(x_min_aligned, 0)); base_line_template.points.emplace_back(Point(x_max_aligned, 0)); @@ -3283,10 +3282,10 @@ bool FillRectilinear::fill_surface_trapezoidal( for (auto& p : trapezoid_row_shifted.points) p.y() = h - p.y(); - bool shift_row = false; - // Generate pattern by copying and translating templates vertically - for (coord_t y = y_min_aligned; y < y_max_aligned; y += h) { + bool shift_row = (first_row % 2) != 0; + for (coord_t row = first_row; row <= last_row; ++row) { + const coord_t y = row * h; // Base line - copy and translate Polyline base_line = base_line_template; for (Point& p : base_line.points) { @@ -3306,12 +3305,6 @@ bool FillRectilinear::fill_surface_trapezoidal( shift_row = !shift_row; } - - // Rotate around origin (0,0) - if (layer_mod) - for (auto& pl : polylines) - pl.rotate(angle, Point(0,0)); - break; } @@ -3325,36 +3318,25 @@ bool FillRectilinear::fill_surface_trapezoidal( const coord_t d1_half_base = d1_half / std::sqrt(3.0); const coord_t half_period = period / 2; const coord_t quarter_period = period / 4; + const coord_t row_y_offset = tri_height - (2 * tri_height) / 3; - bb.merge(align_to_grid(bb.center(), Point(period, tri_height))); - const size_t layer_mod = infill_layer_id % 3; - const double angle = layer_mod * 2.0 * M_PI / 3.0; + // Keep the lattice anchored at the origin while generating only tiles around this surface. + const int64_t first_tile = int64_t(std::floor(double(cover.min.x()) / period)) - 1; + const int64_t last_tile = int64_t(std::ceil(double(cover.max.x()) / period)) + 1; + const int64_t first_row = int64_t(std::floor(double(cover.min.y() - row_y_offset) / hex_height)) - 1; + const int64_t last_row = int64_t(std::ceil(double(cover.max.y() - row_y_offset) / hex_height)) + 1; - const coord_t half_w = bb.size().x() / 2; - const coord_t half_h = bb.size().y() / 2; - - const coord_t num_periods_x = coord_t(std::ceil(half_w / double(period))); - coord_t num_periods_y = coord_t(std::ceil(half_h / double(hex_height))); - if ((num_periods_y % 2) != 0) - ++num_periods_y; - - const coord_t x_alignment_shift = half_period; - const coord_t y_alignment_shift = (2 * tri_height) / 3; - const coord_t x_min_aligned = -num_periods_x * period - x_alignment_shift; - const coord_t x_max_aligned = num_periods_x * period - x_alignment_shift; - const coord_t y_min_aligned = -num_periods_y * hex_height - y_alignment_shift; - const coord_t y_max_aligned = num_periods_y * hex_height - y_alignment_shift; - - const size_t estimated_rows = (y_max_aligned - y_min_aligned) / hex_height + 2; - const size_t estimated_polylines = (estimated_rows + 1) * 2; + const size_t estimated_rows = size_t(last_row - first_row + 1); + const size_t estimated_polylines = estimated_rows * 2; polylines.reserve(estimated_polylines); Polyline star_row_normal; - star_row_normal.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 7); + star_row_normal.points.reserve(size_t(last_tile - first_tile) * 7); Polyline star_row_mirrored; - star_row_mirrored.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 7); + star_row_mirrored.points.reserve(size_t(last_tile - first_tile) * 7); - for (coord_t x = x_min_aligned; x < x_max_aligned; x += period) { + for (int64_t tile = first_tile; tile < last_tile; ++tile) { + const coord_t x = coord_t(tile * period) - half_period; star_row_normal.points.emplace_back(Point(x, hex_height)); // P0 star_row_normal.points.emplace_back(Point(x + quarter_period - d1, hex_height)); // P1 star_row_normal.points.emplace_back(Point(x + quarter_period + d1_half, hex_height - chamfer_height)); // P2 @@ -3368,9 +3350,7 @@ bool FillRectilinear::fill_surface_trapezoidal( for (auto& p : star_row_mirrored.points) p.y() = hex_height - p.y(); - size_t pair_idx = 0; const coord_t global_x_shift = half_period; - const coord_t global_y_shift = tri_height; auto append_row_with_shift = [&polylines](const Polyline& row_template, coord_t x_shift, coord_t y_shift) { Polyline row = row_template; for (Point& p : row.points) { @@ -3381,16 +3361,12 @@ bool FillRectilinear::fill_surface_trapezoidal( polylines.emplace_back(std::move(row)); }; - for (coord_t y = y_min_aligned; y < y_max_aligned; y += hex_height, ++pair_idx) { - const coord_t x_shift = (pair_idx % 2 == 0) ? 0 : half_period; - append_row_with_shift(star_row_normal, x_shift + global_x_shift, y + global_y_shift); - append_row_with_shift(star_row_mirrored, x_shift + global_x_shift, y + global_y_shift); + for (int64_t row = first_row; row <= last_row; ++row) { + const coord_t y = coord_t(row * hex_height) + row_y_offset; + const coord_t x_shift = (row % 2 == 0) ? 0 : half_period; + append_row_with_shift(star_row_normal, x_shift + global_x_shift, y); + append_row_with_shift(star_row_mirrored, x_shift + global_x_shift, y); } - - if (layer_mod) - for (auto& pl : polylines) - pl.rotate(angle, Point(0, 0)); - break; } @@ -3407,19 +3383,9 @@ bool FillRectilinear::fill_surface_trapezoidal( for (Vec2d &p : levels.front()) p.y() = h - p.y(); - const size_t layer_mod = infill_layer_id % 3; - const double angle = layer_mod * 2.0 * M_PI / 3.0; - - // Only cover the surface, seen in the frame the pattern is built in. - ExPolygon local = expolygon; - local.translate(-rotate_vector.second.x(), -rotate_vector.second.y()); - if (layer_mod) - local.rotate(-angle); - BoundingBox cover = get_extents(local); - cover.offset(period); - const int64_t n_min = int64_t(std::floor((cover.min.y() - y0) / h)) - 1; const int64_t n_max = int64_t(std::ceil((cover.max.y() - y0) / h)) + 1; + polylines.reserve(size_t(n_max - n_min + 1) * levels.size()); for (int64_t n = n_min; n <= n_max; ++n) { const double x_off = (n & 1) ? 0.5 * period : 0.; const double base = y0 + double(n) * h - tau; @@ -3435,11 +3401,6 @@ bool FillRectilinear::fill_surface_trapezoidal( polylines.emplace_back(std::move(row)); } } - - if (layer_mod) - for (Polyline &pl : polylines) - pl.rotate(angle, Point(0, 0)); - break; } @@ -3448,21 +3409,38 @@ bool FillRectilinear::fill_surface_trapezoidal( break; } - // Orca: cases 1 & 2 build the pattern symmetrically around the origin, so on their own they - // phase to the global origin and every part shares one grid. Shift the pattern onto the box - // center this->bounding_box carries, so separated infills align each part on itself. The center - // is the origin for a standalone object (or when the feature is off), making this a no-op there. + // Orca: cases 1 to 3 anchor the pattern at the origin, so on their own they phase to the global + // origin and every part shares one grid. Shift the pattern onto the box center + // this->bounding_box carries, so separated infills align each part on itself. The center is the + // origin for a standalone object (or when the feature is off), making the shift a no-op there. if (Pattern_type != 0) - for (Polyline &pl : polylines) + for (Polyline &pl : polylines) { + if (layer_mod) + pl.rotate(angle, Point(0, 0)); pl.translate(rotate_vector.second); + } // Orca: round the corners of the trapezoids. The straight base lines of the triangular family // have no corner to round. smooth_polylines_corners(polylines, params.smooth_factor, scaled(params.resolution)); + // Only the centerlines within d1 / 2 of the surface have outlines reaching it. + polylines = intersection_pl(std::move(polylines), offset(expolygon, float(d1 / 2))); + // Apply multiline fill multiline_fill(polylines, params, spacing); + // Start each outline on the cap at the first end of its path, outside the surface, so clipping splits it only there. + const Vec2d row_dir = Pattern_type != 0 ? Vec2d(std::cos(angle), std::sin(angle)) : infill_layer_id % 2 ? Vec2d::UnitY() : Vec2d::UnitX(); + for (Polyline &pl : polylines) + if (pl.size() > 3 && pl.first_point() == pl.last_point()) { + pl.points.pop_back(); + std::rotate(pl.points.begin(), std::min_element(pl.points.begin(), pl.points.end(), [&row_dir](const Point &a, const Point &b) { + return row_dir.dot(a.cast()) < row_dir.dot(b.cast()); + }), pl.points.end()); + pl.points.emplace_back(pl.points.front()); + } + // Contract surface polygon by half line width to avoid excesive overlap with perimeter ExPolygons contracted = offset_ex(expolygon, -float(scale_(0.5 * this->spacing))); @@ -3545,9 +3523,7 @@ Polylines FillGrid::fill_surface(const Surface *surface, const FillParams ¶m if (params.multiline > 1) { // Experimental trapezoidal grid if (!this->fill_surface_trapezoidal( - surface, params, - { { 0.f, 0.f }, { float(M_PI / 2.), 0.f } }, - polylines_out,0)) + surface, params, polylines_out, 0)) BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface_trapezoidal() failed."; } else { @@ -3587,9 +3563,7 @@ Polylines FillTriangles::fill_surface(const Surface *surface, const FillParams & if (params.multiline > 1) { // Experimental trapezoidal grid if (!this->fill_surface_trapezoidal( - surface, params, - { { 0.f, 0.f }, { float(M_PI / 2.), 0.f } }, - polylines_out,1)) + surface, params, polylines_out, 1)) BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface_trapezoidal() failed."; } else { @@ -3608,9 +3582,7 @@ Polylines FillStars::fill_surface(const Surface *surface, const FillParams ¶ Polylines polylines_out; if (params.multiline > 1) { if (!this->fill_surface_trapezoidal( - surface, params, - {{0.f, 0.f}, {float(M_PI / 3.), 0.f}, {float(2. * M_PI / 3.), float((3. / 2.) * this->spacing * params.multiline / params.density)}}, - polylines_out, 2)) + surface, params, polylines_out, 2)) BOOST_LOG_TRIVIAL(error) << "FillStars::fill_surface_trapezoidal() failed."; } else { if (! this->fill_surface_by_multilines( @@ -3626,7 +3598,7 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams ¶ { Polylines polylines_out; if (params.multiline > 1) { - if (!this->fill_surface_trapezoidal(surface, params, {}, polylines_out, 3)) + if (!this->fill_surface_trapezoidal(surface, params, polylines_out, 3)) BOOST_LOG_TRIVIAL(error) << "FillCubic::fill_surface_trapezoidal() failed."; return polylines_out; } diff --git a/src/libslic3r/Fill/FillRectilinear.hpp b/src/libslic3r/Fill/FillRectilinear.hpp index 126cbe3a15..adb9ef5131 100644 --- a/src/libslic3r/Fill/FillRectilinear.hpp +++ b/src/libslic3r/Fill/FillRectilinear.hpp @@ -29,7 +29,7 @@ protected: float pattern_shift; }; bool fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list &sweep_params, Polylines &polylines_out); - bool fill_surface_trapezoidal(const Surface *surface, FillParams params, const std::initializer_list &sweep_params, Polylines &polylines_out,int Pattern_type); + bool fill_surface_trapezoidal(const Surface *surface, FillParams params, Polylines &polylines_out, int Pattern_type); // The extended bounding box of the whole object that covers any rotation of every layer. BoundingBox extended_object_bounding_box() const; diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 812e9f0154..738f1f5f6f 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -125,6 +125,10 @@ static constexpr const char* VOLUME_TYPE = "volume"; static constexpr const char* NAME_KEY = "name"; static constexpr const char* MODIFIER_KEY = "modifier"; static constexpr const char* VOLUME_TYPE_KEY = "volume_type"; +// Keep seam modes separate from the base type so older readers see a non-printing modifier. +static constexpr const char* PRECISE_SEAM_TYPE_KEY = "precise_seam_type"; +// Preserve dormant settings without turning an older reader's modifier into an active override. +static constexpr char PRECISE_SEAM_CONFIG_PREFIX[] = "precise_seam_config:"; static constexpr const char* MATRIX_KEY = "matrix"; static constexpr const char* SOURCE_FILE_KEY = "source_file"; static constexpr const char* SOURCE_OBJECT_ID_KEY = "source_object_id"; @@ -307,14 +311,17 @@ bool PrusaFileParser::check_3mf_from_prusa(const std::string filename) mz_zip_archive_file_stat stat; if (!mz_zip_reader_file_stat(&archive, model_file_index, &stat)) goto EXIT; + // expat sizes its buffer with an int, so a larger entry cannot be parsed in one piece. + if (stat.m_uncomp_size > static_cast(std::numeric_limits::max())) goto EXIT; - void *parser_buffer = XML_GetBuffer(m_parser, (int) stat.m_uncomp_size); + const int xml_size = static_cast(stat.m_uncomp_size); + void *parser_buffer = XML_GetBuffer(m_parser, xml_size); if (parser_buffer == nullptr) goto EXIT; - mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t) stat.m_uncomp_size, 0); + mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, static_cast(xml_size), 0); if (res == 0) goto EXIT; - XML_ParseBuffer(m_parser, (int) stat.m_uncomp_size, 1); + XML_ParseBuffer(m_parser, xml_size, 1); } } @@ -368,7 +375,14 @@ ModelVolumeType type_from_string(const std::string &s) if (s == "ParameterModifier") return ModelVolumeType::PARAMETER_MODIFIER; if (s == "SupportEnforcer") return ModelVolumeType::SUPPORT_ENFORCER; if (s == "SupportBlocker") return ModelVolumeType::SUPPORT_BLOCKER; - // Default value if invalud type string received. + // Precise Seam types (snake_case strings from ModelVolume::type_to_string) + if (s == "precise_seam_center") return ModelVolumeType::PRECISE_SEAM_CENTER; + if (s == "precise_seam_left") return ModelVolumeType::PRECISE_SEAM_LEFT; + if (s == "precise_seam_right") return ModelVolumeType::PRECISE_SEAM_RIGHT; + if (s == "precise_seam_enforced") return ModelVolumeType::PRECISE_SEAM_ENFORCED; + if (s == "precise_seam_blocked") return ModelVolumeType::PRECISE_SEAM_BLOCKED; + if (s == "precise_seam_neutral") return ModelVolumeType::PRECISE_SEAM_NEUTRAL; + // Default value if invalid type string received. return ModelVolumeType::MODEL_PART; } @@ -1346,19 +1360,26 @@ ModelVolumeType type_from_string(const std::string &s) XML_SetUserData(m_xml_parser, (void*)this); XML_SetElementHandler(m_xml_parser, _3MF_Importer::_handle_start_config_xml_element, _3MF_Importer::_handle_end_config_xml_element); - void* parser_buffer = XML_GetBuffer(m_xml_parser, (int)stat.m_uncomp_size); + // expat sizes its buffer with an int, so a larger entry cannot be parsed in one piece. + if (stat.m_uncomp_size > static_cast(std::numeric_limits::max())) { + add_error("Found invalid size"); + return false; + } + const int xml_size = static_cast(stat.m_uncomp_size); + + void* parser_buffer = XML_GetBuffer(m_xml_parser, xml_size); if (parser_buffer == nullptr) { add_error("Unable to create buffer"); return false; } - mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0); + mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, static_cast(xml_size), 0); if (res == 0) { add_error("Error while reading config data to buffer"); return false; } - if (!XML_ParseBuffer(m_xml_parser, (int)stat.m_uncomp_size, 1)) { + if (!XML_ParseBuffer(m_xml_parser, xml_size, 1)) { char error_buf[1024]; ::sprintf(error_buf, "Error (%s) while parsing xml file at line %d", XML_ErrorString(XML_GetErrorCode(m_xml_parser)), (int)XML_GetCurrentLineNumber(m_xml_parser)); add_error(error_buf); @@ -2035,6 +2056,7 @@ ModelVolumeType type_from_string(const std::string &s) std::vector valid_keys = { "name", "volume_type", + PRECISE_SEAM_TYPE_KEY, "matrix", "source_file", "source_object_id", @@ -2047,7 +2069,7 @@ ModelVolumeType type_from_string(const std::string &s) }; auto itor = std::find(valid_keys.begin(), valid_keys.end(), key); - if (itor == valid_keys.end()) { + if (itor == valid_keys.end() && !(type == VOLUME_TYPE && boost::starts_with(key, PRECISE_SEAM_CONFIG_PREFIX))) { // do nothing if not valid keys return true; } @@ -2180,6 +2202,8 @@ ModelVolumeType type_from_string(const std::string &s) volume->mmu_segmentation_facets.shrink_to_fit(); volume->fuzzy_skin_facets.shrink_to_fit(); + // Apply the seam mode after all base-type metadata, regardless of XML key order. + ModelVolumeType precise_seam_type = ModelVolumeType::INVALID; // apply the remaining volume's metadata for (const Metadata& metadata : volume_data.metadata) { if (metadata.key == NAME_KEY) @@ -2188,6 +2212,10 @@ ModelVolumeType type_from_string(const std::string &s) volume->set_type(ModelVolumeType::PARAMETER_MODIFIER); else if (metadata.key == VOLUME_TYPE_KEY) volume->set_type(type_from_string(metadata.value)); + else if (metadata.key == PRECISE_SEAM_TYPE_KEY) + precise_seam_type = ModelVolume::type_from_string(metadata.value); + else if (boost::starts_with(metadata.key, PRECISE_SEAM_CONFIG_PREFIX)) + continue; // Restore dormant settings only after the final volume type is known. else if (metadata.key == SOURCE_FILE_KEY) volume->source.input_file = metadata.value; else if (metadata.key == SOURCE_OBJECT_ID_KEY) @@ -2208,6 +2236,22 @@ ModelVolumeType type_from_string(const std::string &s) volume->config.set_deserialize(metadata.key, metadata.value, config_substitutions); } + // Missing or unknown seam modes retain the ordinary modifier fallback. + // Ignore seam metadata on other base types; legacy inline seam types still load above. + if (volume->is_modifier() && is_precise_seam(precise_seam_type)) + volume->set_type(precise_seam_type); + + // Unknown seam modes must remain inert modifiers, even when dormant settings are present. + if (volume->is_precise_seam()) { + for (const Metadata& metadata : volume_data.metadata) { + if (boost::starts_with(metadata.key, PRECISE_SEAM_CONFIG_PREFIX)) { + const std::string key = metadata.key.substr(sizeof(PRECISE_SEAM_CONFIG_PREFIX) - 1); + if (!key.empty()) + volume->config.set_deserialize(key, metadata.value, config_substitutions); + } + } + } + // this may happen for 3mf saved by 3rd part softwares if (volume->name.empty()) { volume->name = object.name; @@ -3123,11 +3167,18 @@ ModelVolumeType type_from_string(const std::string &s) stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n"; // stores volume's modifier field (legacy, to support old slicers) - if (volume->is_modifier()) + // Readers with only the legacy flag still see helper geometry as a modifier. + if (volume->is_modifier() || volume->is_precise_seam()) stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MODIFIER_KEY << "\" " << VALUE_ATTR << "=\"1\"/>\n"; - // stores volume's type (overrides the modifier field above) + // This Prusa-format reader uses ParameterModifier, not Bambu's modifier_part. + // The base type overrides the legacy flag, so it must also be backward-compatible. + // Use the same spelling for ordinary modifiers, including a downgraded seam helper. + const bool store_as_modifier = volume->is_modifier() || volume->is_precise_seam(); stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " << - VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n"; + VALUE_ATTR << "=\"" << (store_as_modifier ? "ParameterModifier" : ModelVolume::type_to_string(volume->type())) << "\"/>\n"; + if (volume->is_precise_seam()) + stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << PRECISE_SEAM_TYPE_KEY << "\" " << + VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n"; // stores volume's local matrix stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MATRIX_KEY << "\" " << VALUE_ATTR << "=\""; @@ -3162,7 +3213,12 @@ ModelVolumeType type_from_string(const std::string &s) // stores volume's config data for (const std::string& key : volume->config.keys()) { - stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n"; + // Seam settings are inactive but must survive changing the helper back into a part/modifier. + const bool dormant = volume->is_precise_seam(); + const std::string stored_key = dormant ? PRECISE_SEAM_CONFIG_PREFIX + key : key; + const std::string value = volume->config.opt_serialize(key); + // Config serialization is C-style, not XML: escape active settings too, including tabs. + stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << stored_key << "\" " << VALUE_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(value) << "\"/>\n"; } // stores mesh's statistics diff --git a/src/libslic3r/Format/DRC.cpp b/src/libslic3r/Format/DRC.cpp index d489f04dba..c07655f69b 100644 --- a/src/libslic3r/Format/DRC.cpp +++ b/src/libslic3r/Format/DRC.cpp @@ -48,24 +48,37 @@ bool load_drc(const char *path, TriangleMesh *meshptr) indexed_triangle_set its; const PointAttribute *const positions = dracoMesh.GetNamedAttribute(GeometryAttribute::POSITION); + if (positions == nullptr) { + BOOST_LOG_TRIVIAL(error) << "load_drc: the mesh has no POSITION attribute"; + return false; + } size_t num_vertices = positions->size(); its.vertices.reserve(num_vertices); for (AttributeValueIndex i(0); i < num_vertices; ++ i) { float pos[3]; - positions->ConvertValue(i, 3, pos); + if (!positions->ConvertValue(i, 3, pos)) { + BOOST_LOG_TRIVIAL(error) << "load_drc: invalid vertex position"; + return false; + } its.vertices.emplace_back(pos[0], pos[1], pos[2]); } + // The Draco decoder does not check face indices against the point count. + const uint32_t num_points = dracoMesh.num_points(); size_t num_faces = dracoMesh.num_faces(); its.indices.reserve(num_faces); for (FaceIndex i(0); i < num_faces; ++ i) { - Mesh::Face face = dracoMesh.face(i); - - its.indices.emplace_back( - positions->mapped_index(face[0]).value(), - positions->mapped_index(face[1]).value(), - positions->mapped_index(face[2]).value() - ); + const Mesh::Face &face = dracoMesh.face(i); + stl_triangle_vertex_indices facet; + for (int k = 0; k < 3; ++ k) { + const size_t vertex_idx = face[k].value() < num_points ? positions->mapped_index(face[k]).value() : num_vertices; + if (vertex_idx >= num_vertices) { + BOOST_LOG_TRIVIAL(error) << "load_drc: invalid vertex index"; + return false; + } + facet[k] = static_cast(vertex_idx); + } + its.indices.emplace_back(facet); } *meshptr = TriangleMesh(std::move(its)); diff --git a/src/libslic3r/Format/OBJ.cpp b/src/libslic3r/Format/OBJ.cpp index 10abe8e4de..8242f2c0c9 100644 --- a/src/libslic3r/Format/OBJ.cpp +++ b/src/libslic3r/Format/OBJ.cpp @@ -141,7 +141,7 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s its.indices.emplace_back(indices[0], indices[1], indices[2]); int face_index =its.indices.size() - 1; RGBA face_color; - auto set_face_color = [&uvs, &data, &mtl_data, &obj_info, &face_color](int face_index, const std::string mtl_name) { + auto set_face_color = [&uvs, &data, &mtl_data, &obj_info, &face_color](int face_index, const std::string mtl_name, const std::array &corners) { if (mtl_data.new_mtl_unmap.find(mtl_name) != mtl_data.new_mtl_unmap.end()) { bool is_merge_ka_kd = true; for (size_t n = 0; n < 3; n++) { @@ -166,10 +166,15 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s obj_info.uv_map_pngs[face_index] = png_name; } if (data.textureCoordinates.size() > 0) { - Vec2f uv0(data.textureCoordinates[uvs[0] * 2], data.textureCoordinates[uvs[0] * 2 + 1]); - Vec2f uv1(data.textureCoordinates[uvs[1] * 2], data.textureCoordinates[uvs[1] * 2 + 1]); - Vec2f uv2(data.textureCoordinates[uvs[2] * 2], data.textureCoordinates[uvs[2] * 2 + 1]); - std::array uv_array{uv0, uv1, uv2}; + // A face vertex may omit vt or reference a missing one. Fall back to (0, 0) rather than + // skipping the face, so obj_info.uvs stays aligned with the face indices. + const int uv_count = static_cast(data.textureCoordinates.size() / OBJ_TEXCOORD_LENGTH); + auto uv_at = [&data, uv_count](int idx) -> Vec2f { + if (idx < 0 || idx >= uv_count) + return Vec2f::Zero(); + return Vec2f(data.textureCoordinates[idx * OBJ_TEXCOORD_LENGTH], data.textureCoordinates[idx * OBJ_TEXCOORD_LENGTH + 1]); + }; + std::array uv_array{uv_at(uvs[corners[0]]), uv_at(uvs[corners[1]]), uv_at(uvs[corners[2]])}; obj_info.uvs.emplace_back(uv_array); } obj_info.face_colors.emplace_back(face_color); @@ -180,27 +185,27 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s } } }; - auto set_face_color_by_mtl = [&data, &set_face_color](int face_index) { + auto set_face_color_by_mtl = [&data, &set_face_color](int face_index, const std::array &corners) { if (data.usemtls.size() == 1) { - set_face_color(face_index, data.usemtls[0].name); + set_face_color(face_index, data.usemtls[0].name, corners); } else { for (size_t k = 0; k < data.usemtls.size(); k++) { auto mtl = data.usemtls[k]; if (face_index >= mtl.face_start && face_index <= mtl.face_end) { - set_face_color(face_index, data.usemtls[k].name); + set_face_color(face_index, data.usemtls[k].name, corners); break; } } } }; if (exist_mtl) { - set_face_color_by_mtl(face_index); + set_face_color_by_mtl(face_index, {0, 1, 2}); } if (cnt == 4) { its.indices.emplace_back(indices[0], indices[2], indices[3]); int face_index = its.indices.size() - 1; if (exist_mtl) { - set_face_color_by_mtl(face_index); + set_face_color_by_mtl(face_index, {0, 2, 3}); } } } @@ -212,8 +217,12 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s message = _L("This OBJ file couldn't be read because it's empty."); return false; } - if (meshptr->volume() < 0) + if (meshptr->volume() < 0) { meshptr->flip_triangles(); + // Flipping swaps corners 1 and 2 of every face, so the UVs have to follow. + for (std::array &uv : obj_info.uvs) + std::swap(uv[1], uv[2]); + } // Hand the parsed material table back so callers can build a TexturedMesh from it. if (out_mtl) *out_mtl = mtl_data; diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 09899aa4c2..160c169d69 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -353,6 +353,10 @@ static constexpr const char* PART_TYPE = "part"; static constexpr const char* NAME_KEY = "name"; static constexpr const char* VOLUME_TYPE_KEY = "volume_type"; static constexpr const char* PART_TYPE_KEY = "part_type"; +// Keep seam modes separate from the base type so older readers see a non-printing modifier. +static constexpr const char* PRECISE_SEAM_TYPE_KEY = "precise_seam_type"; +// Preserve dormant settings without turning an older reader's modifier into an active override. +static constexpr char PRECISE_SEAM_CONFIG_PREFIX[] = "precise_seam_config:"; static constexpr const char* MATRIX_KEY = "matrix"; static constexpr const char* SOURCE_FILE_KEY = "source_file"; static constexpr const char* SOURCE_OBJECT_ID_KEY = "source_object_id"; @@ -1629,7 +1633,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } while (it != m_plater_data.end()) { - if (it->first > m_plater_data.size()) + if (it->first <= 0 || static_cast(it->first) > m_plater_data.size()) { add_error("invalid plate index"); return false; @@ -2312,7 +2316,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } while (it != m_plater_data.end()) { - if (it->first > m_plater_data.size()) + if (it->first <= 0 || static_cast(it->first) > m_plater_data.size()) { add_error("invalid plate index"); return false; @@ -2508,19 +2512,26 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) XML_SetEntityDeclHandler(m_xml_parser, nullptr); XML_SetExternalEntityRefHandler(m_xml_parser, nullptr); - void* parser_buffer = XML_GetBuffer(m_xml_parser, (int)stat.m_uncomp_size); + // expat sizes its buffer with an int, so a larger entry cannot be parsed in one piece. + if (stat.m_uncomp_size > static_cast(std::numeric_limits::max())) { + add_error("Found invalid size"); + return false; + } + const int xml_size = static_cast(stat.m_uncomp_size); + + void* parser_buffer = XML_GetBuffer(m_xml_parser, xml_size); if (parser_buffer == nullptr) { add_error("Unable to create buffer"); return false; } - mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0); + mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, static_cast(xml_size), 0); if (res == 0) { add_error("Error while reading config data to buffer"); return false; } - if (!XML_ParseBuffer(m_xml_parser, (int)stat.m_uncomp_size, 1)) { + if (!XML_ParseBuffer(m_xml_parser, xml_size, 1)) { char error_buf[1024]; ::snprintf(error_buf, 1024, "Error (%s) while parsing xml file at line %d", XML_ErrorString(XML_GetErrorCode(m_xml_parser)), (int)XML_GetCurrentLineNumber(m_xml_parser)); add_error(error_buf); @@ -5212,6 +5223,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (auto &tc = volume_data->text_configuration; tc.has_value()) volume->text_configuration = std::move(tc); + // Apply the seam mode after all base-type metadata, regardless of XML key order. + ModelVolumeType precise_seam_type = ModelVolumeType::INVALID; // apply the remaining volume's metadata for (const Metadata& metadata : volume_data->metadata) { if (metadata.key == NAME_KEY) @@ -5221,6 +5234,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //for old format else if ((metadata.key == VOLUME_TYPE_KEY) || (metadata.key == PART_TYPE_KEY)) volume->set_type(ModelVolume::type_from_string(metadata.value)); + else if (metadata.key == PRECISE_SEAM_TYPE_KEY) + precise_seam_type = ModelVolume::type_from_string(metadata.value); + else if (boost::starts_with(metadata.key, PRECISE_SEAM_CONFIG_PREFIX)) + continue; // Restore dormant settings only after the final volume type is known. else if (metadata.key == SOURCE_FILE_KEY) volume->source.input_file = metadata.value; else if (metadata.key == SOURCE_OBJECT_ID_KEY) @@ -5243,6 +5260,22 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) volume->config.set_deserialize(metadata.key, metadata.value, config_substitutions); } + // Missing or unknown seam modes retain the ordinary modifier fallback. + // Ignore seam metadata on other base types; legacy inline seam types still load above. + if (volume->is_modifier() && is_precise_seam(precise_seam_type)) + volume->set_type(precise_seam_type); + + // Unknown seam modes must remain inert modifiers, even when dormant settings are present. + if (volume->is_precise_seam()) { + for (const Metadata& metadata : volume_data->metadata) { + if (boost::starts_with(metadata.key, PRECISE_SEAM_CONFIG_PREFIX)) { + const std::string key = metadata.key.substr(sizeof(PRECISE_SEAM_CONFIG_PREFIX) - 1); + if (!key.empty()) + volume->config.set_deserialize(key, metadata.value, config_substitutions); + } + } + } + // this may happen for 3mf saved by 3rd part softwares if (volume->name.empty()) { volume->name = object.name; @@ -8002,7 +8035,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) volume_id = m_volume_paths.find(volume)->second.second; stream << ID_ATTR << "=\"" << volume_id << "\" "; - stream << SUBTYPE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\">\n"; + // Older slicers must recognize the base type even when they ignore seam metadata. + const ModelVolumeType stored_type = volume->is_precise_seam() ? ModelVolumeType::PARAMETER_MODIFIER : volume->type(); + stream << SUBTYPE_ATTR << "=\"" << ModelVolume::type_to_string(stored_type) << "\">\n"; + if (volume->is_precise_seam()) + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PRECISE_SEAM_TYPE_KEY << "\" " << VALUE_ATTR << "=\"" << + ModelVolume::type_to_string(volume->type()) << "\"/>\n"; //stream << " <" << PART_TAG << " " << ID_ATTR << "=\"" << it->second << "\" " << SUBTYPE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\">\n"; // stores volume's name @@ -8052,7 +8090,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) // stores volume's config data for (const std::string& key : volume->config.keys()) { - stream << " <" << METADATA_TAG << " "<< KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n"; + // Seam settings are inactive but must survive changing the helper back into a part/modifier. + const bool dormant = volume->is_precise_seam(); + const std::string stored_key = dormant ? PRECISE_SEAM_CONFIG_PREFIX + key : key; + const std::string value = volume->config.opt_serialize(key); + // Config serialization is C-style, not XML: escape active settings too, including tabs. + stream << " <" << METADATA_TAG << " "<< KEY_ATTR << "=\"" << stored_key << "\" " << VALUE_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(value) << "\"/>\n"; } if (const std::optional &es = volume->emboss_shape; es.has_value()) { diff --git a/src/libslic3r/Format/objparser.cpp b/src/libslic3r/Format/objparser.cpp index 886fa423bd..c5f33a7d0a 100644 --- a/src/libslic3r/Format/objparser.cpp +++ b/src/libslic3r/Format/objparser.cpp @@ -51,19 +51,18 @@ static bool obj_parseline(const char *line, ObjData &data) line = endptr; EATWS(); } - /*double w = 0; + // The optional w is accepted but not stored: only u and v are used. if (*line != 0) { - w = strtod(line, &endptr); + strtod(line, &endptr); if (endptr == 0 || (*endptr != ' ' && *endptr != '\t' && *endptr != 0)) return false; line = endptr; EATWS(); - }*/ + } if (*line != 0) return false; data.textureCoordinates.push_back((float)u); data.textureCoordinates.push_back((float)v); - //data.textureCoordinates.push_back((float)w); break; } case 'n': @@ -245,7 +244,7 @@ static bool obj_parseline(const char *line, ObjData &data) else -- vertex.normalIdx; if (vertex.textureCoordIdx < 0) - vertex.textureCoordIdx += (int)data.textureCoordinates.size() / 3; + vertex.textureCoordIdx += (int)data.textureCoordinates.size() / OBJ_TEXCOORD_LENGTH; else -- vertex.textureCoordIdx; data.vertices.push_back(vertex); diff --git a/src/libslic3r/Format/objparser.hpp b/src/libslic3r/Format/objparser.hpp index 58afd015a8..e711bdf6f4 100644 --- a/src/libslic3r/Format/objparser.hpp +++ b/src/libslic3r/Format/objparser.hpp @@ -92,6 +92,7 @@ inline bool operator==(const ObjSmoothingGroup &v1, const ObjSmoothingGroup &v2) } #define OBJ_VERTEX_COLOR_ALPHA 6 #define OBJ_VERTEX_LENGTH 7 // x, y, z, color_x,color_y,color_z,color_w +#define OBJ_TEXCOORD_LENGTH 2 // u, v #define ONE_FACE_SIZE 4//ONE_FACE format: f 8/4/6 7/3/6 6/2/6 -1/-1/-1 struct ObjData { // Version of the data structure for load / store in the private binary format. @@ -100,7 +101,7 @@ struct ObjData { // x, y, z, color_x,color_y,color_z,color_w std::vector coordinates; bool has_vertex_color{false}; - // u, v, w + // u, v std::vector textureCoordinates; // x, y, z std::vector normals; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 941818c78f..dedd024f2b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1258,7 +1258,7 @@ static std::vector get_path_of_change_filament(const Print& print) config.set_key_value("old_filament_temp", new ConfigOptionInt(old_filament_temp)); int interface_temp = full_config.filament_tower_interface_print_temp.get_at(new_filament_id); if (interface_temp == -1) - interface_temp = full_config.nozzle_temperature_range_high.get_at(new_filament_id); + interface_temp = full_config.nozzle_temperature_range_high.get_at(new_fi); if (full_config.enable_tower_interface_features && tcr.is_contact) new_filament_temp = interface_temp; config.set_key_value("new_filament_temp", new ConfigOptionInt(new_filament_temp)); @@ -1309,7 +1309,7 @@ static std::vector get_path_of_change_filament(const Print& print) flush_temps[idx] = use_fast_flush ? m_print_config->filament_flush_temp_fast.get_at(fi) : m_print_config->filament_flush_temp.get_at(fi); if (flush_temps[idx] == 0) - flush_temps[idx] = m_print_config->nozzle_temperature_range_high.get_at(idx); + flush_temps[idx] = m_print_config->nozzle_temperature_range_high.get_at(fi); filament_cooling_before_tower[idx] = m_print_config->filament_cooling_before_tower.get_at(fi); } if (tcr.is_contact || gcodegen.m_layer_index == 0) @@ -1497,12 +1497,7 @@ static std::vector get_path_of_change_filament(const Print& print) check_add_eol(toolchange_gcode_str); // SoftFever: set new PA for new filament - if (gcodegen.config().enable_pressure_advance.get_at(new_filament_id)) { - gcode += gcodegen.writer().set_pressure_advance(gcodegen.config().pressure_advance.get_at(new_filament_id)); - // Orca: Adaptive PA - // Reset Adaptive PA processor last PA value - gcodegen.m_pa_processor->resetPreviousPA(gcodegen.config().pressure_advance.get_at(new_filament_id)); - } + gcode += gcodegen.set_filament_pressure_advance(new_filament_id); // A phony move to the end position at the wipe tower. gcodegen.writer().travel_to_xy((end_pos + plate_origin_2d).cast()); @@ -1568,7 +1563,7 @@ static std::vector get_path_of_change_filament(const Print& print) const bool will_go_down = !is_approx(z, current_z); const bool is_ramming = (gcodegen.config().single_extruder_multi_material) || (!gcodegen.config().single_extruder_multi_material && - gcodegen.config().filament_multitool_ramming.get_at(tcr.initial_tool)); + gcodegen.config().filament_multitool_ramming.get_at(gcodegen.get_filament_config_index(tcr.initial_tool))); // Orca: user-facing override (Printer Settings > Wipe tower > "Tool change on wipe tower"). // Forces the toolhead to travel over the wipe tower before issuing Tx even on multi-toolhead // printers without ramming, where Orca would otherwise emit Tx in place (potentially over the part). @@ -1625,7 +1620,7 @@ static std::vector get_path_of_change_filament(const Print& print) if (gcodegen.config().enable_tower_interface_features && tcr.is_contact) { interface_temp = gcodegen.config().filament_tower_interface_print_temp.get_at(new_extruder_id); if (interface_temp == -1) - interface_temp = gcodegen.config().nozzle_temperature_range_high.get_at(new_extruder_id); + interface_temp = gcodegen.config().nozzle_temperature_range_high.get_at(gcodegen.get_filament_config_index(new_extruder_id)); toolchange_temp_override = interface_temp; } toolchange_gcode_str = gcodegen.set_extruder(new_extruder_id, tcr.print_z, false, toolchange_temp_override, @@ -1826,12 +1821,8 @@ static std::vector get_path_of_change_filament(const Print& print) check_add_eol(toolchange_gcode_str); // SoftFever: set new PA for new filament - if (new_extruder_id != -1 && gcodegen.config().enable_pressure_advance.get_at(new_extruder_id)) { - gcode += gcodegen.writer().set_pressure_advance(gcodegen.config().pressure_advance.get_at(new_extruder_id)); - // Orca: Adaptive PA - // Reset Adaptive PA processor last PA value - gcodegen.m_pa_processor->resetPreviousPA(gcodegen.config().pressure_advance.get_at(new_extruder_id)); - } + if (new_extruder_id != -1) + gcode += gcodegen.set_filament_pressure_advance(new_extruder_id); // A phony move to the end position at the wipe tower. gcodegen.writer().travel_to_xy((end_pos + plate_origin_2d).cast()); @@ -3232,7 +3223,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_cooling_buffer->set_current_extruder(initial_extruder_id, extruder_id); // Orca: Initialise AdaptivePA processor filter - m_pa_processor = std::make_unique(*this, tool_ordering.all_extruders()); + m_pa_processor = std::make_unique(*this); // Update output variables after the extruders were initialized. m_placeholder_parser_integration.init(m_writer); @@ -3797,12 +3788,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } } // Orca: add missing PA settings for initial filament - if (m_config.enable_pressure_advance.get_at(initial_non_support_extruder_id)) { - file.write(m_writer.set_pressure_advance(m_config.pressure_advance.get_at(initial_non_support_extruder_id))); - // Orca: Adaptive PA - // Reset Adaptive PA processor last PA value - m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(initial_non_support_extruder_id)); - } + file.write(set_filament_pressure_advance(initial_non_support_extruder_id)); } //flush FanMover buffer to avoid modifying the start gcode if it's manual. @@ -4188,6 +4174,28 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato print.throw_if_canceled(); + // Some firmwares only scan the last N lines for the time estimate, so the stats are written + // after the config block. + if (!is_bbl_printers && !skip_config_block) { + file.write("; CONFIG_BLOCK_START\n"); + std::string full_config; + append_full_config(print, full_config); + if (!full_config.empty()) + file.write(full_config); + + // SoftFever: write compatiple info + int first_layer_bed_temperature = get_bed_temperature(0, true, print.config().curr_bed_type); + file.write_format("; first_layer_bed_temperature = %d\n", first_layer_bed_temperature); + file.write_format("; bed_shape = %s\n", print.full_print_config().opt_serialize("printable_area").c_str()); + file.write_format("; first_layer_temperature = %d\n", print.config().nozzle_temperature_initial_layer.get_at(0)); + file.write_format("; first_layer_height = %.3f\n", print.config().initial_layer_print_height.value); + + //SF TODO +// file.write_format("; variable_layer_height = %d\n", print.ad.adaptive_layer_height ? 1 : 0); + + file.write("; CONFIG_BLOCK_END\n\n"); + } + // Get filament stats. file.write(DoExport::update_print_stats_and_format_filament_stats( // Const inputs @@ -4198,6 +4206,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Const input (tool-change fallback for non-wipe-tower prints) print.tool_ordering())); print.m_print_statistics.initial_tool = initial_extruder_id; + print.m_print_statistics.initial_no_support_tool = initial_non_support_extruder_id; if (!is_bbl_printers) { file.write_format("; total filament used [g] = %.2lf\n", print.m_print_statistics.total_weight); @@ -4213,26 +4222,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder) .c_str()); file.write("\n"); - if (!skip_config_block) { - file.write("; CONFIG_BLOCK_START\n"); - std::string full_config; - append_full_config(print, full_config); - if (!full_config.empty()) - file.write(full_config); - - // SoftFever: write compatiple info - int first_layer_bed_temperature = get_bed_temperature(0, true, print.config().curr_bed_type); - file.write_format("; first_layer_bed_temperature = %d\n", first_layer_bed_temperature); - file.write_format("; bed_shape = %s\n", print.full_print_config().opt_serialize("printable_area").c_str()); - file.write_format("; first_layer_temperature = %d\n", print.config().nozzle_temperature_initial_layer.get_at(0)); - file.write_format("; first_layer_height = %.3f\n", print.config().initial_layer_print_height.value); - - //SF TODO -// file.write_format("; variable_layer_height = %d\n", print.ad.adaptive_layer_height ? 1 : 0); - - file.write("; CONFIG_BLOCK_END\n\n"); - } // !skip_config_block - } file.write("\n"); @@ -4353,6 +4342,12 @@ size_t GCode::get_filament_config_index(int filament_id) const return filament_id; } +size_t GCode::get_filament_config_index(int filament_id, size_t layer_id) const +{ + // Orca: uncached, as the stages after the generator run concurrently with it. + return m_print ? m_print->get_filament_config_indx(filament_id, (int) layer_id, false) : filament_id; +} + size_t GCode::get_nozzle_config_index(int filament_id) const { if (m_print) { @@ -8389,12 +8384,16 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // Orca: Dynamic PA // If adaptive PA is enabled, by default evaluate PA on all extrusion moves + // The PA settings and the PA_CHANGE tags use the filament config index of the filament's extruder variant + const unsigned int pa_config_index = (unsigned int) get_filament_config_index(m_writer.filament()->id()); + const bool adaptive_pa = m_config.adaptive_pressure_advance.get_at(pa_config_index) && m_config.enable_pressure_advance.get_at(pa_config_index); + const bool adaptive_pa_overhangs = adaptive_pa && m_config.adaptive_pressure_advance_overhangs.get_at(pa_config_index); bool is_pa_calib = m_curr_print->calib_mode() == CalibMode::Calib_PA_Line || m_curr_print->calib_mode() == CalibMode::Calib_PA_Pattern || m_curr_print->calib_mode() == CalibMode::Calib_PA_Tower; bool evaluate_adaptive_pa = false; bool role_change = (m_last_extrusion_role != path.role()); - if (!is_pa_calib && FILAMENT_CONFIG(adaptive_pressure_advance) && FILAMENT_CONFIG(enable_pressure_advance)) { + if (!is_pa_calib && adaptive_pa) { evaluate_adaptive_pa = true; // If we have already emmited a PA change because the m_multi_flow_segment_path_pa_set is set // skip re-issuing the PA change tag. @@ -8477,7 +8476,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // Post processor flag generation code segment when option to emit only at role changes is enabled // Variables published to the post processor: // 1) Tag to trigger a PA evaluation (because a role change was identified and the user has requested dynamic PA adjustments) - // 2) Current extruder ID (to identify the PA model for the currently used extruder) + // 2) Current filament config index (to identify the PA model for the currently used filament and its extruder variant) // 3) mm3_per_mm value (to then multiply by the final model print speed after slowdown for cooling is applied) // 4) the current acceleration (to pass to the model for evaluation) // 5) whether this is an external perimeter (for future use) @@ -8488,7 +8487,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (m_multi_flow_segment_path_average_mm3_per_mm > 0) { sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer.filament()->id(), + pa_config_index, m_multi_flow_segment_path_average_mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8501,7 +8500,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // to issue a zero flow PA change command for this sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer.filament()->id(), + pa_config_index, _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8609,11 +8608,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // or a flow change, so emit the flag to evaluate PA for the upcomming extrusion // Emit tag before new speed is set so the post processor reads the next speed immediately and uses it. // Dont emit tag if it has just already been emitted from a role change above - if(_mm3_per_mm >0 && - FILAMENT_CONFIG(adaptive_pressure_advance) && - FILAMENT_CONFIG(enable_pressure_advance) && - FILAMENT_CONFIG(adaptive_pressure_advance_overhangs) && - !evaluate_adaptive_pa){ + if(_mm3_per_mm >0 && adaptive_pa_overhangs && !evaluate_adaptive_pa){ if(writer().get_current_speed() > F){ // Ramping down speed - use overhang logic where the minimum speed is used between current and upcoming extrusion if(m_config.gcode_comments){ sprintf(buf, "; Ramp down-non-variable\n"); @@ -8621,7 +8616,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer.filament()->id(), + pa_config_index, _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8636,7 +8631,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer.filament()->id(), + pa_config_index, _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8842,10 +8837,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // ORCA: Adaptive PA code segment when adjusting PA within the same feature // There is a speed change or flow change so emit the flag to evaluate PA for the upcomming extrusion // Emit tag before new speed is set so the post processor reads the next speed immediately and uses it. - if(_mm3_per_mm >0 && - EXTRUDER_CONFIG(adaptive_pressure_advance) && - EXTRUDER_CONFIG(enable_pressure_advance) && - EXTRUDER_CONFIG(adaptive_pressure_advance_overhangs) ){ + if(_mm3_per_mm >0 && adaptive_pa_overhangs){ if(last_set_speed > new_speed){ // Ramping down speed - use overhang logic where the minimum speed is used between current and upcoming extrusion if(m_config.gcode_comments) { sprintf(buf, "; Ramp up-variable\n"); @@ -8853,7 +8845,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer.filament()->id(), + pa_config_index, _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8868,7 +8860,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer.filament()->id(), + pa_config_index, _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -9421,33 +9413,42 @@ void GCode::update_placeholder_parser_with_variant_params() if (num_filaments == 0) return; - // Helpers: remap config arrays from variant index space to filament_id index space. + // Helper: remap config arrays from variant index space to filament_id index space. // After remapping, gcode templates can use param[filament_id] directly. - auto remap_floats_by_filament = [&](const auto &src) { - std::vector dst(num_filaments); + std::vector config_index(num_filaments); + for (size_t i = 0; i < num_filaments; ++i) + config_index[i] = get_filament_config_index(i); + auto remap_by_filament = [&](const auto &src) { + std::decay_t dst(num_filaments); for (size_t i = 0; i < num_filaments; ++i) - dst[i] = src.get_at(get_filament_config_index(i)); - return dst; - }; - auto remap_ints_by_filament = [&](const auto &src) { - std::vector dst(num_filaments); - for (size_t i = 0; i < num_filaments; ++i) - dst[i] = src.get_at(get_filament_config_index(i)); + dst[i] = src.get_at(config_index[i]); return dst; }; // --- filament_options_with_variant: gcode indexes by filament_id --- - this->placeholder_parser().set("filament_max_volumetric_speed", new ConfigOptionFloats(remap_floats_by_filament(m_config.filament_max_volumetric_speed))); - this->placeholder_parser().set("filament_pre_cooling_temperature", new ConfigOptionInts(remap_ints_by_filament(m_config.filament_pre_cooling_temperature))); - this->placeholder_parser().set("filament_pre_cooling_temperature_nc", new ConfigOptionInts(remap_ints_by_filament(m_config.filament_pre_cooling_temperature_nc))); - this->placeholder_parser().set("filament_cooling_before_tower", new ConfigOptionFloats(remap_floats_by_filament(m_config.filament_cooling_before_tower))); - this->placeholder_parser().set("nozzle_temperature_initial_layer", new ConfigOptionInts(remap_ints_by_filament(m_config.nozzle_temperature_initial_layer))); - this->placeholder_parser().set("nozzle_temperature", new ConfigOptionInts(remap_ints_by_filament(m_config.nozzle_temperature))); + this->placeholder_parser().set("filament_max_volumetric_speed", new ConfigOptionFloats(remap_by_filament(m_config.filament_max_volumetric_speed))); + this->placeholder_parser().set("filament_pre_cooling_temperature", new ConfigOptionInts(remap_by_filament(m_config.filament_pre_cooling_temperature))); + this->placeholder_parser().set("filament_pre_cooling_temperature_nc", new ConfigOptionInts(remap_by_filament(m_config.filament_pre_cooling_temperature_nc))); + this->placeholder_parser().set("filament_cooling_before_tower", new ConfigOptionFloats(remap_by_filament(m_config.filament_cooling_before_tower))); + this->placeholder_parser().set("nozzle_temperature_initial_layer", new ConfigOptionInts(remap_by_filament(m_config.nozzle_temperature_initial_layer))); + this->placeholder_parser().set("nozzle_temperature", new ConfigOptionInts(remap_by_filament(m_config.nozzle_temperature))); // first_layer_temperature is a legacy alias of nozzle_temperature_initial_layer - this->placeholder_parser().set("first_layer_temperature", new ConfigOptionInts(remap_ints_by_filament(m_config.nozzle_temperature_initial_layer))); + this->placeholder_parser().set("first_layer_temperature", new ConfigOptionInts(remap_by_filament(m_config.nozzle_temperature_initial_layer))); + this->placeholder_parser().set("pressure_advance", new ConfigOptionFloats(remap_by_filament(m_config.pressure_advance))); + this->placeholder_parser().set("enable_pressure_advance", new ConfigOptionBools(remap_by_filament(m_config.enable_pressure_advance))); + this->placeholder_parser().set("fan_min_speed", new ConfigOptionFloats(remap_by_filament(m_config.fan_min_speed))); + this->placeholder_parser().set("fan_max_speed", new ConfigOptionFloats(remap_by_filament(m_config.fan_max_speed))); + this->placeholder_parser().set("additional_cooling_fan_speed", new ConfigOptionInts(remap_by_filament(m_config.additional_cooling_fan_speed))); + this->placeholder_parser().set("filament_minimal_purge_on_wipe_tower", new ConfigOptionFloats(remap_by_filament(m_config.filament_minimal_purge_on_wipe_tower))); + this->placeholder_parser().set("filament_multitool_ramming", new ConfigOptionBools(remap_by_filament(m_config.filament_multitool_ramming))); + this->placeholder_parser().set("filament_multitool_ramming_volume", new ConfigOptionFloats(remap_by_filament(m_config.filament_multitool_ramming_volume))); + this->placeholder_parser().set("filament_multitool_ramming_flow", new ConfigOptionFloats(remap_by_filament(m_config.filament_multitool_ramming_flow))); + this->placeholder_parser().set("nozzle_temperature_range_low", new ConfigOptionInts(remap_by_filament(m_config.nozzle_temperature_range_low))); + const auto nozzle_temperature_range_high = remap_by_filament(m_config.nozzle_temperature_range_high); + this->placeholder_parser().set("nozzle_temperature_range_high", new ConfigOptionInts(nozzle_temperature_range_high)); // --- printer_options_with_variant_1: in m_config these are already merged as filament-indexed --- - this->placeholder_parser().set("retraction_distances_when_cut", new ConfigOptionFloats(remap_floats_by_filament(m_config.retraction_distances_when_cut))); + this->placeholder_parser().set("retraction_distances_when_cut", new ConfigOptionFloats(remap_by_filament(m_config.retraction_distances_when_cut))); // hotend_cooling_rate / hotend_heating_rate: gcode uses [filament_map[x]-1] (extruder_id), no remap needed // --- filament_map: per-layer dynamic, sync from m_config to placeholder_parser --- @@ -9457,15 +9458,15 @@ void GCode::update_placeholder_parser_with_variant_params() { // Fast purge mode uses filament_flush_temp_fast; Default is inert. bool use_fast_flush = m_config.prime_volume_mode == PrimeVolumeMode::pvmFast; - auto flush_v_speed = remap_floats_by_filament(m_config.filament_flush_volumetric_speed); - auto filament_max_v = remap_floats_by_filament(m_config.filament_max_volumetric_speed); - auto flush_temps = remap_ints_by_filament(use_fast_flush ? m_config.filament_flush_temp_fast - : m_config.filament_flush_temp); + auto flush_v_speed = remap_by_filament(m_config.filament_flush_volumetric_speed); + auto filament_max_v = remap_by_filament(m_config.filament_max_volumetric_speed); + auto flush_temps = remap_by_filament(use_fast_flush ? m_config.filament_flush_temp_fast + : m_config.filament_flush_temp); for (size_t i = 0; i < num_filaments; ++i) { if (flush_v_speed[i] == 0) flush_v_speed[i] = filament_max_v[i]; if (flush_temps[i] == 0) - flush_temps[i] = m_config.nozzle_temperature_range_high.get_at(i); + flush_temps[i] = nozzle_temperature_range_high[i]; } this->placeholder_parser().set("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); this->placeholder_parser().set("flush_temperatures", new ConfigOptionInts(flush_temps)); @@ -9512,12 +9513,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo gcode += this->placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config); check_add_eol(gcode); } - if (m_config.enable_pressure_advance.get_at(new_filament_id)) { - gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id)); - // Orca: Adaptive PA - // Reset Adaptive PA processor last PA value - m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id)); - } + gcode += set_filament_pressure_advance(new_filament_id); gcode += m_writer.toolchange(new_filament_id, new_extruder_id); if (Extruder *fil = m_writer.filament()) @@ -9729,7 +9725,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo { int interface_temp = m_config.filament_tower_interface_print_temp.get_at(new_filament_id); if (interface_temp == -1) - interface_temp = m_config.nozzle_temperature_range_high.get_at(new_filament_id); + interface_temp = m_config.nozzle_temperature_range_high.get_at(new_fi); dyn_config.set_key_value("filament_tower_interface_print_temp", new ConfigOptionInt(interface_temp)); } if (toolchange_temp_override > 0) { @@ -9768,7 +9764,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo flush_temps[idx] = use_fast_flush ? m_print->config().filament_flush_temp_fast.get_at(fi) : m_print->config().filament_flush_temp.get_at(fi); if (flush_temps[idx] == 0) - flush_temps[idx] = m_print->config().nozzle_temperature_range_high.get_at(idx); + flush_temps[idx] = m_print->config().nozzle_temperature_range_high.get_at(fi); filament_cooling_before_tower[idx] = m_print->config().filament_cooling_before_tower.get_at(fi); } std::fill(filament_cooling_before_tower.begin(), filament_cooling_before_tower.end(), 0); @@ -9908,18 +9904,24 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo if (m_ooze_prevention.enable && !defer_temp_wait) gcode += m_ooze_prevention.post_toolchange(*this); - if (m_config.enable_pressure_advance.get_at(new_filament_id)) { - gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id)); - // Orca: Adaptive PA - // Reset Adaptive PA processor last PA value - m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id)); - } + gcode += set_filament_pressure_advance(new_filament_id); //Orca: tool changer or IDEX's firmware may change Z position, so we set it to unknown/undefined m_last_pos_defined = false; return gcode; } +std::string GCode::set_filament_pressure_advance(unsigned int filament_id) +{ + const size_t fi = get_filament_config_index(filament_id); + if (!m_config.enable_pressure_advance.get_at(fi)) + return {}; + // Orca: Adaptive PA + // Reset Adaptive PA processor last PA value + m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(fi)); + return m_writer.set_pressure_advance(m_config.pressure_advance.get_at(fi)); +} + inline std::string polygon_to_string(const Polygon &polygon, Print *print, bool is_print_space = false) { std::ostringstream gcode; gcode << "["; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 41986cc1d6..6516a3f6fd 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -281,6 +281,8 @@ public: // extra_retract forwards a PETG pre-extrusion over-extrusion; default 0 -> identical to the plain deretract. std::string unretract(float extra_retract = 0.f) { return m_writer.unlift() + m_writer.unretract(extra_retract); } std::string set_extruder(unsigned int extruder_id, double print_z, bool by_object=false, int toolchange_temp_override = -1, bool defer_temp_wait = false); + // Sets the pressure advance of the filament's extruder variant, if enabled for it. + std::string set_filament_pressure_advance(unsigned int filament_id); bool is_BBL_Printer(); WipeTowerType wipe_tower_type(); @@ -294,6 +296,9 @@ public: // resolver keys filament-indexed arrays, the nozzle resolver keys (extruder x volume-type) // slot arrays. Both degenerate to filament_id / extruder index on single-volume printers. size_t get_filament_config_index(int filament_id) const; + // The filament resolver for a given layer, for the export pipeline stages after the generator, + // which run behind the current layer and concurrently with the generator. + size_t get_filament_config_index(int filament_id, size_t layer_id) const; size_t get_nozzle_config_index(int filament_id) const; // Object and support extrusions of the same PrintObject at the same print_z. diff --git a/src/libslic3r/GCode/AdaptivePAProcessor.cpp b/src/libslic3r/GCode/AdaptivePAProcessor.cpp index 80d6b034ad..8145db3b9f 100644 --- a/src/libslic3r/GCode/AdaptivePAProcessor.cpp +++ b/src/libslic3r/GCode/AdaptivePAProcessor.cpp @@ -21,38 +21,30 @@ namespace Slic3r { * * @param gcodegen A reference to the GCode object that generates the G-code. */ -AdaptivePAProcessor::AdaptivePAProcessor(GCode &gcodegen, const std::vector &tools_used) +AdaptivePAProcessor::AdaptivePAProcessor(GCode &gcodegen) : m_gcodegen(gcodegen), m_config(gcodegen.config()), m_last_predicted_pa(0.0), m_max_next_feedrate(0.0), m_next_feedrate(0.0), m_current_feedrate(0.0), - m_last_extruder_id(-1), + m_last_config_index(-1), m_pa_change_pattern(R"(; PA_CHANGE:T(\d+) MM3MM:([0-9]*\.[0-9]+) ACCEL:(\d+) BR:(\d+) RC:(\d+) OV:(\d+))"), m_g1_f_pattern(R"(G1 F([0-9]+))") { - // Constructor body can be used for further initialization if necessary - for (unsigned int tool : tools_used) { - // Only enable model for the tool if both PA and adaptive PA options are enabled - if(m_config.adaptive_pressure_advance.get_at(tool) && m_config.enable_pressure_advance.get_at(tool)){ - auto interpolator = std::make_unique(); - // Get calibration values from extruder - std::string pa_calibration_values = m_config.adaptive_pressure_advance_model.get_at(tool); - // Setup the model and store it in the tool-interpolation model map - interpolator->parseAndSetData(pa_calibration_values); - m_AdaptivePAInterpolators[tool] = std::move(interpolator); - } - } } -// Method to get the interpolator for a specific tool ID -AdaptivePAInterpolator* AdaptivePAProcessor::getInterpolator(unsigned int tool_id) { - auto it = m_AdaptivePAInterpolators.find(tool_id); - if (it != m_AdaptivePAInterpolators.end()) { - return it->second.get(); +// Method to get the interpolator for a specific filament config index. +// The model is built the first time an index is requested, as the indices in use depend on +// the extruder variant each filament prints with. +AdaptivePAInterpolator* AdaptivePAProcessor::getInterpolator(unsigned int config_index) { + auto [it, inserted] = m_AdaptivePAInterpolators.try_emplace(config_index); + // Only enable model for the index if both PA and adaptive PA options are enabled + if (inserted && m_config.adaptive_pressure_advance.get_at(config_index) && m_config.enable_pressure_advance.get_at(config_index)) { + it->second = std::make_unique(); + it->second->parseAndSetData(m_config.adaptive_pressure_advance_model.get_at(config_index)); } - return nullptr; // Handle the case where the tool_id was not found + return it->second.get(); } /** @@ -108,16 +100,17 @@ std::string AdaptivePAProcessor::process_layer(std::string &&gcode) { // the PA for that material is set. As no tag below will be found for this extruder, the original PA is retained. if (line.find("; PA_CHANGE") == 0) { // prune lines quickly before running regex check as regex is more expensive to run if (std::regex_search(line, m_match, m_pa_change_pattern)) { - int extruder_id = std::stoi(m_match[1].str()); + // The tag carries the filament config index, which selects the PA settings of the filament's extruder variant + int config_index = std::stoi(m_match[1].str()); mm3mm_value = std::stod(m_match[2].str()); accel_value = std::stod(m_match[3].str()); int isBridge = std::stoi(m_match[4].str()); int roleChange = std::stoi(m_match[5].str()); int isOverhang = std::stoi(m_match[6].str()); - // Check if the extruder ID has changed - bool extruder_changed = (extruder_id != m_last_extruder_id); - m_last_extruder_id = extruder_id; + // Check if the filament config index has changed + bool config_index_changed = (config_index != m_last_config_index); + m_last_config_index = config_index; // Save the PA_CHANGE line to output later after finding feedrate pa_change_line = line; @@ -212,23 +205,23 @@ std::string AdaptivePAProcessor::process_layer(std::string &&gcode) { // Calculate the predicted PA using the upcomming feature maximum feedrate // Get the interpolator for the active tool - AdaptivePAInterpolator* interpolator = getInterpolator(m_last_extruder_id); + AdaptivePAInterpolator* interpolator = getInterpolator(m_last_config_index); double predicted_pa = 0; double adaptive_PA_speed = 0; if(!interpolator){ // Tool not found in the interpolator map // Tool not found in the PA interpolator to tool map - predicted_pa = m_config.enable_pressure_advance.get_at(m_last_extruder_id) ? m_config.pressure_advance.get_at(m_last_extruder_id) : 0; + predicted_pa = m_config.enable_pressure_advance.get_at(m_last_config_index) ? m_config.pressure_advance.get_at(m_last_config_index) : 0; if(m_config.gcode_comments) output << "; APA: Tool doesnt have APA enabled\n"; - } else if (!interpolator->isInitialised() || (!m_config.adaptive_pressure_advance.get_at(m_last_extruder_id)) ) + } else if (!interpolator->isInitialised() || (!m_config.adaptive_pressure_advance.get_at(m_last_config_index)) ) // Check if the model is not initialised by the constructor for the active extruder // Also check that adaptive PA is enabled for that extruder. This should not be needed // as the PA change flag should not be set upstream (in the GCode.cpp file) if adaptive PA is disabled // however check for robustness sake. { // Model failed or adaptive pressure advance not enabled - use default value from m_config - predicted_pa = m_config.enable_pressure_advance.get_at(m_last_extruder_id) ? m_config.pressure_advance.get_at(m_last_extruder_id) : 0; + predicted_pa = m_config.enable_pressure_advance.get_at(m_last_config_index) ? m_config.pressure_advance.get_at(m_last_config_index) : 0; if(m_config.gcode_comments) output << "; APA: Interpolator setup failed, using default pressure advance\n"; } else { // Model setup succeeded // Proceed to identify the print speed to use to calculate the adaptive PA value @@ -249,18 +242,18 @@ std::string AdaptivePAProcessor::process_layer(std::string &&gcode) { predicted_pa = (*interpolator)(mm3mm_value * adaptive_PA_speed, accel_value); // This is a bridge, use the dedicated PA setting. - if(isBridge && m_config.adaptive_pressure_advance_bridges.get_at(m_last_extruder_id) > EPSILON) - predicted_pa = m_config.adaptive_pressure_advance_bridges.get_at(m_last_extruder_id); + if(isBridge && m_config.adaptive_pressure_advance_bridges.get_at(m_last_config_index) > EPSILON) + predicted_pa = m_config.adaptive_pressure_advance_bridges.get_at(m_last_config_index); if (predicted_pa < 0) { // If extrapolation fails, fall back to the default PA for the extruder. - predicted_pa = m_config.enable_pressure_advance.get_at(m_last_extruder_id) ? m_config.pressure_advance.get_at(m_last_extruder_id) : 0; + predicted_pa = m_config.enable_pressure_advance.get_at(m_last_config_index) ? m_config.pressure_advance.get_at(m_last_config_index) : 0; if(m_config.gcode_comments) output << "; APA: Interpolation failed, using fallback pressure advance value\n"; } } if(m_config.gcode_comments) { // Output debug GCode comments output << pa_change_line << '\n'; // Output PA change command tag - if(isBridge && m_config.adaptive_pressure_advance_bridges.get_at(m_last_extruder_id) > EPSILON) + if(isBridge && m_config.adaptive_pressure_advance_bridges.get_at(m_last_config_index) > EPSILON) output << "; APA Model Override (bridge)\n"; output << "; APA Current Speed: " << std::to_string(m_current_feedrate) << "\n"; output << "; APA Next Speed: " << std::to_string(m_next_feedrate) << "\n"; @@ -269,7 +262,7 @@ std::string AdaptivePAProcessor::process_layer(std::string &&gcode) { output << "; APA Flow rate: " << std::to_string(mm3mm_value * m_max_next_feedrate) << "\n"; output << "; APA Prev PA: " << std::to_string(m_last_predicted_pa) << " New PA: " << std::to_string(predicted_pa) << "\n"; } - if (extruder_changed || std::fabs(predicted_pa - m_last_predicted_pa) > EPSILON) { + if (config_index_changed || std::fabs(predicted_pa - m_last_predicted_pa) > EPSILON) { output << m_gcodegen.writer().set_pressure_advance(predicted_pa); // Use m_writer to set pressure advance m_last_predicted_pa = predicted_pa; // Update the last predicted PA value } diff --git a/src/libslic3r/GCode/AdaptivePAProcessor.hpp b/src/libslic3r/GCode/AdaptivePAProcessor.hpp index 33d4c26d24..01aa2f1104 100644 --- a/src/libslic3r/GCode/AdaptivePAProcessor.hpp +++ b/src/libslic3r/GCode/AdaptivePAProcessor.hpp @@ -11,7 +11,6 @@ #include #include #include -#include #include "AdaptivePAInterpolator.hpp" namespace Slic3r { @@ -33,7 +32,7 @@ public: * * @param gcodegen A reference to the GCode object that generates the G-code. */ - AdaptivePAProcessor(GCode &gcodegen, const std::vector &tools_used); + AdaptivePAProcessor(GCode &gcodegen); /** * @brief Processes a layer of G-code and applies adaptive pressure advance. @@ -70,28 +69,25 @@ public: private: GCode &m_gcodegen; ///< Reference to the GCode object. - std::unordered_map> m_AdaptivePAInterpolators; ///< Map between Interpolator objects and tool ID's + std::unordered_map> m_AdaptivePAInterpolators; ///< Map between Interpolator objects and filament config indices (null when adaptive PA is off) const PrintConfig &m_config; ///< Reference to the print configuration. double m_last_predicted_pa; ///< Last predicted pressure advance value. double m_max_next_feedrate; ///< Maximum feed rate (speed) for the upcomming island. If no speed is found, the previous island speed is used. double m_next_feedrate; ///< First feed rate (speed) for the upcomming island. double m_current_feedrate; ///< Current, latest feedrate. - int m_last_extruder_id; ///< Last used extruder ID. + int m_last_config_index; ///< Filament config index of the last PA_CHANGE tag. std::regex m_pa_change_pattern; ///< Regular expression to detect PA_CHANGE pattern. std::regex m_g1_f_pattern; ///< Regular expression to detect G1 F pattern. std::smatch m_match; ///< Match results for regular expressions. /** - * @brief Get the PA interpolator attached to the specified tool ID. + * @brief Get the PA interpolator attached to the specified filament config index. * - * This method manually sets the adaptive PA internally held value. - * Call this when changing tools or in any other case where the internally assumed last PA value may be incorrect - * - * @param An integer with the tool ID for which the PA interpolation model is to be returned. - * @return The Adaptive PA Interpolator object corresponding to that tool. + * @param config_index The filament config index (one per filament and extruder variant) for which the PA interpolation model is to be returned. + * @return The Adaptive PA Interpolator object corresponding to that index, or nullptr when adaptive PA is off for it. */ - AdaptivePAInterpolator* getInterpolator(unsigned int tool_id); + AdaptivePAInterpolator* getInterpolator(unsigned int config_index); }; } // namespace Slic3r diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index e55b89212e..7f6e9c67d5 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -18,7 +18,7 @@ namespace Slic3r { -CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0), m_current_nozzle(0) +CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_gcodegen(gcodegen), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0), m_current_nozzle(0) { this->reset(gcodegen.writer().get_position()); @@ -737,10 +737,12 @@ std::string CoolingBuffer::apply_layer_cooldown( &ironing_fan_control, &ironing_fan_speed ](bool immediately_apply) { #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_current_extruder) - float fan_min_speed = EXTRUDER_CONFIG(fan_min_speed); + // The per-variant options take the extruder variant the filament prints with on this layer + const size_t config_index = m_gcodegen.get_filament_config_index(m_current_extruder, layer_id); + float fan_min_speed = m_config.fan_min_speed.get_at(config_index); float fan_speed_new = EXTRUDER_CONFIG(reduce_fan_stop_start_freq) ? fan_min_speed : 0; //BBS - int additional_fan_speed_new = EXTRUDER_CONFIG(additional_cooling_fan_speed); + int additional_fan_speed_new = m_config.additional_cooling_fan_speed.get_at(config_index); int close_fan_the_first_x_layers = EXTRUDER_CONFIG(close_fan_the_first_x_layers); // Is the fan speed ramp enabled? int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); @@ -776,7 +778,7 @@ std::string CoolingBuffer::apply_layer_cooldown( // additional_fan_speed_new is left at its configured value (auxiliary fan is independent of the // part-cooling override). } else if (int(layer_id) >= close_fan_the_first_x_layers) { - float fan_max_speed = EXTRUDER_CONFIG(fan_max_speed); + float fan_max_speed = m_config.fan_max_speed.get_at(config_index); float slow_down_layer_time = float(EXTRUDER_CONFIG(slow_down_layer_time)); float fan_cooling_layer_time = float(EXTRUDER_CONFIG(fan_cooling_layer_time)); //BBS: always enable the fan speed interpolation according to layer time diff --git a/src/libslic3r/GCode/CoolingBuffer.hpp b/src/libslic3r/GCode/CoolingBuffer.hpp index 9b0a5ab9df..742b8f78b7 100644 --- a/src/libslic3r/GCode/CoolingBuffer.hpp +++ b/src/libslic3r/GCode/CoolingBuffer.hpp @@ -54,6 +54,8 @@ private: // Referencs GCode::m_config, which is FullPrintConfig. While the PrintObjectConfig slice of FullPrintConfig is being modified, // the PrintConfig slice of FullPrintConfig is constant, thus no thread synchronization is required. const PrintConfig &m_config; + // Resolves the filament config index of the per-variant options. + const GCode &m_gcodegen; unsigned int m_current_extruder; unsigned int m_current_nozzle; //BBS: current fan speed diff --git a/src/libslic3r/GCode/PreciseSeam.cpp b/src/libslic3r/GCode/PreciseSeam.cpp new file mode 100644 index 0000000000..378ab2d2d3 --- /dev/null +++ b/src/libslic3r/GCode/PreciseSeam.cpp @@ -0,0 +1,1353 @@ +#include "PreciseSeam.hpp" +#include "SeamPlacer.hpp" +#include "libslic3r/BoundingBox.hpp" +#include +#include +#include + +namespace Slic3r { +namespace PreciseSeam { + +// Import EnforcedBlockedSeamPoint from SeamPlacerImpl namespace for convenience +using SeamPlacerImpl::EnforcedBlockedSeamPoint; + +// Machine precision for checking exact coordinate matching (squared distance) +// Ideally, intersection points should match perimeter vertices bitwise, +// but we account for possible machine rounding errors in Clipper calculations +// Actual deviations: maximum ~0.27, using 2.5 with margin (nanometers) +static constexpr double MACHINE_PRECISION_SQUARED = 2.5; + +// Tolerance for checking proximity when inserting seam points into perimeter +static const coord_t TOLERANCE_LINEAR = scale_(0.001); // 1.0 micrometers +static const coord_t TOLERANCE_SQUARED = TOLERANCE_LINEAR * TOLERANCE_LINEAR; + +// Find common segment between intersection polygon and object perimeter +// +// REQUIREMENTS: +// - intersection_polygon must be converted to CCW (counter-clockwise) beforehand +// - perimeter_polygon must be converted to CCW (counter-clockwise) beforehand +// +// Parameters: +// intersection_polygon - intersection area polygon (result of intersection()), CCW orientation +// perimeter_polygon - object outline (outer perimeter), CCW orientation +// modifier_polygon - modifier that formed the intersection +// +// Returns: +// SegmentData - longest continuous segment with point correspondence +// std::nullopt - if segment not found (< 2 points) or error +// +static std::optional common_segment_in_intersection( + const Polygon &intersection_polygon, + const Polygon &perimeter_polygon, + PreciseSeamWarnings* warnings = nullptr) +{ + const size_t isect_n = intersection_polygon.points.size(); + const size_t perim_n = perimeter_polygon.points.size(); + + // Check for empty polygons + if (isect_n == 0 || perim_n == 0) { + return std::nullopt; + } + + // Minimum 2 points required to form segment + if (isect_n < 2) { + return std::nullopt; + } + + // ============================================================ + // STEP 1: Project all intersection points onto perimeter + // ============================================================ + + struct PointProjection { + double dist_squared; // Squared distance to perimeter + size_t edge_index; // Edge/vertex index of perimeter + bool on_perimeter; // Whether point lies on perimeter (within machine precision) + }; + + std::vector projections; + projections.reserve(isect_n); + + // Project each intersection point onto perimeter + for (size_t i = 0; i < isect_n; ++i) { + size_t edge_idx; + const Point proj_point = perimeter_polygon.point_projection(intersection_polygon.points[i], &edge_idx); + const double dist_sq = (intersection_polygon.points[i] - proj_point).cast().squaredNorm(); + + const auto invalid = std::numeric_limits::max(); + if (edge_idx == invalid) { + // Projection error - point does not belong to perimeter + projections.push_back({dist_sq, edge_idx, false}); + } else { + // Check whether point lies on perimeter (within machine precision) + bool on_perim = (dist_sq <= MACHINE_PRECISION_SQUARED); + projections.push_back({dist_sq, edge_idx, on_perim}); + } + } + + // ============================================================ + // STEP 2: Find all continuous segments of points on perimeter + // ============================================================ + + std::vector processed(isect_n, false); // Processed point flags + std::vector> segments; // Found segments (point indices) + + for (size_t start_idx = 0; start_idx < isect_n; ++start_idx) { + // Skip processed or non-perimeter points + if (processed[start_idx] || !projections[start_idx].on_perimeter) { + continue; + } + + // Found point on perimeter - search for continuous segment + std::vector backward_indices; // Point indices backward from start_idx + std::vector forward_indices; // Point indices forward from start_idx (including start_idx) + + // Add start point to forward + forward_indices.push_back(start_idx); + processed[start_idx] = true; + + // Backward traversal (only if start_idx == 0, for wrap-around handling) + if (start_idx == 0) { + for (size_t offset = 1; offset < isect_n; ++offset) { + size_t curr_idx = (start_idx + isect_n - offset) % isect_n; + + // Stop if point already processed or not on perimeter + if (processed[curr_idx] || !projections[curr_idx].on_perimeter) { + break; + } + + backward_indices.push_back(curr_idx); + processed[curr_idx] = true; + } + } + + // Forward traversal from start_idx + for (size_t offset = 1; offset < isect_n; ++offset) { + size_t curr_idx = (start_idx + offset) % isect_n; + + // Stop if point already processed or not on perimeter + if (processed[curr_idx] || !projections[curr_idx].on_perimeter) { + break; + } + + forward_indices.push_back(curr_idx); + processed[curr_idx] = true; + } + + // Merge backward (in reverse order) + forward into one segment + std::vector segment_indices; + segment_indices.reserve(backward_indices.size() + forward_indices.size()); + + // Add backward in reverse order + segment_indices.insert( + segment_indices.end(), + backward_indices.rbegin(), + backward_indices.rend() + ); + + // Add forward + segment_indices.insert( + segment_indices.end(), + forward_indices.begin(), + forward_indices.end() + ); + + // Save found segment + segments.push_back(std::move(segment_indices)); + } + + // ============================================================ + // STEP 3: Select longest segment + // ============================================================ + + // If no segments found + if (segments.empty()) { + return std::nullopt; + } + + // Search for segment with maximum point count + auto it_longest = std::max_element( + segments.begin(), + segments.end(), + [](const auto &a, const auto &b) { return a.size() < b.size(); } + ); + + const std::vector &longest_segment = *it_longest; + + // Check minimum requirement: >= 2 points + if (longest_segment.size() < 2) { + return std::nullopt; + } + + // Special case: all intersection vertices lie on perimeter + if (longest_segment.size() == isect_n) { + // Threshold for edge midpoint check: increased by 0.5 due to rounding error in integer coordinate division + constexpr double EDGE_CENTER_THRESHOLD = MACHINE_PRECISION_SQUARED + 0.5; + + // Check each intersection edge - does its midpoint lie on perimeter + std::vector edges_not_on_perim_indices; + + for (size_t i = 0; i < isect_n; ++i) { + size_t next_i = (i + 1) % isect_n; + + // Calculate edge midpoint i→next_i + const Point &pt1 = intersection_polygon.points[i]; + const Point &pt2 = intersection_polygon.points[next_i]; + Point edge_center( + (pt1.x() + pt2.x()) / 2, + (pt1.y() + pt2.y()) / 2 + ); + + // Project midpoint onto perimeter + const Point proj = perimeter_polygon.point_projection(edge_center); + const double dist_sq = (edge_center - proj).cast().squaredNorm(); + + // Check if midpoint lies on perimeter (accounting for rounding error) + if (dist_sq > EDGE_CENTER_THRESHOLD) { + edges_not_on_perim_indices.push_back(i); + } + } + + // Analyze results + if (edges_not_on_perim_indices.empty()) { + // All edges on perimeter → modifier fully contains perimeter → not suitable for seam placement + if (warnings) + warnings->full_containment.store(true, std::memory_order_relaxed); + return std::nullopt; + } + + // Edges not on perimeter act as "cuts" that split the circular ring of vertices + // into separate on-perimeter segments. For k cuts there are k segments. + // We iterate over consecutive pairs of cuts and pick the longest segment. + const size_t k = edges_not_on_perim_indices.size(); + size_t best_start = 0; + size_t best_length = 0; + + for (size_t i = 0; i < k; ++i) { + size_t gap_cur = edges_not_on_perim_indices[i]; + size_t gap_next = edges_not_on_perim_indices[(i + 1) % k]; + + // Segment starts at the vertex right after the current cut + size_t start = (gap_cur + 1) % isect_n; + // Number of vertices from start up to and including the vertex before the next cut + size_t length = (gap_next - gap_cur - 1 + isect_n) % isect_n + 1; + + if (length > best_length) { + best_length = length; + best_start = start; + } + } + + if (best_length < 2) { + return std::nullopt; + } + + // Form SegmentData from the longest on-perimeter segment + SegmentData result; + result.segment.points.reserve(best_length); + result.perimeter_edge_indices.reserve(best_length); + + for (size_t i = 0; i < best_length; ++i) { + size_t idx = (best_start + i) % isect_n; + result.segment.points.push_back(intersection_polygon.points[idx]); + result.perimeter_edge_indices.push_back(projections[idx].edge_index); + } + + return result; + } + + // ============================================================ + // STEP 4: Form SegmentData result + // ============================================================ + + SegmentData result; + result.segment.points.reserve(longest_segment.size()); + result.perimeter_edge_indices.reserve(longest_segment.size()); + + // Fill points and edge_index for each segment point + for (size_t idx : longest_segment) { + result.segment.points.push_back(intersection_polygon.points[idx]); + result.perimeter_edge_indices.push_back(projections[idx].edge_index); + } + + return result; +} + +// Fast search for common segment between intersection polygon and object perimeter +// Hybrid algorithm: first exact coordinate matching, then geometric check +// +// REQUIREMENTS: +// - intersection_polygon must be converted to CCW (counter-clockwise) beforehand +// - perimeter_polygon must be converted to CCW (counter-clockwise) beforehand +// +// Parameters: +// intersection_polygon - intersection area polygon (result of intersection()), CCW orientation +// perimeter_polygon - object outline (outer perimeter), CCW orientation +// +// Returns: +// SegmentData - continuous segment with point correspondence +// std::nullopt - if segment not found (< 2 points) or error +// +static std::optional common_segment_in_intersection_fast( + const Polygon &intersection_polygon, + const Polygon &perimeter_polygon, + PreciseSeamWarnings* warnings = nullptr) +{ + const size_t isect_n = intersection_polygon.points.size(); + const size_t perim_n = perimeter_polygon.points.size(); + + // ============================================================ + // STEP 1: Input data validation + // ============================================================ + + if (isect_n == 0 || perim_n == 0) { + return std::nullopt; + } + + if (isect_n < 2) { + return std::nullopt; + } + + // ============================================================ + // STEP 2: Find first point (exact coordinate match) + // ============================================================ + + // Vectors for forward direction + std::vector forward_intersection_indices; + std::vector forward_edge_indices; + forward_intersection_indices.reserve(isect_n); + forward_edge_indices.reserve(isect_n); + + // Vectors for backward direction + std::vector backward_intersection_indices; + std::vector backward_edge_indices; + backward_intersection_indices.reserve(isect_n); + backward_edge_indices.reserve(isect_n); + + size_t first_isect_idx = 0; // index of first matching point in intersection_polygon + size_t first_perim_idx = 0; // index of first matching point in perimeter_polygon (also edge_index) + bool found_first = false; + + // Search for first exact match (not optimized — expected gain is negligible) + for (size_t i = 0; i < isect_n; ++i) { + const Point &isect_pt = intersection_polygon.points[i]; + + auto it = std::find(perimeter_polygon.points.begin(), + perimeter_polygon.points.end(), + isect_pt); + + if (it != perimeter_polygon.points.end()) { + first_isect_idx = i; + first_perim_idx = std::distance(perimeter_polygon.points.begin(), it); + found_first = true; + + // Add first point to forward vectors + forward_intersection_indices.push_back(i); + forward_edge_indices.push_back(first_perim_idx); + break; + } + } + + // If no matching point found - use full geometric algorithm + if (!found_first) { + return common_segment_in_intersection(intersection_polygon, perimeter_polygon, warnings); + } + + // Sentinel value for an invalid edge_index returned by Polygon::point_projection. + const auto invalid = std::numeric_limits::max(); + + // ============================================================ + // STEP 3: Forward pass (from first point forward) + // ============================================================ + + // Adaptive tracking of position in perimeter (instead of fixed prediction) + size_t next_expected_perim_idx = (first_perim_idx + 1) % perim_n; + + for (size_t offset = 1; offset < isect_n; ++offset) { + size_t curr_isect_idx = (first_isect_idx + offset) % isect_n; + const Point &curr_isect_pt = intersection_polygon.points[curr_isect_idx]; + const Point &expected_pt = perimeter_polygon.points[next_expected_perim_idx]; + + // First check exact match with expected position + if (curr_isect_pt == expected_pt) { + forward_intersection_indices.push_back(curr_isect_idx); + forward_edge_indices.push_back(next_expected_perim_idx); + next_expected_perim_idx = (next_expected_perim_idx + 1) % perim_n; + continue; + } + + // Exact match not found - check geometrically + size_t edge_idx; + const Point proj_point = perimeter_polygon.point_projection(curr_isect_pt, &edge_idx); + const double dist_sq = (curr_isect_pt - proj_point).cast().squaredNorm(); + + if (edge_idx == invalid || dist_sq > MACHINE_PRECISION_SQUARED) { + // Point not on perimeter - break forward pass + break; + } + + // Point on perimeter - add and adjust expected position + forward_intersection_indices.push_back(curr_isect_idx); + forward_edge_indices.push_back(edge_idx); + next_expected_perim_idx = (edge_idx + 1) % perim_n; + } + + // ============================================================ + // STEP 4: Backward pass + // ============================================================ + + // Optimization: backward can find maximum (isect_n - forward_count) points + size_t forward_count = forward_intersection_indices.size(); + size_t max_backward_iterations = isect_n - forward_count; + + // Adaptive tracking of position in perimeter for backward direction + next_expected_perim_idx = (first_perim_idx + perim_n - 1) % perim_n; + + for (size_t offset = 1; offset <= max_backward_iterations; ++offset) { + size_t curr_isect_idx = (first_isect_idx + isect_n - offset) % isect_n; + const Point &curr_isect_pt = intersection_polygon.points[curr_isect_idx]; + const Point &expected_pt = perimeter_polygon.points[next_expected_perim_idx]; + + // First check exact match with expected position + if (curr_isect_pt == expected_pt) { + backward_intersection_indices.push_back(curr_isect_idx); + backward_edge_indices.push_back(next_expected_perim_idx); + next_expected_perim_idx = (next_expected_perim_idx + perim_n - 1) % perim_n; + continue; + } + + // Exact match not found - check geometrically + size_t edge_idx; + const Point proj_point = perimeter_polygon.point_projection(curr_isect_pt, &edge_idx); + const double dist_sq = (curr_isect_pt - proj_point).cast().squaredNorm(); + + if (edge_idx == invalid || dist_sq > MACHINE_PRECISION_SQUARED) { + // Point not on perimeter - break backward pass + break; + } + + // Point on perimeter - add and adjust expected position + backward_intersection_indices.push_back(curr_isect_idx); + backward_edge_indices.push_back(edge_idx); + next_expected_perim_idx = (edge_idx + perim_n - 1) % perim_n; + } + + // Check special case: all intersection vertices lie on perimeter + // Use full geometric algorithm (rare case but requires special handling) + size_t total_points = forward_intersection_indices.size() + backward_intersection_indices.size(); + if (total_points == isect_n) { + return common_segment_in_intersection(intersection_polygon, perimeter_polygon, warnings); + } + + // ============================================================ + // STEP 5: Merge backward (reversed) + forward + // ============================================================ + + std::vector continuous_intersection_indices; + std::vector continuous_edge_indices; + + if (backward_intersection_indices.empty()) { + // No backward - just move forward + continuous_intersection_indices = std::move(forward_intersection_indices); + continuous_edge_indices = std::move(forward_edge_indices); + } else { + // Merge: backward (reversed) + forward + size_t total_size = backward_intersection_indices.size() + forward_intersection_indices.size(); + continuous_intersection_indices.reserve(total_size); + continuous_edge_indices.reserve(total_size); + + // Add backward in reverse order + continuous_intersection_indices.insert( + continuous_intersection_indices.end(), + backward_intersection_indices.rbegin(), + backward_intersection_indices.rend() + ); + continuous_edge_indices.insert( + continuous_edge_indices.end(), + backward_edge_indices.rbegin(), + backward_edge_indices.rend() + ); + + // Add forward + continuous_intersection_indices.insert( + continuous_intersection_indices.end(), + forward_intersection_indices.begin(), + forward_intersection_indices.end() + ); + continuous_edge_indices.insert( + continuous_edge_indices.end(), + forward_edge_indices.begin(), + forward_edge_indices.end() + ); + } + + // ============================================================ + // STEP 6: Check minimum size and special cases + // ============================================================ + + if (continuous_intersection_indices.size() < 2) { + return std::nullopt; + } + + // ============================================================ + // STEP 7: Form SegmentData result + // ============================================================ + + SegmentData result; + result.segment.points.reserve(continuous_intersection_indices.size()); + result.perimeter_edge_indices.reserve(continuous_intersection_indices.size()); + + // Fill with original coordinates from intersection_polygon + edge_index + for (size_t i = 0; i < continuous_intersection_indices.size(); ++i) { + size_t idx = continuous_intersection_indices[i]; + result.segment.points.push_back(intersection_polygon.points[idx]); + result.perimeter_edge_indices.push_back(continuous_edge_indices[i]); + } + + return result; +} + +void init_precise_seam_data( + std::vector& strong_volumes_out, + std::vector& weak_volumes_out, + bool& has_strong_out, + const ModelObject* model_object) +{ + // Clear output vectors + strong_volumes_out.clear(); + weak_volumes_out.clear(); + + if (model_object == nullptr) { + has_strong_out = false; + return; + } + + // Collect and categorize precise seam modifiers + for (const ModelVolume* volume : model_object->volumes) { + if (volume->is_precise_seam()) { + ModelVolumeType type = volume->type(); + // Categorization: strong modifiers have priority + if (type == ModelVolumeType::PRECISE_SEAM_CENTER || + type == ModelVolumeType::PRECISE_SEAM_LEFT || + type == ModelVolumeType::PRECISE_SEAM_RIGHT) { + strong_volumes_out.push_back(volume); + } else { + // ENFORCED, BLOCKED, NEUTRAL - weak modifiers (processed later) + weak_volumes_out.push_back(volume); + } + } + } + + has_strong_out = !strong_volumes_out.empty(); + + // Collection already preserves model order, with higher-priority strong modifiers first. + // Weak modifiers use last-write-wins, so apply the higher-priority ones last. + std::reverse(weak_volumes_out.begin(), weak_volumes_out.end()); +} + +// Calculate cumulative lengths for each Polyline point +// Analog of Polygon::parameter_by_length(), adapted for open line +static std::vector polyline_parameter_by_length(const Polyline &polyline) +{ + // Keep scaled-coordinate lengths in double precision for midpoint interpolation. + std::vector lengths(polyline.points.size(), 0.); + for (size_t i = 1; i < polyline.points.size(); ++i) { + lengths[i] = lengths[i-1] + (polyline.points[i] - polyline.points[i-1]).cast().norm(); + } + return lengths; +} + +// Find geometric center coordinates of segment +// Returns: {center coordinates, perimeter vertex index} +// Index is start vertex of edge containing center +static std::optional> segment_center(const SegmentData &data, const Polygon &perimeter_polygon) +{ + const Polyline &segment = data.segment; + + if (segment.points.size() < 2) { + return std::nullopt; // Need at least a line to find middle + } + + std::vector lengths = polyline_parameter_by_length(segment); + if (lengths.empty()) { + return std::nullopt; // Polyline contains no points + } + + double half_length = lengths.back() * 0.5; // Take half of total length + size_t mid_idx = segment.points.size() / 2; + double mid_length = lengths[mid_idx]; + + bool found = false; + size_t start_idx = 0; + size_t end_idx = 0; + + if (mid_length < half_length) { + // Go right (to end) + for (size_t i = mid_idx; i < segment.points.size() - 1; ++i) { + if (lengths[i] <= half_length && half_length < lengths[i+1]) { + start_idx = i; // Fix left point of segment + end_idx = i + 1; // Fix right point of segment + found = true; + break; + } + } + } else if (mid_length > half_length) { + // Go left (to start) + for (size_t i = mid_idx; i > 0; --i) { + if (lengths[i-1] <= half_length && half_length < lengths[i]) { + start_idx = i - 1; // Take neighboring point on left + end_idx = i; // And nearest on right + found = true; + break; + } + } + } else { + // Middle sits exactly at vertex + start_idx = mid_idx; + end_idx = (mid_idx + 1) % segment.points.size(); // use next point (wrap-around) + found = true; + } + + if (!found) { + return std::nullopt; // Didn't find suitable segment + } + + const Point &p1 = segment.points[start_idx]; + const Point &p2 = segment.points[end_idx]; + + double local_mid_length = half_length - lengths[start_idx]; + double edge_length = lengths[end_idx] - lengths[start_idx]; + + Point mid_point; + if (edge_length <= 0.0) { + mid_point = p1; // Degenerate case, take start point + } else { + double k = local_mid_length / edge_length; + mid_point = p1 + (k * (p2 - p1).cast()).cast(); // Linear interpolation + } + + // Clipper may merge several collinear perimeter edges into one segment edge. + // Locate the midpoint on the original perimeter instead of reusing the start's edge. + size_t edge_idx; + const Point projected_midpoint = perimeter_polygon.point_projection(mid_point, &edge_idx); + if (edge_idx == std::numeric_limits::max()) + return std::nullopt; + + return std::make_pair(projected_midpoint, edge_idx); +} + +// Find coordinates of left (first) point of segment +// Returns: {first point coordinates, perimeter vertex index} +// Index is start vertex of edge containing first point +static std::optional> segment_left(const SegmentData &data) +{ + if (data.segment.points.empty()) { + return std::nullopt; + } + + return std::make_pair(data.segment.points[0], data.perimeter_edge_indices[0]); +} + +// Find coordinates of right (last) point of segment +// Returns: {last point coordinates, perimeter vertex index} +// Index is start vertex of edge containing last point +static std::optional> segment_right(const SegmentData &data) +{ + if (data.segment.points.empty()) { + return std::nullopt; + } + + size_t last_idx = data.segment.points.size() - 1; + return std::make_pair(data.segment.points[last_idx], data.perimeter_edge_indices[last_idx]); +} + +// Insert point into perimeter with proximity check to existing vertices +// If point is close to vertex (< TOLERANCE_SQUARED) - use existing vertex +// Returns pair: {final coordinates, point index in polygon} +// edge_start_idx is start vertex of edge containing point +static std::optional> insert_point_into_perimeter( + const Point &point, + size_t edge_start_idx, + Polygon &perimeter_polygon +) +{ + // Check input data + if (perimeter_polygon.points.size() < 3) { + return std::nullopt; // Polygon must be at least a triangle + } + + size_t perim_max = perimeter_polygon.points.size(); + + // Determine edge start and end + size_t vtx_start = edge_start_idx; + size_t vtx_end = (edge_start_idx + 1) % perim_max; + + const Point &perim_p_start = perimeter_polygon.points[vtx_start]; + const Point &perim_p_end = perimeter_polygon.points[vtx_end]; + + // Check proximity to edge vertices + coord_t dist_sq_start = (point - perim_p_start).squaredNorm(); + if (dist_sq_start < TOLERANCE_SQUARED) { + return std::make_pair(perim_p_start, vtx_start); + } + + coord_t dist_sq_end = (point - perim_p_end).squaredNorm(); + if (dist_sq_end < TOLERANCE_SQUARED) { + return std::make_pair(perim_p_end, vtx_end); + } + + // Insert point into perimeter + // IMPORTANT: Special handling for the last edge to preserve indexing for subsequent insertions. + // If this is the last edge (edge_start_idx == perim_max - 1), we append to the end instead of + // inserting at position 0 (which would shift all indices). This allows sorting points by + // descending arc length and inserting them without invalidating previously computed indices. + size_t insert_pos; + if (edge_start_idx == perim_max - 1) { + // Last edge: add to end of vector + perimeter_polygon.points.push_back(point); + insert_pos = perimeter_polygon.points.size() - 1; + } else { + // Regular edge: insert before end vertex + insert_pos = vtx_end; + perimeter_polygon.points.insert( + perimeter_polygon.points.begin() + insert_pos, + point + ); + } + + return std::make_pair(perimeter_polygon.points[insert_pos], insert_pos); +} + +// Insert new point at distance TOLERANCE_LINEAR from specified perimeter vertex +// Insertion direction specified by direction parameter: +1 = after vertex, -1 = before vertex +// If target edge length < 2*TOLERANCE_LINEAR, insertion not performed (new point would be too close to edge end) +// Returns true if point was inserted, false otherwise +// point_idx is index of perimeter vertex from which insertion is performed +static bool refine_at_vertex( + size_t point_idx, + int direction, + Polygon &perimeter_polygon +) +{ + // Check input data + if (perimeter_polygon.points.size() < 3) { + return false; // Polygon must be at least a triangle + } + + if (direction != 1 && direction != -1) { + return false; // Direction must be +1 or -1 + } + + size_t perim_max = perimeter_polygon.points.size(); + + // Determine target edge based on direction + size_t edge_start_idx, edge_end_idx; + + if (direction == 1) { + // Direction +1: insertion AFTER point_idx (edge point_idx → point_idx+1) + edge_start_idx = point_idx; + edge_end_idx = (point_idx + 1) % perim_max; + } else { + // Direction -1: insertion BEFORE point_idx (edge point_idx-1 → point_idx) + edge_start_idx = (point_idx + perim_max - 1) % perim_max; + edge_end_idx = point_idx; + } + + const Point &edge_start = perimeter_polygon.points[edge_start_idx]; + const Point &edge_end = perimeter_polygon.points[edge_end_idx]; + + // Calculate edge length + Vec2d edge_vector = (edge_end - edge_start).cast(); + double edge_length = edge_vector.norm(); + + // Check if edge is long enough for insertion + // New point must be at distance TOLERANCE_LINEAR from start + // and at distance >= TOLERANCE_LINEAR from end + if (edge_length < 2.0 * TOLERANCE_LINEAR) { + return false; // Edge too short - new point would be too close to end + } + + // Calculate new point coordinates: edge_start + TOLERANCE_LINEAR * direction_normalized + Vec2d direction_normalized = edge_vector / edge_length; + // Place helper point near point_idx: after it for +1, before it for -1 + auto offset = (TOLERANCE_LINEAR * direction_normalized).cast(); + Point new_point = (direction == 1) + ? Point(edge_start + offset) + : Point(edge_end - offset); + + // Insert point into perimeter + // IMPORTANT: Special handling of last edge to preserve indexing for subsequent insertions. + // If this is last edge (edge_start_idx == perim_max - 1), add point to end of vector + // instead of inserting at position 0 (which would shift all indices). This allows sorting points + // by descending arc length and inserting them without invalidating previously computed indices. + if (edge_start_idx == perim_max - 1) { + // Last edge: add to end of vector + perimeter_polygon.points.push_back(new_point); + } else { + // Regular edge: insert before end vertex + perimeter_polygon.points.insert( + perimeter_polygon.points.begin() + edge_end_idx, + new_point + ); + } + + return true; +} + +// Insert strong seam point into perimeter polygon +std::optional insert_strong_seam_point( + const std::vector &strong_volumes, + Polygon &polygon, + const Layer *layer, + const ModifierSlicesCache &slices_cache, + PreciseSeamWarnings* warnings) +{ + if (strong_volumes.empty() || layer == nullptr) { + return std::nullopt; + } + + // layer->id() is offset by raft layer count, but modifier_slices is 0-based + // (built from PrintObject::layers() via slice_single_volume). Subtract raft + // offset to get the correct index into the cache. + const size_t raft_layers = layer->object()->slicing_parameters().raft_layers(); + size_t layer_id = layer->id() - raft_layers; + + // Reject disjoint bounds before running polygon clipping; touching bounds still overlap. + const BoundingBox perimeter_bbox(polygon.points); + + // Iterate through strong modifiers in hierarchy order + for (const ModelVolume* modifier_volume : strong_volumes) { + // Look up pre-sliced polygons from cache (sliced once in SeamPlacer::init). + // TODO: slice_single_volume() converts ExPolygons to flat Polygons, losing + // the association between outer contours and their holes. This makes correct + // handling of multiply-connected modifier regions (e.g. a torus cross-section) + // impossible. Consider a variant returning std::vector and adapting + // the algorithm to work with multiply-connected domains. + auto it = slices_cache.find(modifier_volume); + if (it == slices_cache.end()) + continue; // modifier not in cache (should not happen) + const std::vector &modifier_slices = it->second; + + // Check if this layer has slices for this modifier + if (layer_id >= modifier_slices.size()) { + continue; // No slices for this layer + } + + const Polygons &modifier_polygons = modifier_slices[layer_id]; + + // Check for multiply-connected regions (holes = CW polygons). + // slice_single_volume() flattens ExPolygons into Polygons, but preserves + // orientation: CCW = outer contour, CW = hole. If any CW polygon is present, + // the modifier is multiply-connected and cannot be processed correctly. + bool has_holes = std::any_of(modifier_polygons.begin(), modifier_polygons.end(), + [](const Polygon &p) { return p.is_clockwise(); }); + if (has_holes) { + if (warnings) + warnings->multiply_connected.store(true, std::memory_order_relaxed); + continue; + } + + // Iterate through all polygons of the modifier on this layer + // After finding a match, check if remaining modifier polygons also intersect the perimeter. + // Strong modifiers process only one intersection (one seam per perimeter), so any additional + // intersections from unprocessed polygons indicate a multiple-intersection situation. + auto check_remaining_polygons = [&](size_t current_idx) { + if (warnings && !warnings->multiple_intersections.load(std::memory_order_relaxed)) { + // Refinement may have rounded newly inserted points, so use the current bounds. + const BoundingBox refined_bbox(polygon.points); + for (size_t j = current_idx + 1; j < modifier_polygons.size(); ++j) { + if (!refined_bbox.overlap(BoundingBox(modifier_polygons[j].points))) + continue; + if (!intersection(Polygons{polygon}, Polygons{modifier_polygons[j]}).empty()) { + warnings->multiple_intersections.store(true, std::memory_order_relaxed); + break; // one extra intersection is enough to trigger the warning + } + } + } + }; + for (size_t modifier_polygon_idx = 0; modifier_polygon_idx < modifier_polygons.size(); ++modifier_polygon_idx) { + const Polygon &modifier_polygon = modifier_polygons[modifier_polygon_idx]; + if (!perimeter_bbox.overlap(BoundingBox(modifier_polygon.points))) + continue; + // Find intersection with perimeter + Polygons intersection_polygons = intersection(Polygons{polygon}, Polygons{modifier_polygon}); + + // Multiple intersection polygons = modifier crosses perimeter in several places + if (warnings && intersection_polygons.size() > 1) + warnings->multiple_intersections.store(true, std::memory_order_relaxed); + // Diff check: modifier minus perimeter yields >1 polygon = through-body intersection. + // However, if any diff polygon is CW, it is a hole left by full containment + // (modifier fully covers perimeter), not a real through-body case. + // Full containment is detected separately in common_segment_in_intersection(). + if (warnings && !warnings->through_body.load(std::memory_order_relaxed)) { + Polygons diff_polygons = diff(Polygons{modifier_polygon}, Polygons{polygon}); + if (diff_polygons.size() > 1) { + bool has_cw = std::any_of(diff_polygons.begin(), diff_polygons.end(), + [](const Polygon &p) { return p.is_clockwise(); }); + if (!has_cw) + warnings->through_body.store(true, std::memory_order_relaxed); + } + } + + // Process each intersection polygon + for (Polygon &intersection_polygon : intersection_polygons) { + // Convert intersection_polygon to CCW to guarantee same traversal direction as perimeter + intersection_polygon.make_counter_clockwise(); + + // Try to find perimeter segment in this intersection + std::optional segment = common_segment_in_intersection_fast( + intersection_polygon, + polygon, + warnings + ); + + if (!segment.has_value()) { + continue; + } + + // Select target point finder based on modifier type + std::optional> target; + switch (modifier_volume->type()) { + case ModelVolumeType::PRECISE_SEAM_CENTER: target = segment_center(segment.value(), polygon); break; + case ModelVolumeType::PRECISE_SEAM_LEFT: target = segment_left(segment.value()); break; + case ModelVolumeType::PRECISE_SEAM_RIGHT: target = segment_right(segment.value()); break; + default: continue; + } + + if (!target.has_value()) + continue; + + // Insert target point into perimeter with tolerance check + std::optional> result = insert_point_into_perimeter( + target->first, // target_point + target->second, // insert_idx + polygon + ); + + if (!result.has_value()) + continue; + + // Add additional points on both sides to create transition zone. + // +1 must be called before -1: reverse order shifts result->second and breaks insertion. + refine_at_vertex(result->second, +1, polygon); + refine_at_vertex(result->second, -1, polygon); + + check_remaining_polygons(modifier_polygon_idx); + return result->first; + } + } + } + + // No matching segment found or insertion failed + return std::nullopt; +} + +// Convert ModelVolumeType of weak modifier to EnforcedBlockedSeamPoint. +// Precondition: called only with weak precise-seam types (filtered via is_precise_seam_weak()). +// Exhaustive switch (no default) so -Wswitch flags any future PRECISE_SEAM_* additions. +static EnforcedBlockedSeamPoint convert_weak_modifier_type(ModelVolumeType type) { + switch (type) { + case ModelVolumeType::PRECISE_SEAM_ENFORCED: + return EnforcedBlockedSeamPoint::Enforced; + case ModelVolumeType::PRECISE_SEAM_BLOCKED: + return EnforcedBlockedSeamPoint::Blocked; + case ModelVolumeType::PRECISE_SEAM_NEUTRAL: + return EnforcedBlockedSeamPoint::Neutral; + // Non-weak types are unreachable by precondition; listed to keep the switch exhaustive. + case ModelVolumeType::INVALID: + case ModelVolumeType::MODEL_PART: + case ModelVolumeType::NEGATIVE_VOLUME: + case ModelVolumeType::PARAMETER_MODIFIER: + case ModelVolumeType::SUPPORT_BLOCKER: + case ModelVolumeType::SUPPORT_ENFORCER: + case ModelVolumeType::PRECISE_SEAM_CENTER: + case ModelVolumeType::PRECISE_SEAM_LEFT: + case ModelVolumeType::PRECISE_SEAM_RIGHT: + break; + } + assert(false && "convert_weak_modifier_type called with non-weak type"); + return EnforcedBlockedSeamPoint::Neutral; +} + +// Collect all weak modifier segments for given perimeter +// Process weak modifiers (ENFORCED/BLOCKED/NEUTRAL) and collect segment boundaries +// Also insert boundary points into perimeter polygon (sorted by descending arc length) +// Split enforced edges into small segments (≤ enforcer_oversampling_distance) for precise seam placement +// Return ordered vector of segments with updated coordinates (in same order as weak_volumes list) +std::vector collect_weak_modifier_segments( + const std::vector &weak_volumes, + Polygon &polygon, + const Layer *layer, + const ModifierSlicesCache &slices_cache, + PreciseSeamWarnings* warnings) +{ + std::vector result; + + // Check input parameters + if (weak_volumes.empty() || layer == nullptr) { + return result; // Empty vector + } + + // layer->id() is offset by raft layer count, but modifier_slices is 0-based + // (built from PrintObject::layers() via slice_single_volume). Subtract raft + // offset to get the correct index into the cache. + const size_t raft_layers = layer->object()->slicing_parameters().raft_layers(); + size_t layer_id = layer->id() - raft_layers; + + // The perimeter is not modified until all weak segments have been collected. + const BoundingBox perimeter_bbox(polygon.points); + + // Iterate through all weak modifiers in hierarchy order + for (const ModelVolume* modifier_volume : weak_volumes) { + // Look up pre-sliced polygons from cache (sliced once in SeamPlacer::init). + // TODO: slice_single_volume() converts ExPolygons to flat Polygons, losing + // the association between outer contours and their holes. This makes correct + // handling of multiply-connected modifier regions (e.g. a torus cross-section) + // impossible. Consider a variant returning std::vector and adapting + // the algorithm to work with multiply-connected domains. + auto it = slices_cache.find(modifier_volume); + if (it == slices_cache.end()) + continue; // modifier not in cache (should not happen) + const std::vector &modifier_slices = it->second; + + // Check if slices exist for given layer + if (layer_id >= modifier_slices.size()) { + continue; // No slices for this layer + } + + const Polygons &modifier_polygons = modifier_slices[layer_id]; + + // Check for multiply-connected regions (holes = CW polygons). + // slice_single_volume() flattens ExPolygons into Polygons, but preserves + // orientation: CCW = outer contour, CW = hole. If any CW polygon is present, + // the modifier is multiply-connected and cannot be processed correctly. + bool has_holes = std::any_of(modifier_polygons.begin(), modifier_polygons.end(), + [](const Polygon &p) { return p.is_clockwise(); }); + if (has_holes) { + if (warnings) + warnings->multiply_connected.store(true, std::memory_order_relaxed); + continue; + } + + // Iterate through all modifier polygons on this layer + for (const Polygon &modifier_polygon : modifier_polygons) { + // Preserve touching and contained pairs for the existing clipping and warning logic. + if (!perimeter_bbox.overlap(BoundingBox(modifier_polygon.points))) + continue; + // Find intersection with perimeter + Polygons intersection_polygons = intersection(Polygons{polygon}, Polygons{modifier_polygon}); + + // Note: intersection_polygons.size() > 1 is NOT flagged as a warning here. + // For weak modifiers, multiple intersection polygons are expected (the modifier + // may legitimately cross the perimeter in several places). + // Only through-body intersections (detected by diff below) are abnormal. + + // Diff check: if modifier minus perimeter yields >1 polygon, the modifier + // passes through the model body, creating a through-body intersection. + // CW polygon in diff = hole from full containment, not through-body. + // Full containment is detected separately in common_segment_in_intersection(). + if (warnings && !warnings->through_body.load(std::memory_order_relaxed)) { + Polygons diff_polygons = diff(Polygons{modifier_polygon}, Polygons{polygon}); + if (diff_polygons.size() > 1) { + bool has_cw = std::any_of(diff_polygons.begin(), diff_polygons.end(), + [](const Polygon &p) { return p.is_clockwise(); }); + if (!has_cw) + warnings->through_body.store(true, std::memory_order_relaxed); + } + } + + // Process each intersection polygon + for (Polygon &intersection_polygon : intersection_polygons) { + // Convert intersection_polygon to CCW to guarantee same traversal direction as perimeter + intersection_polygon.make_counter_clockwise(); + + // Search for perimeter segment in this intersection + std::optional segment = common_segment_in_intersection_fast( + intersection_polygon, + polygon, + warnings + ); + + if (!segment.has_value()) { + continue; // Segment not found + } + + // Get left (first) point of segment + std::optional> left = segment_left(segment.value()); + + // Get right (last) point of segment + std::optional> right = segment_right(segment.value()); + + // If both boundaries found, add segment to result + if (left.has_value() && right.has_value()) { + result.push_back({ + convert_weak_modifier_type(modifier_volume->type()), // Type: Enforced/Blocked/Neutral + left->first, // Left point coordinates + left->second, // Perimeter vertex index for left point + right->first, // Right point coordinates + right->second // Perimeter vertex index for right point + }); + } + } + } + } + + // If no segments, return empty vector + if (result.empty()) { + return result; + } + + // Insert boundary points into perimeter polygon + // Sort points by descending arc length to avoid breaking indexing + + // 1. Parameterize polygon: calculate cumulative lengths for each vertex + std::vector cumulative_lengths(polygon.points.size() + 1); + cumulative_lengths[0] = 0.0; + for (size_t i = 0; i < polygon.points.size(); ++i) { + size_t next_i = (i + 1) % polygon.points.size(); + double edge_length = (polygon.points[next_i] - polygon.points[i]).cast().norm(); + cumulative_lengths[i + 1] = cumulative_lengths[i] + edge_length; + } + + // 2. Create helper vector for sorting: {segment index, left/right point, arc length} + struct PointToInsert { + size_t segment_idx; // Index in result + bool is_left; // true = left point, false = right point + double arc_length; // Arc length from perimeter start + }; + std::vector points_to_insert; + points_to_insert.reserve(result.size() * 2); + + for (size_t seg_idx = 0; seg_idx < result.size(); ++seg_idx) { + const WeakModifierSegment &seg = result[seg_idx]; + + // Left point + double left_base = cumulative_lengths[seg.left_idx]; + double left_offset = (seg.left_point - polygon.points[seg.left_idx]).cast().norm(); + points_to_insert.push_back({seg_idx, true, left_base + left_offset}); + + // Right point + double right_base = cumulative_lengths[seg.right_idx]; + double right_offset = (seg.right_point - polygon.points[seg.right_idx]).cast().norm(); + points_to_insert.push_back({seg_idx, false, right_base + right_offset}); + } + + // 3. Sort by descending arc length (insert distant points first) + std::sort(points_to_insert.begin(), points_to_insert.end(), + [](const PointToInsert &a, const PointToInsert &b) { + return a.arc_length > b.arc_length; + }); + + // 4. Insert points in descending arc length order + std::vector segment_valid(result.size(), true); + bool any_insertion_failed = false; + + for (const PointToInsert &pt : points_to_insert) { + WeakModifierSegment &seg = result[pt.segment_idx]; + Point &point_coords = pt.is_left ? seg.left_point : seg.right_point; + size_t edge_idx = pt.is_left ? seg.left_idx : seg.right_idx; + + // Insert point with tolerance check + std::optional> insert_result = + insert_point_into_perimeter(point_coords, edge_idx, polygon); + + if (insert_result.has_value()) { + // Update coordinates in result (if point coincided with existing vertex, take its coordinates) + point_coords = insert_result->first; + } else { + // Failed to insert point - segment becomes invalid + segment_valid[pt.segment_idx] = false; + any_insertion_failed = true; + } + } + + // 5. Remove segments whose boundaries could not be inserted + if (any_insertion_failed) { + // Critical error: boundary point not inserted (shouldn't happen in normal conditions) + BOOST_LOG_TRIVIAL(error) << "PreciseSeam: boundary point insertion failed, performing segment compaction"; + + // Remove invalid segments (array compaction) + size_t write_pos = 0; + for (size_t read_pos = 0; read_pos < result.size(); ++read_pos) { + if (segment_valid[read_pos]) { + if (write_pos != read_pos) { + result[write_pos] = std::move(result[read_pos]); + } + ++write_pos; + } + } + result.resize(write_pos); + } + + // 6. Group coincident boundaries by their snapped vertex, including wraparound to vertex 0. + // Scan original vertices backwards so insertions cannot shift pending vertex indices. + // O(vertices * segments), matching the boundary lookup below; typically only a few segments. + for (size_t poly_idx = polygon.size(); poly_idx-- > 0; ) { + bool refine_before = false; + bool refine_after = false; + for (const WeakModifierSegment &segment : result) { + refine_before |= polygon[poly_idx] == segment.left_point; + refine_after |= polygon[poly_idx] == segment.right_point; + } + // Insert after first: inserting before would shift the current vertex index. + if (refine_after) + refine_at_vertex(poly_idx, +1, polygon); + if (refine_before) + refine_at_vertex(poly_idx, -1, polygon); + } + + // 7. Split edges in enforced zones into segments ≤ enforcer_oversampling_distance + // Determine type pattern for each polygon edge (sequential application of hierarchy) + std::vector edge_types(polygon.size(), EnforcedBlockedSeamPoint::Neutral); + + // Helper lambda: search for point index in modified polygon by coordinates. + // Linear scan is intentional — O(N×M) is acceptable for typical M ≤ 5 weak segments. + auto find_point_index = [&](const Point &pt) -> std::optional { + for (size_t i = 0; i < polygon.size(); ++i) { + if (polygon[i] == pt) return i; + } + return std::nullopt; + }; + + // Apply types sequentially: segments are sorted low-priority-first + // (bottom of object tree first), so higher-priority modifiers overwrite + // lower-priority ones via last-write-wins. + for (const auto &segment : result) { + // Find boundary point indices in modified polygon + std::optional left_idx = find_point_index(segment.left_point); + std::optional right_idx = find_point_index(segment.right_point); + + if (!left_idx.has_value() || !right_idx.has_value()) { + BOOST_LOG_TRIVIAL(error) << "PreciseSeam: boundary point not found in modified polygon, skipping segment"; + continue; + } + + // Set type for edges [left_idx, right_idx] + for (size_t idx = left_idx.value(); ; idx = (idx + 1) % polygon.size()) { + edge_types[idx] = segment.type; + if (idx == right_idx.value()) break; + } + } + + // Split enforced edges into small segments + const double STEP_SCALED = scale_(SeamPlacer::enforcer_oversampling_distance); + + // Collect new list of polygon points with split enforced edges + Points new_points; + new_points.reserve(polygon.size() * 10); // Approximate estimate + + for (size_t i = 0; i < polygon.size(); ++i) { + size_t next_i = (i + 1) % polygon.size(); + Point p_start = polygon[i]; + Point p_end = polygon[next_i]; + + // Add current vertex + new_points.push_back(p_start); + + // Check edge type [i, next_i] + if (edge_types[i] != EnforcedBlockedSeamPoint::Enforced) { + continue; // Not enforced - don't split + } + + // Calculate subdivision parameters + Vec2d edge_vec = (p_end - p_start).cast(); + double edge_length = edge_vec.norm(); + + if (edge_length <= STEP_SCALED) { + continue; // Edge too short - don't split + } + + // Number of segments: ceil(L / S) + size_t num_segments = static_cast(std::ceil(edge_length / STEP_SCALED)); + + // Uniform step: L / num_segments (each segment ≤ S) + double actual_step = edge_length / num_segments; + Vec2d step_vec = edge_vec.normalized() * actual_step; + + // Add intermediate points incrementally + Vec2d current_pos = p_start.cast(); + for (size_t j = 1; j < num_segments; ++j) { + current_pos += step_vec; + new_points.push_back(current_pos.cast()); + } + } + + // Replace polygon points with new ones (with split enforced edges) + polygon.points = std::move(new_points); + + return result; +} + +// Apply weak modifier types to perimeter points based on segment boundaries. +// Find boundary points in refined polygon by coordinates and set types +// for all points inside each segment. +void apply_weak_modifiers_to_perimeter( + const std::vector &weak_segments, + PrintObjectSeamData::LayerSeams &result, + const SeamPlacerImpl::Perimeter &perimeter, + bool &some_point_enforced) +{ + // Get z-coordinate for unscaling boundary points + const float z_coord = result.points[perimeter.start_index].position.z(); + const size_t perimeter_size = perimeter.end_index - perimeter.start_index; + + // Helper lambda: search for point index in result.points by unscaled coordinates. + // Linear scan is intentional — O(N×M) is acceptable for typical M ≤ 5 weak segments. + auto find_point_index = [&](const Point &pt) -> std::optional { + Vec2f unscaled_pt = unscale(pt).cast(); + Vec3f target(unscaled_pt.x(), unscaled_pt.y(), z_coord); + for (size_t i = perimeter.start_index; i < perimeter.end_index; ++i) { + if (result.points[i].position == target) return i - perimeter.start_index; + } + return std::nullopt; + }; + + // Apply weak modifiers sequentially: sorted low-priority-first, + // so higher-priority modifiers (higher in object tree) overwrite via last-write-wins. + for (size_t seg_idx = 0; seg_idx < weak_segments.size(); ++seg_idx) { + const auto &segment = weak_segments[seg_idx]; + + // Find boundary point indices in result.points + std::optional left_idx = find_point_index(segment.left_point); + std::optional right_idx = find_point_index(segment.right_point); + + if (!left_idx.has_value() || !right_idx.has_value()) { + BOOST_LOG_TRIVIAL(error) << "PreciseSeam: boundary point not found in perimeter, skipping segment"; + continue; + } + + // Apply modifier type to range [left_idx, right_idx] with wraparound + for (size_t idx = left_idx.value(); ; idx = (idx + 1) % perimeter_size) { + result.points[perimeter.start_index + idx].type = segment.type; + if (idx == right_idx.value()) break; + } + + if (segment.type == EnforcedBlockedSeamPoint::Enforced) { + some_point_enforced = true; + } + } +} + +// Restore precise seam positions that may have been modified +void restore_precise_seam_positions(std::vector &layers) { + using SeamPlacerImpl::SeamCandidate; + using SeamPlacerImpl::Perimeter; + + tbb::parallel_for(tbb::blocked_range(0, layers.size()), + [&layers](tbb::blocked_range r) { + for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { + std::vector &layer_perimeter_points = layers[layer_idx].points; + // Iterate over perimeters (jump by end_index) + for (size_t current = 0; current < layer_perimeter_points.size(); + current = layer_perimeter_points[current].perimeter.end_index) { + Perimeter &perimeter = layer_perimeter_points[current].perimeter; + if (perimeter.precise_seam_point.has_value()) { + perimeter.final_seam_position = perimeter.precise_seam_point.value(); + perimeter.seam_index = perimeter.precise_seam_index; + } + } + } + }); +} + +} // namespace PreciseSeam +} // namespace Slic3r diff --git a/src/libslic3r/GCode/PreciseSeam.hpp b/src/libslic3r/GCode/PreciseSeam.hpp new file mode 100644 index 0000000000..d5c1e98952 --- /dev/null +++ b/src/libslic3r/GCode/PreciseSeam.hpp @@ -0,0 +1,146 @@ +#ifndef slic3r_PreciseSeam_hpp_ +#define slic3r_PreciseSeam_hpp_ + +#include +#include +#include +#include +#include "libslic3r/Polygon.hpp" +#include "libslic3r/Polyline.hpp" +#include "libslic3r/Model.hpp" +#include "libslic3r/Layer.hpp" +#include "libslic3r/Print.hpp" +#include "libslic3r/ClipperUtils.hpp" +#include "SeamPlacer.hpp" + +// CURRENT STATUS: +// Strong modifiers (Center/Left/Right): only one intersection per perimeter is supported, +// since there can be only one seam. Additional intersections are ignored. +// +// Weak modifiers (Enforced/Blocked/Neutral): multiple intersections are supported, +// but none of them should pass through the model entirely. A through-body intersection +// produces multiple segments, of which only one will be processed. +// +// In both cases, a pop-up warning is shown when unsupported intersections are detected. +// +// If any modifier has a multiply-connected cross-section (e.g. a hollow shape), +// it is skipped and a corresponding notification is shown. +// +// Full containment of the perimeter within modifier is not handled. +// +// FUTURE DIRECTION: +// A lightweight algorithm is needed to detect and handle through-body intersections +// for Weak modifiers. The algorithm must not slow down the 99.9% common case. +// Possible approach: if intersection passes the diff check (no through-body), +// use the current fast algorithm. If diff check fails, fall back to a heavier +// method: compute midpoints of intersection polygon edges, then check which +// midpoints lie strictly inside the modifier (not on boundary) using +// point_in_polygon. Those edges originate from the perimeter; the rest +// originate from the modifier boundary. Collect perimeter edges into a polyline. +// Additionally, multiply-connected cross-sections could be supported instead of +// being skipped entirely (e.g. by decomposing them into simple polygons). +// For Enforced and Neutral weak modifiers, full containment of the perimeter +// within modifier could be handled (currently ignored). + +namespace Slic3r { +namespace PreciseSeam { + +// Import EnforcedBlockedSeamPoint from SeamPlacerImpl namespace for convenience +using SeamPlacerImpl::EnforcedBlockedSeamPoint; + +// Pre-sliced modifier cache: ModelVolume pointer → per-layer Polygons. +// Built once in SeamPlacer::init(), then passed read-only into per-perimeter functions. +using ModifierSlicesCache = std::unordered_map>; + +// Warning flags set during Precise Seam processing (thread-safe) +struct PreciseSeamWarnings { + std::atomic multiple_intersections{false}; // modifier intersects perimeter in multiple separate places (strong only) + std::atomic through_body{false}; // modifier passes through the model body entirely + std::atomic multiply_connected{false}; // modifier has holes (multiply-connected cross-section) + std::atomic full_containment{false}; // modifier fully contains perimeter, no intersection edges +}; + +// Result of finding common segment between perimeter and intersection +struct SegmentData { + Polyline segment; // Points from intersection_polygon forming the segment + std::vector perimeter_edge_indices; // edge_index for each point in segment +}; + +// Result of weak modifier segment processing +struct WeakModifierSegment { + EnforcedBlockedSeamPoint type; // Enforced/Blocked/Neutral + Point left_point; // Coordinates of left (first) point of segment + size_t left_idx; // Perimeter vertex index for left_point + Point right_point; // Coordinates of right (last) point of segment + size_t right_idx; // Perimeter vertex index for right_point +}; + +// Initialize Precise Seam data by populating provided vectors and flag +// Collects precise seam modifiers and fills output parameters +// Call once during SeamPlacer::init() before gather_seam_candidates() +// Parameters: +// strong_volumes_out - output vector for strong modifiers (CENTER/LEFT/RIGHT) +// weak_volumes_out - output vector for weak modifiers (ENFORCED/BLOCKED/NEUTRAL) +// has_strong_out - output flag indicating presence of strong modifiers +// model_object - model object containing volumes +void init_precise_seam_data( + std::vector& strong_volumes_out, + std::vector& weak_volumes_out, + bool& has_strong_out, + const ModelObject* model_object); + +// Insert strong seam point into perimeter polygon +// Processes strong modifiers (CENTER/LEFT/RIGHT) and inserts seam point into polygon +// Parameters: +// strong_volumes - list of strong precise seam modifiers +// polygon - perimeter polygon (will be modified if point inserted) +// layer - current layer +// slices_cache - pre-sliced modifier polygons (built once in SeamPlacer::init) +// Returns: +// Coordinates of inserted point (internal units) or std::nullopt if nothing inserted +std::optional insert_strong_seam_point( + const std::vector &strong_volumes, + Polygon &polygon, + const Layer *layer, + const ModifierSlicesCache &slices_cache, + PreciseSeamWarnings* warnings = nullptr); + +// Collect all weak modifier segments for a perimeter polygon +// Processes weak modifiers (ENFORCED/BLOCKED/NEUTRAL) and collects segment boundaries +// Also inserts boundary points into the perimeter polygon (sorted by descending arc length) +// Refines enforced edges by subdividing them into segments ≤ enforcer_oversampling_distance +// Parameters: +// weak_volumes - list of weak precise seam modifiers +// polygon - perimeter polygon (will be modified with inserted points and refined edges) +// layer - current layer +// slices_cache - pre-sliced modifier polygons (built once in SeamPlacer::init) +// Returns: +// Ordered vector of segments with updated coordinates (same order as weak_volumes list) +std::vector collect_weak_modifier_segments( + const std::vector &weak_volumes, + Polygon &polygon, + const Layer *layer, + const ModifierSlicesCache &slices_cache, + PreciseSeamWarnings* warnings = nullptr); + +// Apply weak modifier types to perimeter points based on segment boundaries +// Finds boundary points in refined polygon and sets types for points within segments +// Parameters: +// weak_segments - segments with boundary coordinates and types +// result - layer seams data to modify +// perimeter - perimeter info (start/end indices) +// some_point_enforced - flag to update if Enforced points are set +void apply_weak_modifiers_to_perimeter( + const std::vector &weak_segments, + PrintObjectSeamData::LayerSeams &result, + const SeamPlacerImpl::Perimeter &perimeter, + bool &some_point_enforced); + +// Restore precise seam positions that may have been modified by alignment +// Iterates through all perimeters and restores precise_seam_point positions +void restore_precise_seam_positions(std::vector &layers); + +} // namespace PreciseSeam +} // namespace Slic3r + +#endif // slic3r_PreciseSeam_hpp_ diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 35bc436d5a..d527ec6aa9 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "libslic3r/AABBTreeLines.hpp" #include "libslic3r/KDTreeIndirect.hpp" @@ -19,10 +20,12 @@ #include "libslic3r/Layer.hpp" #include "libslic3r/Geometry/Curves.hpp" +#include "libslic3r/I18N.hpp" #include "libslic3r/ShortEdgeCollapse.hpp" #include "libslic3r/TriangleSetSampling.hpp" #include "libslic3r/Utils.hpp" +#include "PreciseSeam.hpp" //#define DEBUG_FILES @@ -303,6 +306,16 @@ struct GlobalModelInfo { AABBTreeIndirect::Tree<3, float> enforcers_tree; AABBTreeIndirect::Tree<3, float> blockers_tree; + // Precise Seam modifiers: strong modifiers (CENTER/LEFT/RIGHT) determine exact seam placement + std::vector precise_seam_strong_volumes; + // Precise Seam modifiers: weak modifiers (ENFORCED/BLOCKED/NEUTRAL) provide hints for seam placement + std::vector precise_seam_weak_volumes; + + // Pre-sliced modifier polygons, keyed by ModelVolume pointer. + // Populated once in SeamPlacer::init() to avoid re-slicing on every perimeter. + // Each value is a per-layer vector of Polygons for that modifier volume. + std::unordered_map> precise_seam_slices; + bool is_enforced(const Vec3f &position, float radius) const { if (enforcers.empty()) { return false; @@ -403,7 +416,8 @@ struct GlobalModelInfo { ; //Extract perimeter polygons of the given layer -Polygons extract_perimeter_polygons(const Layer *layer, std::vector &corresponding_regions_out) { +Polygons extract_perimeter_polygons(const Layer *layer, std::vector &corresponding_regions_out, + bool has_precise_seam_modifiers) { Polygons polygons; for (const LayerRegion *layer_region : layer->regions()) { for (const ExtrusionEntity *ex_entity : layer_region->perimeters.entities) { @@ -440,6 +454,18 @@ Polygons extract_perimeter_polygons(const Layer *layer, std::vector 1 && polygon.points.front() == polygon.points.back()) + polygon.points.pop_back(); + } + } + if (polygons.empty()) { // If there are no perimeter polygons for whatever reason (disabled perimeters .. ) insert dummy point // it is easier than checking everywhere if the layer is not emtpy, no seam will be placed to this layer anyway polygons.emplace_back(Points{ { 0, 0 } }); @@ -449,17 +475,42 @@ Polygons extract_perimeter_polygons(const Layer *layer, std::vectorlayer() : nullptr; + + // Use pre-computed Precise Seam volumes from global_model_info (computed once in init) + const auto& strong_volumes = global_model_info.precise_seam_strong_volumes; + const auto& weak_volumes = global_model_info.precise_seam_weak_volumes; + + // Use pre-sliced cache from global_model_info instead of re-slicing on every call + auto seam_point = PreciseSeam::insert_strong_seam_point(strong_volumes, polygon, layer, global_model_info.precise_seam_slices, warnings); + + // Store the inserted point position for marking as central_enforcer later + std::optional inserted_seam_position; + if (seam_point.has_value()) { + Vec2f unscaled_p = unscale(seam_point.value()).cast(); + inserted_seam_position = Vec3f(unscaled_p.x(), unscaled_p.y(), z_coord); + } + + // Process weak modifiers (ENFORCED/BLOCKED/NEUTRAL) only if no strong modifier was inserted + std::vector weak_segments; + if (!inserted_seam_position.has_value()) { + weak_segments = PreciseSeam::collect_weak_modifier_segments(weak_volumes, polygon, layer, global_model_info.precise_seam_slices, warnings); + } + float angle_arm_len = region != nullptr ? region->flow(FlowRole::frExternalPerimeter).nozzle_diameter() : 0.5f; std::vector lengths { }; @@ -528,10 +579,15 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const perimeter.end_index = result.points.size(); + // Apply weak modifiers if no strong modifier was inserted + if (!inserted_seam_position.has_value() && !weak_segments.empty()) { + PreciseSeam::apply_weak_modifiers_to_perimeter( + weak_segments, result, perimeter, some_point_enforced); + } + if (some_point_enforced) { - // We will patches of enforced points (patch: continuous section of enforced points), choose - // the longest patch, and select the middle point or sharp point (depending on the angle) - // this point will have high priority on this perimeter + // Choose the continuous enforced patch with the most candidates, then select its middle + // candidate or a sharp corner. Patch length here is a point count, not geometric distance. size_t perimeter_size = perimeter.end_index - perimeter.start_index; const auto next_index = [&](size_t idx) { return perimeter.start_index + Slic3r::next_idx_modulo(idx - perimeter.start_index, perimeter_size); @@ -562,7 +618,9 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const std::pair longest_patch { 0, 0 }; auto patch_len = [perimeter_size](const std::pair &start_end) { if (start_end.second < start_end.first) { - return start_end.first + (perimeter_size - start_end.second); + // Count [start, end) across the closing edge, independently of the contour's start. + // Subtract indices first: they are offsets in the layer, not local perimeter indices. + return perimeter_size - (start_end.first - start_end.second); } else { return start_end.second - start_end.first; } @@ -595,30 +653,24 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const } } -} - -// Get index of previous and next perimeter point of the layer. Because SeamCandidates of all polygons of the given layer -// are sequentially stored in the vector, each perimeter contains info about start and end index. These vales are used to -// deduce index of previous and next neigbour in the corresponding perimeter. -std::pair find_previous_and_next_perimeter_point(const std::vector &perimeter_points, - size_t point_index) { - const SeamCandidate ¤t = perimeter_points[point_index]; - int prev = point_index - 1; //for majority of points, it is true that neighbours lie behind and in front of them in the vector - int next = point_index + 1; - - if (point_index == current.perimeter.start_index) { - // if point_index is equal to start, it means that the previous neighbour is at the end - prev = current.perimeter.end_index; + // Apply precise seam point if it was inserted + if (inserted_seam_position.has_value()) { + // Set single point as Enforced, block all others + for (size_t i = perimeter.start_index; i < perimeter.end_index; ++i) { + if (result.points[i].position == inserted_seam_position.value()) { + // Mark as the single enforced point with highest priority + result.points[i].type = EnforcedBlockedSeamPoint::Enforced; + result.points[i].central_enforcer = true; + perimeter.precise_seam_point = inserted_seam_position; + perimeter.precise_seam_index = i; + } else { + // Block all other points + result.points[i].type = EnforcedBlockedSeamPoint::Blocked; + result.points[i].central_enforcer = false; + } + } } - if (point_index == current.perimeter.end_index - 1) { - // if point_index is equal to end, than next neighbour is at the start - next = current.perimeter.start_index; - } - - assert(prev >= 0); - assert(next >= 0); - return {size_t(prev),size_t(next)}; } // Computes all global model info - transforms object, performs raycasting @@ -636,7 +688,9 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po, || model_volume->type() == ModelVolumeType::NEGATIVE_VOLUME) { auto model_transformation = model_volume->get_matrix(); indexed_triangle_set model_its = model_volume->mesh().its; - // ORCA: Mirrored transforms flip winding, keep normals outward + // ORCA fix (not related to Precise Seam, discovered during its development): + // Mirror transforms have negative determinant which flips triangle winding. + // fix_left_handed=true swaps indices to keep normals pointing outward. its_transform(model_its, model_transformation, true); if (model_volume->type() == ModelVolumeType::MODEL_PART) { its_merge(triangle_set, model_its); @@ -657,7 +711,10 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po, size_t negative_volumes_start_index = triangle_set.indices.size(); its_merge(triangle_set, negative_volumes_set); - // ORCA: Mirroring flips normals, keep them outward for visibility sampling + // ORCA fix (not related to Precise Seam, discovered during its development): + // Object-level transform may include mirroring (negative determinant), + // which inverts triangle winding. fix_left_handed=true corrects this + // so visibility ray sampling sees outward-facing normals. its_transform(triangle_set, obj_transform, true); BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: decimate: end"; @@ -719,12 +776,12 @@ void gather_enforcers_blockers(GlobalModelInfo &result, const PrintObject *po) { auto model_transformation = obj_transform * mv->get_matrix(); indexed_triangle_set enforcers = mv->seam_facets.get_facets(*mv, EnforcerBlockerType::ENFORCER); - // ORCA: Keep normals outward when mirroring seam enforcers + // ORCA fix (not related to Precise Seam): fix winding for mirrored transforms its_transform(enforcers, model_transformation, true); its_merge(result.enforcers, enforcers); indexed_triangle_set blockers = mv->seam_facets.get_facets(*mv, EnforcerBlockerType::BLOCKER); - // ORCA: Keep normals outward when mirroring seam blockers + // ORCA fix (not related to Precise Seam): fix winding for mirrored transforms its_transform(blockers, model_transformation, true); its_merge(result.blockers, blockers); } @@ -1011,13 +1068,14 @@ void pick_random_seam_point(const std::vector &perimeter_points, // Parallel process and extract each perimeter polygon of the given print object. // Gather SeamCandidates of each layer into vector and build KDtree over them // Store results in the SeamPlacer variables m_seam_per_object -void SeamPlacer::gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info) { +void SeamPlacer::gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info, + PreciseSeam::PreciseSeamWarnings* warnings) { using namespace SeamPlacerImpl; PrintObjectSeamData &seam_data = m_seam_per_object.emplace(po, PrintObjectSeamData { }).first->second; seam_data.layers.resize(po->layer_count()); tbb::parallel_for(tbb::blocked_range(0, po->layers().size()), - [po, &global_model_info, &seam_data] + [po, &global_model_info, &seam_data, warnings] (tbb::blocked_range r) { for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { PrintObjectSeamData::LayerSeams &layer_seams = seam_data.layers[layer_idx]; @@ -1025,10 +1083,13 @@ void SeamPlacer::gather_seam_candidates(const PrintObject *po, const SeamPlacerI auto unscaled_z = layer->slice_z; std::vector regions; //NOTE corresponding region ptr may be null, if the layer has zero perimeters - Polygons polygons = extract_perimeter_polygons(layer, regions); + const bool has_precise_seam_modifiers = !global_model_info.precise_seam_strong_volumes.empty() || + !global_model_info.precise_seam_weak_volumes.empty(); + Polygons polygons = extract_perimeter_polygons(layer, regions, has_precise_seam_modifiers); for (size_t poly_index = 0; poly_index < polygons.size(); ++poly_index) { process_perimeter_polygon(polygons[poly_index], unscaled_z, - regions[poly_index], global_model_info, layer_seams); + regions[poly_index], global_model_info, layer_seams, + warnings); } auto functor = SeamCandidateCoordinateFunctor { layer_seams.points }; seam_data.layers[layer_idx].points_tree = @@ -1424,10 +1485,13 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl:: } -void SeamPlacer::init(const Print &print, std::function throw_if_canceled_func) { +void SeamPlacer::init(Print &print, std::function throw_if_canceled_func) { using namespace SeamPlacerImpl; m_seam_per_object.clear(); + // Warning flags for Precise Seam processing — shared across all objects + PreciseSeam::PreciseSeamWarnings precise_seam_warnings; + for (const PrintObject *po : print.objects()) { throw_if_canceled_func(); SeamPosition configured_seam_preference = po->config().seam_position.value; @@ -1436,14 +1500,29 @@ void SeamPlacer::init(const Print &print, std::function throw_if_can { GlobalModelInfo global_model_info { }; gather_enforcers_blockers(global_model_info, po); + PreciseSeam::init_precise_seam_data( + global_model_info.precise_seam_strong_volumes, + global_model_info.precise_seam_weak_volumes, + m_seam_per_object[po].has_precise_seam_strong_volumes, + po->model_object()); + + // Pre-slice all precise seam modifier volumes once per object. + // Without this cache, slice_single_volume() would be called for every + // modifier × every perimeter × every layer — thousands of redundant slicing operations. + for (const ModelVolume* vol : global_model_info.precise_seam_strong_volumes) + global_model_info.precise_seam_slices[vol] = po->slice_single_volume(vol); + for (const ModelVolume* vol : global_model_info.precise_seam_weak_volumes) + global_model_info.precise_seam_slices[vol] = po->slice_single_volume(vol); + throw_if_canceled_func(); if (configured_seam_preference == spAligned || configured_seam_preference == spNearest || configured_seam_preference == spAlignedBack) { compute_global_occlusion(global_model_info, po, throw_if_canceled_func, configured_seam_preference); } throw_if_canceled_func(); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather_seam_candidates: start"; - gather_seam_candidates(po, global_model_info); + gather_seam_candidates(po, global_model_info, &precise_seam_warnings); BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather_seam_candidates: end"; throw_if_canceled_func(); @@ -1491,10 +1570,49 @@ void SeamPlacer::init(const Print &print, std::function throw_if_can << "SeamPlacer: align_seam_points : end"; } + // Restore precise seam positions that were potentially modified + if (m_seam_per_object[po].has_precise_seam_strong_volumes) { + PreciseSeam::restore_precise_seam_positions(m_seam_per_object[po].layers); + } + #ifdef DEBUG_FILES debug_export_points(m_seam_per_object[po].layers, po->bounding_box(), comparator); #endif } + + // Show Precise Seam warnings (once for all objects). + // Only ONE active_step_add_warning() call — multiple calls generate multiple UI events, + // each re-pushing ALL current warnings via Plater handler, causing NotificationManager::append() + // to duplicate text within each popup. + { + const bool mi = precise_seam_warnings.multiple_intersections.load(std::memory_order_relaxed); + const bool tb = precise_seam_warnings.through_body.load(std::memory_order_relaxed); + const bool mc = precise_seam_warnings.multiply_connected.load(std::memory_order_relaxed); + const bool fc = precise_seam_warnings.full_containment.load(std::memory_order_relaxed); + std::vector parts; + if (mi) + parts.push_back(_u8L("multiple intersections with a perimeter detected")); + if (tb) + parts.push_back(_u8L("modifier fully crosses the printable perimeter")); + if (mc) + parts.push_back(_u8L("modifier shape is not solid (has holes inside) and was ignored")); + if (fc) + parts.push_back(_u8L("perimeter is fully contained inside modifier and was ignored")); + if (!parts.empty()) { + // One line: the export warnings dialog shows only the first line of each warning. + std::string warning_text = _u8L("Precise Seam") + ": "; + for (size_t i = 0; i < parts.size(); ++i) { + if (i > 0) warning_text += "; "; + warning_text += parts[i]; + } + warning_text += ". "; + warning_text += _u8L("Seam placement may differ from expected."); + print.active_step_add_warning( + PrintStateBase::WarningLevel::NON_CRITICAL, + warning_text, + PrintStateBase::SlicingPreciseSeamWarning); + } + } } void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, diff --git a/src/libslic3r/GCode/SeamPlacer.hpp b/src/libslic3r/GCode/SeamPlacer.hpp index 8a973d0d8a..9855b4f4aa 100644 --- a/src/libslic3r/GCode/SeamPlacer.hpp +++ b/src/libslic3r/GCode/SeamPlacer.hpp @@ -18,6 +18,7 @@ namespace Slic3r { class PrintObject; +namespace PreciseSeam { struct PreciseSeamWarnings; } class ExtrusionLoop; class Print; class Layer; @@ -41,7 +42,7 @@ enum class EnforcedBlockedSeamPoint { // struct representing single perimeter loop struct Perimeter { size_t start_index{}; - size_t end_index{}; //inclusive! + size_t end_index{}; //exclusive (one-past-the-end) size_t seam_index{}; float flow_width{}; @@ -50,6 +51,10 @@ struct Perimeter { // Random position also uses this flexibility to set final seam point position bool finalized = false; Vec3f final_seam_position = Vec3f::Zero(); + + // Stores precise seam coordinates found by Precise Seam modifiers + std::optional precise_seam_point; + size_t precise_seam_index{}; }; //Struct over which all processing of perimeters is done. For each perimeter point, its respective candidate is created, @@ -102,6 +107,9 @@ struct PrintObjectSeamData // Map of PrintObjects (PO) -> vector of layers of PO -> unique_ptr to KD // tree of all points of the given layer + // Indicates presence of strong Precise Seam modifiers (CENTER/LEFT/RIGHT) for this object + bool has_precise_seam_strong_volumes = false; + void clear() { layers.clear(); @@ -141,11 +149,12 @@ public: //The following data structures hold all perimeter points for all PrintObject. std::unordered_map m_seam_per_object; - void init(const Print &print, std::function throw_if_canceled_func); + void init(Print &print, std::function throw_if_canceled_func); void place_seam(const Layer *layer, ExtrusionLoop &loop, const Point &last_pos, float& overhang) const; private: - void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info); + void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info, + PreciseSeam::PreciseSeamWarnings* warnings = nullptr); void calculate_candidates_visibility(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info); void calculate_overhangs_and_layer_embedding(const PrintObject *po); diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 7ea46cf8a7..5026323d54 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -1230,15 +1230,21 @@ void ToolOrdering::cal_most_used_extruder(const PrintConfig &config) float ToolOrdering::cal_max_additional_fan(const PrintConfig &config) { - // record + std::set used_filaments; + for (const LayerTools &layer_tools : m_layer_tools) + used_filaments.insert(layer_tools.extruders.begin(), layer_tools.extruders.end()); + if (used_filaments.empty()) + return 0; + + // Orca: additional_cooling_fan_speed can hold one value per extruder variant a filament prints with; + // filament_self_index maps such a column to its filament. + const std::vector &self_index = config.filament_self_index.values; + const size_t columns = std::max(config.additional_cooling_fan_speed.size(), size_t(*used_filaments.rbegin()) + 1); float max_fan = 0; - for (LayerTools &layer_tools : m_layer_tools) { - std::vector filaments = layer_tools.extruders; - std::set layer_extruder_count; - // count once only - for (unsigned int &filament : filaments) - if (max_fan < config.additional_cooling_fan_speed.get_at(filament)) - max_fan = config.additional_cooling_fan_speed.get_at(filament); + for (size_t column = 0; column < columns; ++column) { + const unsigned int filament_id = self_index.size() == columns ? self_index[column] - 1 : column; + if (used_filaments.count(filament_id) && max_fan < config.additional_cooling_fan_speed.get_at(column)) + max_fan = config.additional_cooling_fan_speed.get_at(column); } return max_fan; } diff --git a/src/libslic3r/LocalesUtils.cpp b/src/libslic3r/LocalesUtils.cpp index e727b29b09..9c81511dc5 100644 --- a/src/libslic3r/LocalesUtils.cpp +++ b/src/libslic3r/LocalesUtils.cpp @@ -13,8 +13,19 @@ namespace Slic3r { +// How many setters this thread holds, so the ones nested in another can skip +// setlocale, which takes a lock the whole process shares on Windows. +static thread_local int s_numeric_locale_depth = 0; + CNumericLocalesSetter::CNumericLocalesSetter() { + // Nested in another setter on this thread, whose "C" the separator check + // confirms is still set. + if (s_numeric_locale_depth > 0 && is_decimal_separator_point()) { + m_nested = true; + ++ s_numeric_locale_depth; + return; + } #ifdef _WIN32 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); m_orig_numeric_locale = std::setlocale(LC_NUMERIC, nullptr); @@ -29,12 +40,17 @@ CNumericLocalesSetter::CNumericLocalesSetter() m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_new_locale); uselocale(m_new_locale); #endif + // Counted last, since the destructor does not run for a constructor that throws. + ++ s_numeric_locale_depth; } CNumericLocalesSetter::~CNumericLocalesSetter() { + -- s_numeric_locale_depth; + if (m_nested) + return; #ifdef _WIN32 std::setlocale(LC_NUMERIC, m_orig_numeric_locale.data()); #else diff --git a/src/libslic3r/LocalesUtils.hpp b/src/libslic3r/LocalesUtils.hpp index f63c3572f7..d7e59f5ded 100644 --- a/src/libslic3r/LocalesUtils.hpp +++ b/src/libslic3r/LocalesUtils.hpp @@ -19,8 +19,13 @@ class CNumericLocalesSetter { public: CNumericLocalesSetter(); ~CNumericLocalesSetter(); + // A copy would restore the locale twice, and count down once more than up. + CNumericLocalesSetter(const CNumericLocalesSetter&) = delete; + CNumericLocalesSetter& operator=(const CNumericLocalesSetter&) = delete; private: + // Inside another setter on this thread, which does the setting and restoring. + bool m_nested { false }; #ifdef _WIN32 std::string m_orig_numeric_locale; #else diff --git a/src/libslic3r/MeshBoolean.cpp b/src/libslic3r/MeshBoolean.cpp index 7497f92abf..4d9dda0c2e 100644 --- a/src/libslic3r/MeshBoolean.cpp +++ b/src/libslic3r/MeshBoolean.cpp @@ -26,6 +26,13 @@ #include #include #include +// For parameterize_lscm() +#include +#include +#include +#include +#include +#include // BBS: for boolean using mcut #include "mcut/include/mcut/mcut.h" @@ -249,6 +256,151 @@ indexed_triangle_set cgal_to_indexed_triangle_set(const CGALMesh &cgalmesh) return cgal_to_indexed_triangle_set(cgalmesh.m); } +// ///////////////////////////////////////////////////////////////////////////// +// Isotropic remeshing +// ///////////////////////////////////////////////////////////////////////////// + +indexed_triangle_set remesh_isotropic(const indexed_triangle_set &mesh, double target_edge_length, + unsigned n_iterations, double sharp_angle_deg, + unsigned n_relaxation_steps) +{ + if (mesh.indices.empty() || target_edge_length <= 0.0) + return mesh; + + _EpicMesh cgal_mesh; + triangle_mesh_to_cgal(mesh.vertices, mesh.indices, cgal_mesh); + if (cgal_mesh.is_empty() || cgal_mesh.number_of_faces() == 0) + return mesh; + + // Surface_mesh::add_face() refuses any face that would make the mesh non-manifold and returns a + // null descriptor instead. Remeshing a mesh that silently lost faces that way produces holes in + // the output, so bail out and let the caller report it rather than hand back a punctured model. + if (cgal_mesh.number_of_faces() != mesh.indices.size()) + return mesh; + + using edge_descriptor = boost::graph_traits<_EpicMesh>::edge_descriptor; + try { + // Sharp edges and open borders are pinned before remeshing. Without that, the tangential + // relaxation pass slides vertices along the surface and rounds every hard feature off - a + // cube comes back with wobbly, eroded edges, which is the most visible way "remeshing does + // not work properly". protect_constraints() forbids splitting or collapsing them, but it + // requires each constrained edge to already be shorter than 4/3 * target, hence the split + // first (passing the map so the halves inherit the constraint). This mirrors CGAL's own + // isotropic_remeshing example. + auto ecm = cgal_mesh.add_property_map("e:is_constrained", false).first; + if (sharp_angle_deg > 0.0) + CGALProc::detect_sharp_edges(cgal_mesh, sharp_angle_deg, ecm); + for (edge_descriptor e : edges(cgal_mesh)) { + const auto h = halfedge(e, cgal_mesh); + if (is_border(h, cgal_mesh) || is_border(opposite(h, cgal_mesh), cgal_mesh)) + put(ecm, e, true); + } + + std::vector constrained; + for (edge_descriptor e : edges(cgal_mesh)) + if (get(ecm, e)) + constrained.push_back(e); + if (!constrained.empty()) + CGALProc::split_long_edges(constrained, target_edge_length, cgal_mesh, + CGALParams::edge_is_constrained_map(ecm)); + + CGALProc::isotropic_remeshing(faces(cgal_mesh), target_edge_length, cgal_mesh, + CGALParams::number_of_iterations(n_iterations) + .number_of_relaxation_steps(n_relaxation_steps) + .edge_is_constrained_map(ecm) + .protect_constraints(true)); + } catch (const std::exception &) { + return mesh; // CGAL throws on some non-manifold / degenerate inputs; leave the mesh untouched + } + if (cgal_mesh.number_of_faces() == 0) + return mesh; + + // isotropic_remeshing edits in place, and its edge collapses only *mark* vertices and faces as + // removed - the underlying arrays keep the holes until the garbage is collected. That matters + // because cgal_to_indexed_triangle_set() numbers its output vertices by iteration order (which + // skips removed slots) while reading each face's corner as the raw integer value of the vertex + // descriptor (which does not). Past the first collapse the two disagree, so every triangle + // points at the wrong vertices, and any descriptor beyond the live vertex count is dropped + // together with its triangle. Compacting first makes descriptor == iteration order again. + cgal_mesh.collect_garbage(); + return cgal_to_indexed_triangle_set(cgal_mesh); +} + +// ///////////////////////////////////////////////////////////////////////////// +// UV parameterization +// ///////////////////////////////////////////////////////////////////////////// + +std::optional> parameterize_lscm(const indexed_triangle_set &mesh) +{ + namespace SMP = CGAL::Surface_mesh_parameterization; + + if (mesh.indices.empty()) + return std::nullopt; + + _EpicMesh cgal_mesh; + triangle_mesh_to_cgal(mesh.vertices, mesh.indices, cgal_mesh); + + using vertex_descriptor = boost::graph_traits<_EpicMesh>::vertex_descriptor; + using halfedge_descriptor = boost::graph_traits<_EpicMesh>::halfedge_descriptor; + + // LSCM assumes a single topological disk: one connected component, one boundary loop. A patch + // with several disconnected painted islands, or with a hole in it, doesn't qualify -- bail out + // rather than silently parameterizing just one arbitrary piece of it. + { + std::vector component_id(num_faces(cgal_mesh)); + const std::size_t num_components = CGAL::Polygon_mesh_processing::connected_components( + cgal_mesh, CGAL::make_property_map(component_id)); + if (num_components != 1) + return std::nullopt; + } + + const halfedge_descriptor border = CGAL::Polygon_mesh_processing::longest_border(cgal_mesh).first; + if (border == halfedge_descriptor()) + return std::nullopt; // no boundary at all -- a closed patch, which isn't a disk either + + // ...and exactly one boundary loop. One connected component is not enough on its own: a patch with + // a hole in it (paint a ring, or erase the middle of a stroke) is a single component with two + // loops, and LSCM will happily "parameterize" it into an overlapping, folded-over chart rather + // than fail. Walk the border halfedges and check every one of them belongs to the longest loop. + { + std::size_t border_halfedges = 0; + for (halfedge_descriptor h : halfedges(cgal_mesh)) + if (is_border(h, cgal_mesh)) + ++border_halfedges; + std::size_t loop_length = 0; + halfedge_descriptor h = border; + do { + ++loop_length; + h = next(h, cgal_mesh); + } while (h != border && loop_length <= border_halfedges); + if (loop_length != border_halfedges) + return std::nullopt; // more than one boundary loop -- not a topological disk + } + + using Point_2 = EpicKernel::Point_2; + using UV_pmap = _EpicMesh::Property_map; + UV_pmap uv_map = cgal_mesh.add_property_map("h:uv", Point_2(0, 0)).first; + + using Parameterizer = SMP::LSCM_parameterizer_3<_EpicMesh>; + const SMP::Error_code err = SMP::parameterize(cgal_mesh, Parameterizer(), border, uv_map); + if (err != SMP::OK) + return std::nullopt; + + // triangle_mesh_to_cgal() adds vertices in the exact same order as mesh.vertices (see above), + // and Surface_mesh assigns indices sequentially on insertion into a fresh mesh, so a + // vertex_descriptor's index here is guaranteed to match the original input vertex index -- + // the same assumption cgal_to_indexed_triangle_set() above already relies on. + std::vector result(mesh.vertices.size(), Vec2f::Zero()); + for (vertex_descriptor vd : vertices(cgal_mesh)) { + const std::size_t idx = std::size_t(vd); + if (idx < result.size()) { + const Point_2 &uv = uv_map[vd]; + result[idx] = Vec2f(float(uv.x()), float(uv.y())); + } + } + return result; +} + // ///////////////////////////////////////////////////////////////////////////// // Boolean operations for CGAL meshes // ///////////////////////////////////////////////////////////////////////////// diff --git a/src/libslic3r/MeshBoolean.hpp b/src/libslic3r/MeshBoolean.hpp index d9a5d196fb..c307d1528b 100644 --- a/src/libslic3r/MeshBoolean.hpp +++ b/src/libslic3r/MeshBoolean.hpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include @@ -73,6 +75,27 @@ bool empty(const CGALMesh &mesh); // Repair a mesh using CGAL. Returns true on success. Optionally returns a summary of repairs and an error string. bool repair(TriangleMesh &mesh, RepairedMeshErrors *repaired_errors = nullptr, std::string *error = nullptr); + +// Real UV unwrap of an open mesh patch via CGAL's LSCM (Least Squares Conformal Maps) surface +// parameterization. Returns one UV coordinate per input vertex (same indexing as `mesh.vertices`), +// or nullopt if `mesh` isn't a single topological disk -- LSCM needs exactly one connected +// component with exactly one boundary loop, true for a typical single brush stroke/patch but not +// guaranteed for multiple disconnected painted islands merged into one mesh. +std::optional> parameterize_lscm(const indexed_triangle_set &mesh); + +// Isotropic remeshing (CGAL): rebuilds the mesh so its triangles are close to a uniform target edge +// length, splitting oversized triangles and collapsing undersized ones. Used to even out a model with +// wildly varying triangle sizes so texture displacement has a consistent vertex density to work with. +// Edges whose dihedral angle exceeds `sharp_angle_deg`, and any open border, are held fixed so hard +// features survive instead of being eroded by the relaxation pass; pass 0 to remesh everything. +// Returns the input unchanged if remeshing fails (e.g. a non-manifold or self-intersecting input). +// `n_relaxation_steps` is the number of tangential relaxation passes run inside each iteration. That +// relaxation is what actually evens out the triangle distribution - splitting and collapsing alone +// only bring edge *lengths* near the target, leaving the vertices wherever they happened to land. CGAL +// defaults it to 1, which on a few iterations is not enough to look uniform. +indexed_triangle_set remesh_isotropic(const indexed_triangle_set &mesh, double target_edge_length, + unsigned n_iterations = 3, double sharp_angle_deg = 40.0, + unsigned n_relaxation_steps = 1); } namespace mcut { diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 209ccdafa2..fbc299cf72 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -23,6 +23,7 @@ #include "libslic3r/Geometry/ConvexHull.hpp" +#include #include #include @@ -1229,6 +1230,7 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs) this->volumes.emplace_back(new ModelVolume(*model_volume)); this->volumes.back()->set_model_object(this); } + this->clear_instances(); this->instances.reserve(rhs.instances.size()); for (const ModelInstance *model_instance : rhs.instances) { @@ -1267,6 +1269,7 @@ ModelObject& ModelObject::assign_copy(ModelObject &&rhs) rhs.volumes.clear(); for (ModelVolume *model_volume : this->volumes) model_volume->set_model_object(this); + this->clear_instances(); this->instances = std::move(rhs.instances); rhs.instances.clear(); @@ -1390,7 +1393,9 @@ ModelVolume* ModelObject::add_volume_with_shared_mesh(const ModelVolume &other, void ModelObject::delete_volume(size_t idx) { ModelVolumePtrs::iterator i = this->volumes.begin() + idx; - delete *i; + ModelVolume* volume_to_delete = *i; + + delete volume_to_delete; this->volumes.erase(i); if (this->volumes.size() == 1) @@ -1449,6 +1454,20 @@ void ModelObject::sort_volumes(bool full_sort) // sort volumes inside the object to order "Model Part, Negative Volume, Modifier, Support Blocker and Support Enforcer. " if (full_sort) std::stable_sort(volumes.begin(), volumes.end(), [](ModelVolume* vl, ModelVolume* vr) { + // Special handling for Precise Seam modifiers: group-based sorting with user order preservation + if (vl->is_precise_seam() && vr->is_precise_seam()) { + // Strong (center/left/right) always before weak (enforced/blocked/neutral) + bool vl_strong = vl->is_precise_seam_strong(); + bool vr_strong = vr->is_precise_seam_strong(); + if (vl_strong != vr_strong) + return vl_strong; // strong < weak → strong group appears first + + // Within same group (both strong or both weak): preserve current order + // stable_sort will maintain relative positions when comparator returns false + return false; + } + + // For non-Precise-Seam or mixed types: use standard enum-based ordering return vl->type() < vr->type(); }); // sort have to controll "place" of the support blockers/enforcers. But one of the model parts have to be on the first place. @@ -1456,10 +1475,19 @@ void ModelObject::sort_volumes(bool full_sort) std::stable_sort(volumes.begin(), volumes.end(), [](ModelVolume* vl, ModelVolume* vr) { ModelVolumeType vl_type = vl->type() > ModelVolumeType::PARAMETER_MODIFIER ? vl->type() : ModelVolumeType::PARAMETER_MODIFIER; ModelVolumeType vr_type = vr->type() > ModelVolumeType::PARAMETER_MODIFIER ? vr->type() : ModelVolumeType::PARAMETER_MODIFIER; + + // Apply same Precise Seam grouping logic for partial sort + if (vl->is_precise_seam() && vr->is_precise_seam()) { + bool vl_strong = vl->is_precise_seam_strong(); + bool vr_strong = vr->is_precise_seam_strong(); + if (vl_strong != vr_strong) + return vl_strong; + return false; // preserve order within same group + } + return vl_type < vr_type; }); } - ModelInstance* ModelObject::add_instance() { ModelInstance* i = new ModelInstance(this); @@ -2059,6 +2087,11 @@ void ModelVolume::reset_extra_facets() this->seam_facets.reset(); this->mmu_segmentation_facets.reset(); this->fuzzy_skin_facets.reset(); + // Texture-displacement paint data has no remap-across-topology-change support yet (see + // build_texture_displacement()'s documented limitation), so it must be dropped here rather + // than left referring to a mesh that no longer matches it. + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + this->texture_displacement_facet(i).reset(); } std::optional ModelVolume::save_painting() const @@ -2615,7 +2648,8 @@ std::vector ModelVolume::get_extruders() const if (m_type == ModelVolumeType::INVALID || m_type == ModelVolumeType::NEGATIVE_VOLUME || m_type == ModelVolumeType::SUPPORT_BLOCKER - || m_type == ModelVolumeType::SUPPORT_ENFORCER) + || m_type == ModelVolumeType::SUPPORT_ENFORCER + || this->is_precise_seam()) // Precise Seam is non-printing helper geometry return std::vector(); if (mmu_segmentation_facets.timestamp() != mmuseg_ts) { @@ -2819,6 +2853,19 @@ ModelVolumeType ModelVolume::type_from_string(const std::string &s) return ModelVolumeType::SUPPORT_ENFORCER; if (s == "support_blocker") return ModelVolumeType::SUPPORT_BLOCKER; + // Precise Seam types + if (s == "precise_seam_center") + return ModelVolumeType::PRECISE_SEAM_CENTER; + if (s == "precise_seam_left") + return ModelVolumeType::PRECISE_SEAM_LEFT; + if (s == "precise_seam_right") + return ModelVolumeType::PRECISE_SEAM_RIGHT; + if (s == "precise_seam_enforced") + return ModelVolumeType::PRECISE_SEAM_ENFORCED; + if (s == "precise_seam_blocked") + return ModelVolumeType::PRECISE_SEAM_BLOCKED; + if (s == "precise_seam_neutral") + return ModelVolumeType::PRECISE_SEAM_NEUTRAL; //assert(s == "0"); // Default value if invalud type string received. return ModelVolumeType::MODEL_PART; @@ -2833,6 +2880,12 @@ std::string ModelVolume::type_to_string(const ModelVolumeType t) case ModelVolumeType::PARAMETER_MODIFIER: return "modifier_part"; case ModelVolumeType::SUPPORT_ENFORCER: return "support_enforcer"; case ModelVolumeType::SUPPORT_BLOCKER: return "support_blocker"; + case ModelVolumeType::PRECISE_SEAM_CENTER: return "precise_seam_center"; + case ModelVolumeType::PRECISE_SEAM_LEFT: return "precise_seam_left"; + case ModelVolumeType::PRECISE_SEAM_RIGHT: return "precise_seam_right"; + case ModelVolumeType::PRECISE_SEAM_ENFORCED: return "precise_seam_enforced"; + case ModelVolumeType::PRECISE_SEAM_BLOCKED: return "precise_seam_blocked"; + case ModelVolumeType::PRECISE_SEAM_NEUTRAL: return "precise_seam_neutral"; default: assert(false); return "normal_part"; @@ -2941,6 +2994,11 @@ void ModelVolume::assign_new_unique_ids_recursive() seam_facets.set_new_unique_id(); mmu_segmentation_facets.set_new_unique_id(); fuzzy_skin_facets.set_new_unique_id(); + // As set_new_unique_id() already does: the undo/redo stack stores FacetsAnnotation contents keyed + // by ObjectID, so a clone left sharing these ids with its source can be handed the source's mask + // on an undo - after which a paint mask and the mesh it was recorded against no longer match. + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + texture_displacement_facet(i).set_new_unique_id(); } void ModelVolume::rotate(double angle, Axis axis) @@ -3702,7 +3760,11 @@ void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::stri m_data.bitstream.insert(m_data.bitstream.end(), bool(dec & (1 << i))); } - m_data.update_used_states(bitstream_start_idx); + if (!m_data.update_used_states(bitstream_start_idx)) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": dropping malformed paint data of triangle " << triangle_id; + m_data.bitstream.resize(bitstream_start_idx); + m_data.triangles_to_split.pop_back(); + } } bool FacetsAnnotation::equals(const FacetsAnnotation &other) const @@ -3785,6 +3847,7 @@ bool model_volume_list_changed(const ModelObject &model_object_old, const ModelO }); } + template< typename TypeFilterFn, typename CompareFn> bool model_property_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, TypeFilterFn type_filter, CompareFn compare) { diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 815b93c362..895ea30d09 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -19,6 +19,7 @@ #include "TextConfiguration.hpp" #include "EmbossShape.hpp" #include "TriangleSelector.hpp" +#include "TextureDisplacement.hpp" //BBS: add bbs 3mf #include "Format/bbs_3mf.hpp" @@ -28,6 +29,7 @@ #include "Format/STL.hpp" #include "Format/OBJ.hpp" +#include #include #include #include @@ -347,8 +349,22 @@ enum class ModelVolumeType : int { PARAMETER_MODIFIER, SUPPORT_BLOCKER, SUPPORT_ENFORCER, + // Precise seam modifiers (6 subtypes for seam placement control). + // Order is critical: strong types first, then weak. Range checks in is_precise_seam*() depend on it. + PRECISE_SEAM_CENTER, + PRECISE_SEAM_LEFT, + PRECISE_SEAM_RIGHT, + PRECISE_SEAM_ENFORCED, + PRECISE_SEAM_BLOCKED, + PRECISE_SEAM_NEUTRAL, }; +// Free functions for checking ModelVolumeType without a ModelVolume object. +// Keep in sync with ModelVolume::is_precise_seam*() methods below. +inline bool is_precise_seam(ModelVolumeType t) { return t >= ModelVolumeType::PRECISE_SEAM_CENTER && t <= ModelVolumeType::PRECISE_SEAM_NEUTRAL; } +inline bool is_precise_seam_strong(ModelVolumeType t) { return t >= ModelVolumeType::PRECISE_SEAM_CENTER && t <= ModelVolumeType::PRECISE_SEAM_RIGHT; } +inline bool is_precise_seam_weak(ModelVolumeType t) { return t >= ModelVolumeType::PRECISE_SEAM_ENFORCED && t <= ModelVolumeType::PRECISE_SEAM_NEUTRAL; } + // A printable object, possibly having multiple print volumes (each with its own set of parameters and materials), // and possibly having multiple modifier volumes, each modifier volume with its set of parameters and materials. // Each ModelObject may be instantiated mutliple times, each instance having different placement on the print bed, @@ -887,6 +903,69 @@ public: // List of mesh facets painted for fuzzy skin. FacetsAnnotation fuzzy_skin_facets; + // One independent paint mask per texture-displacement layer slot (see texture_displacement_layers + // below). Unlike the other facets fields above, a triangle may be painted (ENFORCER) in more + // than one of these simultaneously -- that overlap is what makes the layers "blend". + // + // These are 8 plain named fields rather than a std::array: FacetsAnnotation's + // default/copy constructors are private and friended only to ModelVolume, but std::array's own + // implicitly-defined default/copy constructors are generated with std::array's access rights, + // not ModelVolume's -- so an array of FacetsAnnotation ends up with its default/copy + // constructors implicitly deleted regardless of the friend declaration. Use + // texture_displacement_facet(slot) below for array-like indexed access. + FacetsAnnotation texture_displacement_facets_0; + FacetsAnnotation texture_displacement_facets_1; + FacetsAnnotation texture_displacement_facets_2; + FacetsAnnotation texture_displacement_facets_3; + FacetsAnnotation texture_displacement_facets_4; + FacetsAnnotation texture_displacement_facets_5; + FacetsAnnotation texture_displacement_facets_6; + FacetsAnnotation texture_displacement_facets_7; + + FacetsAnnotation& texture_displacement_facet(int slot) { + switch (slot) { + case 0: return texture_displacement_facets_0; + case 1: return texture_displacement_facets_1; + case 2: return texture_displacement_facets_2; + case 3: return texture_displacement_facets_3; + case 4: return texture_displacement_facets_4; + case 5: return texture_displacement_facets_5; + case 6: return texture_displacement_facets_6; + default: assert(slot == 7); return texture_displacement_facets_7; + } + } + const FacetsAnnotation& texture_displacement_facet(int slot) const { return const_cast(this)->texture_displacement_facet(slot); } + + // Small helpers for the constructor asserts below (kept out of line-noise at each call site). + bool texture_displacement_facets_ids_valid() const { + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + if (!texture_displacement_facet(i).id().valid() || texture_displacement_facet(i).id() == this->id()) + return false; + return true; + } + bool texture_displacement_facets_ids_invalid() const { + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + if (texture_displacement_facet(i).id().valid()) + return false; + return true; + } + bool texture_displacement_facets_all_empty() const { + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + if (!texture_displacement_facet(i).empty()) + return false; + return true; + } + + // Texture assets (height maps) and their projection/displacement parameters. Element order + // is not meaningful for baking (layers are applied in TextureDisplacementLayer::slot order, + // see build_texture_displacement()); it only reflects UI insertion order. + std::vector texture_displacement_layers; + + // Whole-stack displacement settings (border handling, post-process smoothing) - see + // TextureDisplacementOptions. They live beside the layers rather than on one of them because + // they are not a property of any single layer. + TextureDisplacementOptions texture_displacement_options; + // Save painting data before reset_extra_facets() discards it. // Used for replacing mesh without losing painting data. // Only for model parts (not modifiers/connectors). @@ -917,6 +996,14 @@ public: bool is_support_enforcer() const { return m_type == ModelVolumeType::SUPPORT_ENFORCER; } bool is_support_blocker() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER; } bool is_support_modifier() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER || m_type == ModelVolumeType::SUPPORT_ENFORCER; } + // Check if this volume is any of the precise seam modifier subtypes + bool is_precise_seam() const { return m_type >= ModelVolumeType::PRECISE_SEAM_CENTER && m_type <= ModelVolumeType::PRECISE_SEAM_NEUTRAL; } + // Helper to check if volume is a "strong" Precise Seam type (center, left, right) + // Strong modifiers have priority and always appear above weak modifiers in UI + bool is_precise_seam_strong() const { return m_type >= ModelVolumeType::PRECISE_SEAM_CENTER && m_type <= ModelVolumeType::PRECISE_SEAM_RIGHT; } + // Helper to check if volume is a "weak" Precise Seam type (enforced, blocked, neutral) + // Weak modifiers always appear below strong modifiers in UI + bool is_precise_seam_weak() const { return m_type >= ModelVolumeType::PRECISE_SEAM_ENFORCED && m_type <= ModelVolumeType::PRECISE_SEAM_NEUTRAL; } bool is_text() const { return text_configuration.has_value(); } bool is_svg() const { return emboss_shape.has_value() && !text_configuration.has_value(); } bool is_the_only_one_part() const; // behave like an object @@ -1024,13 +1111,18 @@ public: this->seam_facets.set_new_unique_id(); this->mmu_segmentation_facets.set_new_unique_id(); this->fuzzy_skin_facets.set_new_unique_id(); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + this->texture_displacement_facet(i).set_new_unique_id(); } bool is_fdm_support_painted() const { return !this->supported_facets.empty(); } bool is_seam_painted() const { return !this->seam_facets.empty(); } bool is_mm_painted() const { return !this->mmu_segmentation_facets.empty(); } bool is_fuzzy_skin_painted() const { return !this->fuzzy_skin_facets.empty(); } - bool is_any_painted() const { return is_fdm_support_painted() || is_seam_painted() || is_mm_painted() || is_fuzzy_skin_painted(); } + bool is_texture_displacement_painted() const { return !this->texture_displacement_facets_all_empty(); } + bool is_any_painted() const { + return is_fdm_support_painted() || is_seam_painted() || is_mm_painted() || is_fuzzy_skin_painted() || is_texture_displacement_painted(); + } // Orca: Implement prusa's filament shrink compensation approach // Returns 0-based indices of extruders painted by multi-material painting gizmo. @@ -1041,7 +1133,7 @@ protected: friend class SLAPrint; friend class Model; friend class ModelObject; - friend void model_volume_list_update_supports(ModelObject& model_object_dst, const ModelObject& model_object_new); + friend void model_volume_list_update_supports_and_seams(ModelObject& model_object_dst, const ModelObject& model_object_new); // Copies IDs of both the ModelVolume and its config. explicit ModelVolume(const ModelVolume &rhs) = default; @@ -1083,6 +1175,7 @@ private: assert(this->seam_facets.id().valid()); assert(this->mmu_segmentation_facets.id().valid()); assert(this->fuzzy_skin_facets.id().valid()); + assert(this->texture_displacement_facets_ids_valid()); assert(this->id() != this->config.id()); assert(this->id() != this->supported_facets.id()); assert(this->id() != this->seam_facets.id()); @@ -1099,6 +1192,7 @@ private: assert(this->seam_facets.id().valid()); assert(this->mmu_segmentation_facets.id().valid()); assert(this->fuzzy_skin_facets.id().valid()); + assert(this->texture_displacement_facets_ids_valid()); assert(this->id() != this->config.id()); assert(this->id() != this->supported_facets.id()); assert(this->id() != this->seam_facets.id()); @@ -1113,6 +1207,7 @@ private: assert(this->seam_facets.id().valid()); assert(this->mmu_segmentation_facets.id().valid()); assert(this->fuzzy_skin_facets.id().valid()); + assert(this->texture_displacement_facets_ids_valid()); assert(this->id() != this->config.id()); assert(this->id() != this->supported_facets.id()); assert(this->id() != this->seam_facets.id()); @@ -1126,10 +1221,17 @@ private: name(other.name), source(other.source), m_mesh(other.m_mesh), m_convex_hull(other.m_convex_hull), config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation), supported_facets(other.supported_facets), seam_facets(other.seam_facets), mmu_segmentation_facets(other.mmu_segmentation_facets), - fuzzy_skin_facets(other.fuzzy_skin_facets), cut_info(other.cut_info), text_configuration(other.text_configuration), emboss_shape(other.emboss_shape) + fuzzy_skin_facets(other.fuzzy_skin_facets), + texture_displacement_facets_0(other.texture_displacement_facets_0), texture_displacement_facets_1(other.texture_displacement_facets_1), + texture_displacement_facets_2(other.texture_displacement_facets_2), texture_displacement_facets_3(other.texture_displacement_facets_3), + texture_displacement_facets_4(other.texture_displacement_facets_4), texture_displacement_facets_5(other.texture_displacement_facets_5), + texture_displacement_facets_6(other.texture_displacement_facets_6), texture_displacement_facets_7(other.texture_displacement_facets_7), + texture_displacement_layers(other.texture_displacement_layers), + texture_displacement_options(other.texture_displacement_options), + cut_info(other.cut_info), text_configuration(other.text_configuration), emboss_shape(other.emboss_shape) { - assert(this->id().valid()); - assert(this->config.id().valid()); + assert(this->id().valid()); + assert(this->config.id().valid()); assert(this->supported_facets.id().valid()); assert(this->seam_facets.id().valid()); assert(this->mmu_segmentation_facets.id().valid()); @@ -1179,6 +1281,8 @@ private: assert(this->seam_facets.empty()); assert(this->mmu_segmentation_facets.empty()); assert(this->fuzzy_skin_facets.empty()); + assert(this->texture_displacement_facets_all_empty()); + assert(this->texture_displacement_layers.empty()); } ModelVolume& operator=(ModelVolume &rhs) = delete; @@ -1186,13 +1290,17 @@ private: friend class cereal::access; friend class UndoRedo::StackImpl; // Used for deserialization, therefore no IDs are allocated. - ModelVolume() : ObjectBase(-1), config(-1), supported_facets(-1), seam_facets(-1), mmu_segmentation_facets(-1), fuzzy_skin_facets(-1), object(nullptr) { + ModelVolume() : ObjectBase(-1), config(-1), supported_facets(-1), seam_facets(-1), mmu_segmentation_facets(-1), fuzzy_skin_facets(-1), + texture_displacement_facets_0(-1), texture_displacement_facets_1(-1), texture_displacement_facets_2(-1), texture_displacement_facets_3(-1), + texture_displacement_facets_4(-1), texture_displacement_facets_5(-1), texture_displacement_facets_6(-1), texture_displacement_facets_7(-1), + object(nullptr) { assert(this->id().invalid()); assert(this->config.id().invalid()); assert(this->supported_facets.id().invalid()); assert(this->seam_facets.id().invalid()); assert(this->mmu_segmentation_facets.id().invalid()); assert(this->fuzzy_skin_facets.id().invalid()); + assert(this->texture_displacement_facets_ids_invalid()); } template void load(Archive &ar) { bool has_convex_hull; @@ -1212,6 +1320,13 @@ private: mesh_changed |= t != mmu_segmentation_facets.timestamp(); cereal::load_by_value(ar, fuzzy_skin_facets); mesh_changed |= t != fuzzy_skin_facets.timestamp(); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) { + FacetsAnnotation &f = texture_displacement_facet(i); + Timestamp tf = f.timestamp(); + cereal::load_by_value(ar, f); + mesh_changed |= tf != f.timestamp(); + } + ar(texture_displacement_layers, texture_displacement_options); cereal::load_by_value(ar, config); cereal::load(ar, text_configuration); cereal::load(ar, emboss_shape); @@ -1233,6 +1348,9 @@ private: cereal::save_by_value(ar, seam_facets); cereal::save_by_value(ar, mmu_segmentation_facets); cereal::save_by_value(ar, fuzzy_skin_facets); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + cereal::save_by_value(ar, texture_displacement_facet(i)); + ar(texture_displacement_layers, texture_displacement_options); cereal::save_by_value(ar, config); cereal::save(ar, text_configuration); cereal::save(ar, emboss_shape); diff --git a/src/libslic3r/PNGReadWrite.cpp b/src/libslic3r/PNGReadWrite.cpp index 32b9a8f79e..9f6a8b739d 100644 --- a/src/libslic3r/PNGReadWrite.cpp +++ b/src/libslic3r/PNGReadWrite.cpp @@ -54,9 +54,43 @@ static void png_read_callback(png_struct *png_ptr, // Retrieve our input buffer through the png_ptr auto reader = static_cast(png_get_io_ptr(png_ptr)); - if (!reader || !reader->is_ok()) return; + // libpng expects a short read to be reported through png_error(); returning quietly would leave + // it decoding whatever happened to be in outBytes. + if (!reader || !reader->is_ok() || + reader->read(static_cast(outBytes), byteCountToRead) != byteCountToRead) + png_error(png_ptr, "PNG data is truncated"); +} - reader->read(static_cast(outBytes), byteCountToRead); +// libpng reports a corrupt or truncated image by longjmp()ing back to the jump buffer set with +// setjmp(). The frame it lands in must own nothing that needs destroying: with exceptions enabled +// MSVC unwinds the stack as part of longjmp, and returning from a frame unwound that way crashes - +// which is what a truncated texture did on Windows while working everywhere else. So the calls that +// can fail live in these two helpers, which hold nothing but pointers, and every C++ object the +// decoders need stays in their own frames. +static bool png_read_header_guarded(png_struct *png, png_info *info, IStream *in_buf, int sig_bytes) +{ + if (setjmp(png_jmpbuf(png))) + return false; + + png_set_read_fn(png, static_cast(in_buf), png_read_callback); + // Tell that we have already read the first bytes to check the signature + png_set_sig_bytes(png, sig_bytes); + png_read_info(png, info); + return true; +} + +// `bottom_up` fills the buffer last row first, which is the order the colour decoder hands back. +static bool png_read_rows_guarded(png_struct *png, png_info *info, png_bytep dst, size_t rows, size_t rowbytes, + bool bottom_up, bool read_end) +{ + if (setjmp(png_jmpbuf(png))) + return false; + + for (size_t i = 0; i < rows; ++i) + png_read_row(png, dst + (bottom_up ? rows - 1 - i : i) * rowbytes, nullptr); + if (read_end) + png_read_end(png, info); + return true; } bool decode_png(IStream &in_buf, ImageGreyscale &out_img) @@ -77,12 +111,8 @@ bool decode_png(IStream &in_buf, ImageGreyscale &out_img) dsc.info = png_create_info_struct(dsc.png); if(!dsc.info) return false; - png_set_read_fn(dsc.png, static_cast(&in_buf), png_read_callback); - - // Tell that we have already read the first bytes to check the signature - png_set_sig_bytes(dsc.png, PNG_SIG_BYTES); - - png_read_info(dsc.png, dsc.info); + if (!png_read_header_guarded(dsc.png, dsc.info, &in_buf, PNG_SIG_BYTES)) + return false; out_img.cols = png_get_image_width(dsc.png, dsc.info); out_img.rows = png_get_image_height(dsc.png, dsc.info); @@ -94,11 +124,8 @@ bool decode_png(IStream &in_buf, ImageGreyscale &out_img) out_img.buf.resize(out_img.rows * out_img.cols); - auto readbuf = static_cast(out_img.buf.data()); - for (size_t r = 0; r < out_img.rows; ++r) - png_read_row(dsc.png, readbuf + r * out_img.cols, nullptr); - - return true; + return png_read_rows_guarded(dsc.png, dsc.info, static_cast(out_img.buf.data()), out_img.rows, + out_img.cols, /* bottom_up */ false, /* read_end */ false); } bool decode_colored_png(IStream &in_buf, ImageColorscale &out_img) @@ -128,12 +155,10 @@ bool decode_colored_png(IStream &in_buf, ImageColorscale &out_img) return false; } - png_set_read_fn(dsc.png, static_cast(&in_buf), png_read_callback); - - // Tell that we have already read the first bytes to check the signature - png_set_sig_bytes(dsc.png, PNG_SIG_BYTES); - - png_read_info(dsc.png, dsc.info); + if (!png_read_header_guarded(dsc.png, dsc.info, &in_buf, PNG_SIG_BYTES)) { + BOOST_LOG_TRIVIAL(error) << "decode_colored_png: corrupt or truncated PNG data"; + return false; + } out_img.cols = png_get_image_width(dsc.png, dsc.info); out_img.rows = png_get_image_height(dsc.png, dsc.info); @@ -162,13 +187,12 @@ bool decode_colored_png(IStream &in_buf, ImageColorscale &out_img) int interlace_type = png_get_interlace_type(dsc.png, dsc.info); BOOST_LOG_TRIVIAL(info) << boost::format("filter_type %1%, compression_type %2%, interlace_type %3%, rowbytes %4%")%filter_type %compression_type %interlace_type %rowbytes; - auto readbuf = static_cast(out_img.buf.data()); - for (size_t r = out_img.rows; r > 0; r--) - { - png_read_row(dsc.png, readbuf + (r - 1) * rowbytes, nullptr); + if (!png_read_rows_guarded(dsc.png, dsc.info, static_cast(out_img.buf.data()), out_img.rows, rowbytes, + /* bottom_up */ true, /* read_end */ true)) { + BOOST_LOG_TRIVIAL(error) << "decode_colored_png: corrupt or truncated PNG data"; + return false; } - png_read_end(dsc.png, dsc.info); png_destroy_read_struct(&dsc.png, &dsc.info, NULL); return true; diff --git a/src/libslic3r/ParallelResolve.hpp b/src/libslic3r/ParallelResolve.hpp new file mode 100644 index 0000000000..e913be728a --- /dev/null +++ b/src/libslic3r/ParallelResolve.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "Exception.hpp" + +namespace Slic3r { + +// A batch of resolved presets, each a whole config, is what resolve_then_commit adds +// to peak memory, so it stays far below a vendor's preset count and above any core count. +inline constexpr size_t resolve_batch_size = 64; + +// Resolve `count` items that do not depend on each other and install them one at +// a time. +// +// `resolve(i)` runs on any thread and must read only, since the items are +// resolved side by side. `commit(i, resolved)` is called for every item in index +// order, on the calling thread, and is where shared state is written. +// +// The items are worked through in batches, so what is resolved and held at once +// does not grow with `count`. An exception from either callable propagates after +// the batches before it have been committed. A cancellation of the caller's task +// group, which stops a batch partway without an exception, throws RuntimeError +// before that batch commits. +// +// `ChunkSetup`, when given, is constructed once for each piece of a batch TBB hands +// out, for per-thread state a resolve would otherwise set up per item, such as the +// C numeric locale, whose setting takes a lock the whole process shares. +template +void resolve_then_commit(size_t count, Resolve resolve, Commit commit) +{ + using Resolved = std::invoke_result_t; + + std::vector resolved(std::min(count, resolve_batch_size)); + for (size_t first = 0; first < count; first += resolve_batch_size) { + const size_t last = std::min(first + resolve_batch_size, count); + // Isolated, so a thread waiting on the batch runs none of the caller's other + // tasks before finishing it. + tbb::this_task_arena::isolate([&] { + tbb::parallel_for(tbb::blocked_range(first, last), + [&](const tbb::blocked_range& range) { + ChunkSetup setup; + (void) setup; + for (size_t i = range.begin(); i < range.end(); ++ i) + resolved[i - first] = resolve(i); + }); + }); + if (tbb::is_current_task_group_canceling()) + throw RuntimeError("resolve_then_commit: canceled before the batch was resolved"); + for (size_t i = first; i < last; ++ i) + commit(i, std::move(resolved[i - first])); + } +} + +} // namespace Slic3r diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp index 3e29e0c172..1d7abcd5de 100644 --- a/src/libslic3r/PlaceholderParser.cpp +++ b/src/libslic3r/PlaceholderParser.cpp @@ -851,6 +851,8 @@ namespace client // If true, the macro processor will evaluate just a boolean condition using the full expressive power of the macro processor. bool just_boolean_expression = false; std::string error_message; + // Local variables declared in {if} branches that were not taken, see PlaceholderParser::check_inactive_branches. + mutable std::set inactive_local_variables; // Table to translate symbol tag to a human readable error message. static std::map tag_to_error_message; @@ -892,6 +894,8 @@ namespace client } // Inside a block, which is conditionally suppressed? bool skipping() const { return m_depth_suppressed > 0; } + // Are variable names resolved inside the suppressed blocks too? + bool check_inactive_names() const { return PlaceholderParser::check_inactive_branches && ! just_boolean_expression; } const ConfigOption* optptr(const t_config_option_key &opt_key) const override { @@ -927,7 +931,7 @@ namespace client static void legacy_variable_expansion(const MyContext *ctx, IteratorRange &opt_key, std::string &output) { - if (ctx->skipping()) + if (ctx->skipping() && ! ctx->check_inactive_names()) return; std::string opt_key_str(opt_key.begin(), opt_key.end()); @@ -949,7 +953,9 @@ namespace client } } if (opt == nullptr) - ctx->throw_exception("Variable does not exist", opt_key); + ctx->throw_exception(ctx->skipping() ? "Variable does not exist (in an inactive branch)" : "Variable does not exist", opt_key); + if (ctx->skipping()) + return; if (opt->is_scalar()) { if (opt->is_nil()) ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt_key); @@ -972,9 +978,10 @@ namespace client IteratorRange &opt_vector_index, std::string &output) { - if (ctx->skipping()) + if (ctx->skipping() && ! ctx->check_inactive_names()) return; + const char *not_found = ctx->skipping() ? "Variable does not exist (in an inactive branch)" : "Variable does not exist"; std::string opt_key_str(opt_key.begin(), opt_key.end()); const ConfigOption *opt = ctx->resolve_symbol(opt_key_str); if (opt == nullptr) { @@ -984,18 +991,20 @@ namespace client opt = ctx->resolve_symbol(opt_key_str); } if (opt == nullptr) - ctx->throw_exception("Variable does not exist", opt_key); + ctx->throw_exception(not_found, opt_key); } if (! opt->is_vector()) ctx->throw_exception("Trying to index a scalar variable", opt_key); + const ConfigOption *opt_index = ctx->resolve_symbol(std::string(opt_vector_index.begin(), opt_vector_index.end())); + if (opt_index == nullptr) + ctx->throw_exception(not_found, opt_key); + if (opt_index->type() != coInt) + ctx->throw_exception("Indexing variable has to be integer", opt_key); + if (ctx->skipping()) + return; const ConfigOptionVectorBase *vec = static_cast(opt); if (vec->empty()) ctx->throw_exception("Indexing an empty vector variable", opt_key); - const ConfigOption *opt_index = ctx->resolve_symbol(std::string(opt_vector_index.begin(), opt_vector_index.end())); - if (opt_index == nullptr) - ctx->throw_exception("Variable does not exist", opt_key); - if (opt_index->type() != coInt) - ctx->throw_exception("Indexing variable has to be integer", opt_key); int idx = opt_index->getInt(); if (idx < 0) ctx->throw_exception("Negative vector index", opt_key); @@ -1021,6 +1030,13 @@ namespace client output.writable = true; } output.opt = opt; + } else if (ctx->check_inactive_names()) { + // Only check the name. Back tracking may resolve the same identifier twice, so there are no side effects. + const std::string key{ opt_key.begin(), opt_key.end() }; + if (ctx->resolve_symbol(key) == nullptr && ctx->resolve_output_symbol(key) == nullptr && + ctx->inactive_local_variables.count(key) == 0 && + (ctx->context_data == nullptr || ctx->context_data->inactive_global_variables.count(key) == 0)) + ctx->throw_exception("Not a variable name (in an inactive branch)", opt_key); } output.it_range = opt_key; } @@ -1426,6 +1442,13 @@ namespace client out.opt = ctx->config_local.optptr(key); } out.name = std::move(key); + } else if (ctx->check_inactive_names()) { + // Declared in a branch that is not taken: the name still counts as defined for the names that follow. + std::string key(it_range.begin(), it_range.end()); + if (global_variable && ctx->context_data != nullptr) + ctx->context_data->inactive_global_variables.insert(std::move(key)); + else + ctx->inactive_local_variables.insert(std::move(key)); } out.it_range = it_range; } @@ -1660,8 +1683,8 @@ namespace client const OptWithPos &rhs) { if (ctx->skipping()) - // Skipping, continue parsing. - return true; + // Skipping, let conditional_expression parse the whole right hand side, which may continue after the variable reference. + return false; if (lhs.opt) { assert(lhs.opt->is_vector()); diff --git a/src/libslic3r/PlaceholderParser.hpp b/src/libslic3r/PlaceholderParser.hpp index 3f3998dc5a..e32a4de9dc 100644 --- a/src/libslic3r/PlaceholderParser.hpp +++ b/src/libslic3r/PlaceholderParser.hpp @@ -4,6 +4,7 @@ #include "libslic3r.h" #include #include +#include #include #include #include @@ -24,8 +25,15 @@ public: // If defined, then this dictionary is used by the scripts to define user variables and persist them // between PlaceholderParser evaluations. std::unique_ptr global_config; + // Global variables declared in {if} branches that were not taken, see check_inactive_branches. + std::set inactive_global_variables; }; + // Orca: when set, variable names inside {if} branches that are not taken must resolve too, so a single + // expansion checks every branch of a template. Only the profile validator's slice sweep sets it. + // It does not apply to evaluate_boolean_expression(), where an error reads as "compatible". + static inline bool check_inactive_branches = false; + PlaceholderParser(const DynamicConfig *external_config = nullptr); void clear_config() { m_config.clear(); } diff --git a/src/libslic3r/Polygon.cpp b/src/libslic3r/Polygon.cpp index 32b4d062f1..77ff30fb40 100644 --- a/src/libslic3r/Polygon.cpp +++ b/src/libslic3r/Polygon.cpp @@ -318,10 +318,13 @@ Points Polygon::concave_points(double angle_threshold) const } // Projection of a point onto the polygon. -Point Polygon::point_projection(const Point &point) const +Point Polygon::point_projection(const Point &point, size_t *edge_index) const { Point proj = point; double dmin = std::numeric_limits::max(); + // Preserve the existing projection and tie order while optionally tracking its edge. + if (edge_index) + *edge_index = std::numeric_limits::max(); if (! this->points.empty()) { for (size_t i = 0; i < this->points.size(); ++ i) { const Point &pt0 = this->points[i]; @@ -330,11 +333,15 @@ Point Polygon::point_projection(const Point &point) const if (d < dmin) { dmin = d; proj = pt0; + if (edge_index) + *edge_index = i; } d = (point - pt1).cast().norm(); if (d < dmin) { dmin = d; proj = pt1; + if (edge_index) + *edge_index = (i + 1) % this->points.size(); } Vec2d v1(coordf_t(pt1(0) - pt0(0)), coordf_t(pt1(1) - pt0(1))); coordf_t div = v1.squaredNorm(); @@ -347,6 +354,8 @@ Point Polygon::point_projection(const Point &point) const if (d < dmin) { dmin = d; proj = foot; + if (edge_index) + *edge_index = i; } } } diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 7d996055e5..34ca214cf3 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -85,7 +85,9 @@ public: Points convex_points(double angle_threshold = 0.) const; Points concave_points(double angle_threshold = 0.) const; // Projection of a point onto the polygon. - Point point_projection(const Point &point) const; + // Optional index: start of the closest edge, or the vertex itself for an endpoint. + // Empty polygons return the query point and std::numeric_limits::max() as the index. + Point point_projection(const Point &point, size_t *edge_index = nullptr) const; std::vector parameter_by_length() const; //BBS diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 9af8969490..cd02465fb0 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -5,6 +5,8 @@ #include "Preset.hpp" #include "PresetBundle.hpp" #include "AppConfig.hpp" +#include "LocalesUtils.hpp" +#include "ParallelResolve.hpp" #ifdef _MSC_VER #define WIN32_LEAN_AND_MEAN @@ -506,10 +508,11 @@ void Preset::normalize(DynamicPrintConfig &config) handle_legacy_sla(config); } -std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config) +std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config, + const DynamicPrintConfig *added) { std::string incorrect_keys; - for (const std::string &key : config.keys()) + for (const std::string &key : (added != nullptr ? *added : config).keys()) if (! default_config.has(key)) { if (incorrect_keys.empty()) incorrect_keys = key; @@ -621,7 +624,6 @@ void Preset::load_info(const std::string& file) } else if (v.first.compare("base_id") == 0) { this->base_id = v.second.get_value(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " load info from: " << file << " and base_id: " << this->base_id; if (this->base_id.compare("null") == 0) this->base_id.clear(); } @@ -974,6 +976,37 @@ void Preset::get_extruder_names_and_keysets(Type type, std::string& extruder_id_ } } +DynamicPrintConfig Preset::load_external_config(Type type, const DynamicPrintConfig &default_config, const DynamicPrintConfig &project_config, + const std::set &different_settings_list, + const std::function &find_base, + t_config_option_keys *keys) +{ + // Load the preset over a default preset, so that the missing fields are filled in from the default preset. + DynamicPrintConfig cfg(default_config); + // SoftFever: ignore print connection info from project + auto cfg_keys = cfg.keys(); + cfg_keys.erase(std::remove_if(cfg_keys.begin(), cfg_keys.end(), + [](std::string &val) { + return val == "print_host" || val == "print_host_webui" || val == "printhost_apikey" || + val == "printhost_cafile" || val == "printhost_user" || val == "printhost_password" || val == "printhost_port"; + }), + cfg_keys.end()); + cfg.apply_only(project_config, cfg_keys, true); + + //add different settings check logic, replace the old system preset's default value with new system preset's default values + if (!different_settings_list.empty()) { + if (DynamicPrintConfig *base_config = find_base(Preset::inherits(cfg))) { + std::string extruder_id_name, extruder_variant_name; + std::set *key_set1 = nullptr, *key_set2 = nullptr; + Preset::get_extruder_names_and_keysets(type, extruder_id_name, extruder_variant_name, &key_set1, &key_set2); + cfg.update_non_diff_values_to_base_config(*base_config, cfg_keys, different_settings_list, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); + } + } + if (keys) + *keys = std::move(cfg_keys); + return cfg; +} + bool Preset::has_lidar(PresetBundle *preset_bundle) { bool has_lidar = false; @@ -1669,6 +1702,169 @@ std::string PresetCollection::canonical_preset_name(const std::string &name, con return get_preset_canonical_name(parsed.bare, origin); } +PresetCollection::UserPresetLoad PresetCollection::resolve_user_preset( + const boost::filesystem::path &file, const std::string &canonical_name, + const PresetOrigin &load_origin, ForwardCompatibilitySubstitutionRule substitution_rule, + const std::string &extruder_id_name, const std::string &extruder_variant_name, + std::set *key_set1, std::set *key_set2) const +{ + UserPresetLoad out; + out.preset = Preset(m_type, canonical_name, false); + Preset &preset = out.preset; + preset.bundle_id = load_origin.bundle_id; + preset.file = file.string(); + // Load the preset file, apply preset values on top of defaults. + try { + fs::path idx_path(preset.file); + idx_path.replace_extension(".info"); + if (fs::exists(idx_path)) { + out.info_file = idx_path.string(); + preset.load_info(out.info_file); + } + DynamicPrintConfig config; + //BBS: change to json format + //ConfigSubstitutions config_substitutions = config.load_from_ini(preset.file, substitution_rule); + std::map key_values; + std::string reason; + ConfigSubstitutions config_substitutions = config.load_from_json(preset.file, substitution_rule, key_values, reason); + if (! config_substitutions.empty()) + out.substitutions.push_back({ preset.name, m_type, PresetConfigSubstitutions::Source::UserFile, preset.file, std::move(config_substitutions) }); + if (!reason.empty()) { + out.discard_file = true; + out.errors.push_back((boost::format("parse config %1% failed") % preset.file).str()); + return out; + } + + std::string version_str = key_values[BBL_JSON_KEY_VERSION]; + boost::optional version = Semver::parse(version_str); + if (!version) return out; + preset.version = *version; + + if (key_values.find(BBL_JSON_KEY_FILAMENT_ID) != key_values.end()) + preset.filament_id = key_values[BBL_JSON_KEY_FILAMENT_ID]; + if (key_values.find(BBL_JSON_KEY_DESCRIPTION) != key_values.end()) + preset.description = key_values[BBL_JSON_KEY_DESCRIPTION]; + if (key_values.find(BBL_JSON_KEY_INSTANTIATION) != key_values.end()) + preset.is_visible = key_values[BBL_JSON_KEY_INSTANTIATION] != "false"; + + //Orca: find and use the inherit config as the base + const Preset* inherit_preset = nullptr; + ConfigOption* inherits_config = config.option(BBL_JSON_KEY_INHERITS); + + // check inherits_config + if (inherits_config) { + ConfigOptionString * option_str = dynamic_cast (inherits_config); + std::string inherits_value = option_str->value; + // Orca: try to find if the parent preset has been renamed + inherit_preset = this->find_preset2(inherits_value); + Preset::normalize_inherits(config, inherit_preset); + } + const Preset& default_preset = this->default_preset_for(config); + if (inherit_preset) { + preset.config = inherit_preset->config; + preset.filament_id = inherit_preset->filament_id; + extend_default_config_length(config, false, {}); + preset.config.update_diff_values_to_child_config(config, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); + } + else { + auto inherits_config2 = dynamic_cast(inherits_config); + if ((inherits_config2 && !inherits_config2->value.empty())) { + out.errors.push_back((boost::format("can not find parent %1% for config %2%!") % inherits_config2->value % preset.file).str()); + return out; + } + // We support custom root preset now + // Find a default preset for the config. The PrintPresetCollection provides different default preset based on the "printer_technology" field. + preset.config = default_preset.config; + preset.config.apply(std::move(config)); + extend_default_config_length(preset.config, true, default_preset.config); + } + + Preset::normalize(preset.config); + // Report configuration fields, which are misplaced into a wrong group. + std::string incorrect_keys = Preset::remove_invalid_keys(preset.config, default_preset.config); + if (!incorrect_keys.empty()) + out.errors.push_back("Error in a preset file: The preset \"" + preset.file + + "\" contains the following incorrect keys: " + incorrect_keys + ", which were removed"); + + if (preset.type == Preset::TYPE_FILAMENT && preset.is_user() && preset.inherits().empty()) { + auto compatible_printers = dynamic_cast(preset.config.option("compatible_printers", true)); + if (compatible_printers && compatible_printers->values.empty()) { + size_t at_pos = canonical_name.find('@'); + if (at_pos != std::string::npos && at_pos + 1 < canonical_name.length()) { + compatible_printers->values.push_back(canonical_name.substr(at_pos + 1)); + out.save_compatible_printers = true; + } + } + } + + preset.loaded = true; + out.complete = true; + } catch (const std::ifstream::failure &err) { + out.discard_file = true; + out.errors.push_back((boost::format("The user-config cannot be loaded: %1%. Reason: %2%") % preset.file % err.what()).str()); + //throw Slic3r::RuntimeError(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what()); + } catch (const std::runtime_error &err) { + out.discard_file = true; + out.errors.push_back((boost::format("Failed loading the user-config file: %1%. Reason: %2%") % preset.file % err.what()).str()); + //throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what()); + } + out.install = true; + return out; +} + +void PresetCollection::commit_user_preset(UserPresetLoad &&loaded, std::deque &presets_loaded, + PresetsConfigSubstitutions &substitutions, + const std::function &preset_loaded_fn, + bool read_only) +{ + Preset &preset = loaded.preset; + if (! loaded.info_file.empty()) + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " load info from: " << loaded.info_file << " and base_id: " << preset.base_id; + append(substitutions, std::move(loaded.substitutions)); + for (const std::string &error : loaded.errors) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << error; + } + if (loaded.discard_file && !read_only) { + fs::path file_path(loaded.preset.file); + if (fs::exists(file_path)) + fs::remove(file_path); + file_path.replace_extension(".info"); + if (fs::exists(file_path)) + fs::remove(file_path); + } + if (!loaded.install) + return; + + if (loaded.complete) { + if (loaded.save_compatible_printers) { + // A filesystem error from the rewrite is counted, and the preset still loads. + try { + if (!read_only) + preset.save(nullptr); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " added compatible_printers for preset: " << preset.name; + } catch (const std::runtime_error &err) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " can not write compatible_printers back to " << preset.file << ": " << err.what(); + } + } + //BBS: add some workaround for previous incorrect settings + if ((!preset.setting_id.empty())&&(preset.setting_id == preset.base_id)) + preset.setting_id.clear(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " load preset: " << preset.name << " and filament_id: " << preset.filament_id << " and base_id: " << preset.base_id; + //BBS: add config related logs + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", preset type %1%, name %2%, path %3%, is_system %4%, is_default %5% is_visible %6%")%Preset::get_type_string(m_type) %preset.name %preset.file %preset.is_system %preset.is_default %preset.is_visible; + // add alias for custom filament preset + set_custom_preset_alias(preset); + } + + if (preset_loaded_fn != nullptr) + preset_loaded_fn(preset); + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load config successful and preset name is:" << preset.name; + presets_loaded.emplace_back(std::move(preset)); +} + // Load all presets found in dir_path. // Throws an exception on error. void PresetCollection::load_presets( @@ -1706,6 +1902,8 @@ void PresetCollection::load_presets( std::set *key_set1 = nullptr, *key_set2 = nullptr; Preset::get_extruder_names_and_keysets(m_type, extruder_id_name, extruder_variant_name, &key_set1, &key_set2); + struct UserPresetFile { fs::path path; std::string canonical_name; }; + std::vector files; //BBS: change to json format for (auto &dir_entry : boost::filesystem::directory_iterator(dir)) { @@ -1721,149 +1919,26 @@ void PresetCollection::load_presets( BOOST_LOG_TRIVIAL(warning) << "Preset already present, not loading: " << canonical_name; continue; } + files.push_back({ dir_entry.path(), std::move(canonical_name) }); + } + } + + resolve_then_commit(files.size(), + [&](size_t i) { + return this->resolve_user_preset(files[i].path, files[i].canonical_name, resolved_origin, substitution_rule, + extruder_id_name, extruder_variant_name, key_set1, key_set2); + }, + [&](size_t, UserPresetLoad &&loaded) { + // Committing can remove an unreadable preset's file, and a filesystem error + // there is reported without stopping the rest of the directory. try { - Preset preset(m_type, canonical_name, false); - preset.bundle_id = resolved_origin.bundle_id; - preset.file = dir_entry.path().string(); - // Load the preset file, apply preset values on top of defaults. - try { - fs::path idx_path(preset.file); - idx_path.replace_extension(".info"); - if (fs::exists(idx_path)) { - preset.load_info(idx_path.string()); - } - DynamicPrintConfig config; - //BBS: change to json format - //ConfigSubstitutions config_substitutions = config.load_from_ini(preset.file, substitution_rule); - std::map key_values; - std::string reason; - ConfigSubstitutions config_substitutions = config.load_from_json(preset.file, substitution_rule, key_values, reason); - if (! config_substitutions.empty()) - substitutions.push_back({ preset.name, m_type, PresetConfigSubstitutions::Source::UserFile, preset.file, std::move(config_substitutions) }); - if (!reason.empty()) { - fs::path file_path(preset.file); - if (!read_only && fs::exists(file_path)) - fs::remove(file_path); - file_path.replace_extension(".info"); - if (!read_only && fs::exists(file_path)) - fs::remove(file_path); - BOOST_LOG_TRIVIAL(error) << boost::format("parse config %1% failed")%preset.file; - ++m_errors; - continue; - } - - std::string version_str = key_values[BBL_JSON_KEY_VERSION]; - boost::optional version = Semver::parse(version_str); - if (!version) continue; - preset.version = *version; - - if (key_values.find(BBL_JSON_KEY_FILAMENT_ID) != key_values.end()) - preset.filament_id = key_values[BBL_JSON_KEY_FILAMENT_ID]; - if (key_values.find(BBL_JSON_KEY_DESCRIPTION) != key_values.end()) - preset.description = key_values[BBL_JSON_KEY_DESCRIPTION]; - if (key_values.find(BBL_JSON_KEY_INSTANTIATION) != key_values.end()) - preset.is_visible = key_values[BBL_JSON_KEY_INSTANTIATION] != "false"; - - //Orca: find and use the inherit config as the base - Preset* inherit_preset = nullptr; - ConfigOption* inherits_config = config.option(BBL_JSON_KEY_INHERITS); - - // check inherits_config - if (inherits_config) { - ConfigOptionString * option_str = dynamic_cast (inherits_config); - std::string inherits_value = option_str->value; - // Orca: try to find if the parent preset has been renamed - inherit_preset = this->find_preset2(inherits_value); - Preset::normalize_inherits(config, inherit_preset); - } else { - ; - } - const Preset& default_preset = this->default_preset_for(config); - if (inherit_preset) { - preset.config = inherit_preset->config; - preset.filament_id = inherit_preset->filament_id; - extend_default_config_length(config, false, {}); - preset.config.update_diff_values_to_child_config(config, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); - } - else { - auto inherits_config2 = dynamic_cast(inherits_config); - if ((inherits_config2 && !inherits_config2->value.empty())) { - BOOST_LOG_TRIVIAL(error) << boost::format("can not find parent %1% for config %2%!")%inherits_config2->value %preset.file; - ++m_errors; - continue; - } - // We support custom root preset now - // Find a default preset for the config. The PrintPresetCollection provides different default preset based on the "printer_technology" field. - preset.config = default_preset.config; - preset.config.apply(std::move(config)); - extend_default_config_length(preset.config, true, default_preset.config); - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " load preset: " << name << " and filament_id: " << preset.filament_id << " and base_id: " << preset.base_id; - - Preset::normalize(preset.config); - // Report configuration fields, which are misplaced into a wrong group. - std::string incorrect_keys = Preset::remove_invalid_keys(preset.config, default_preset.config); - if (!incorrect_keys.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) - << "Error in a preset file: The preset \"" << preset.file - << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; - } - - if (preset.type == Preset::TYPE_FILAMENT && preset.is_user() && preset.inherits().empty()) { - auto compatible_printers = dynamic_cast(preset.config.option("compatible_printers", true)); - if (compatible_printers && compatible_printers->values.empty()) { - size_t at_pos = name.find('@'); - if (at_pos != std::string::npos && at_pos + 1 < name.length()) { - compatible_printers->values.push_back(name.substr(at_pos + 1)); - if (!read_only) - preset.save(nullptr); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " added compatible_printers for preset: " << name; - } - } - } - - preset.loaded = true; - //BBS: add some workaround for previous incorrect settings - if ((!preset.setting_id.empty())&&(preset.setting_id == preset.base_id)) - preset.setting_id.clear(); - //BBS: add config related logs - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", preset type %1%, name %2%, path %3%, is_system %4%, is_default %5% is_visible %6%")%Preset::get_type_string(m_type) %preset.name %preset.file %preset.is_system %preset.is_default %preset.is_visible; - // add alias for custom filament preset - set_custom_preset_alias(preset); - } catch (const std::ifstream::failure &err) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << boost::format("The user-config cannot be loaded: %1%. Reason: %2%")%preset.file %err.what(); - fs::path file_path(preset.file); - if (!read_only && fs::exists(file_path)) - fs::remove(file_path); - file_path.replace_extension(".info"); - if (!read_only && fs::exists(file_path)) - fs::remove(file_path); - //throw Slic3r::RuntimeError(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what()); - } catch (const std::runtime_error &err) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << boost::format("Failed loading the user-config file: %1%. Reason: %2%")%preset.file %err.what(); - //throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what()); - fs::path file_path(preset.file); - if (!read_only && fs::exists(file_path)) - fs::remove(file_path); - file_path.replace_extension(".info"); - if (!read_only && fs::exists(file_path)) - fs::remove(file_path); - } - - if (preset_loaded_fn != nullptr) - preset_loaded_fn(preset); - - presets_loaded.emplace_back(preset); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load config successful and preset name is:" << preset.name; + this->commit_user_preset(std::move(loaded), presets_loaded, substitutions, preset_loaded_fn, read_only); } catch (const std::runtime_error &err) { errors_cummulative += err.what(); errors_cummulative += "\n"; } - } - } + }); + if (presets_loaded.size() > 0) m_presets.insert(m_presets.end(), std::make_move_iterator(presets_loaded.begin()), std::make_move_iterator(presets_loaded.end())); sort_presets(); @@ -2596,20 +2671,6 @@ std::pair PresetCollection::load_external_preset( const Semver file_version, const std::string filament_id) { - // Load the preset over a default preset, so that the missing fields are filled in from the default preset. - DynamicPrintConfig cfg(this->default_preset_for(combined_config).config); - // SoftFever: ignore print connection info from project - auto keys = cfg.keys(); - keys.erase(std::remove_if(keys.begin(), keys.end(), - [](std::string &val) { - return val == "print_host" || val == "print_host_webui" || val == "printhost_apikey" || - val == "printhost_cafile" || val == "printhost_user" || val == "printhost_password" || val == "printhost_port"; - }), - keys.end()); - cfg.apply_only(combined_config, keys, true); - std::string &inherits = Preset::inherits(cfg); - - //add different settings check logic, replace the old system preset's default value with new system preset's default values std::deque::iterator it = this->find_preset_internal(original_name); bool found = it != m_presets.end() && it->name == original_name; if (! found) { @@ -2618,24 +2679,25 @@ std::pair PresetCollection::load_external_preset( found = it != m_presets.end(); } - std::string extruder_id_name, extruder_variant_name; - std::set *key_set1 = nullptr, *key_set2 = nullptr; - Preset::get_extruder_names_and_keysets(m_type, extruder_id_name, extruder_variant_name, &key_set1, &key_set2); - - if (!inherits.empty() && (different_settings_list.size() > 0)) { - auto iter = this->find_preset_internal(inherits); - if (iter == m_presets.end() || iter->name != inherits) - iter = this->find_preset_renamed(inherits); - if (iter != m_presets.end()) { - //std::vector dirty_options = cfg.diff(iter->config); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": change preset %1% inherit %2% 's value to %3% 's values")%original_name %inherits %path; - cfg.update_non_diff_values_to_base_config(iter->config, keys, different_settings_list, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); - } - } - else if (found && it->is_system && (different_settings_list.size() > 0)) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": change preset %1% 's value to %2% 's values")%original_name %path; - cfg.update_non_diff_values_to_base_config(it->config, keys, different_settings_list, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); - } + t_config_option_keys keys; + DynamicPrintConfig cfg = Preset::load_external_config(m_type, this->default_preset_for(combined_config).config, combined_config, different_settings_list, + [this, &original_name, &path, found, it](const std::string &inherits) -> DynamicPrintConfig * { + if (!inherits.empty()) { + auto iter = this->find_preset_internal(inherits); + if (iter == m_presets.end() || iter->name != inherits) + iter = this->find_preset_renamed(inherits); + if (iter == m_presets.end()) + return nullptr; + BOOST_LOG_TRIVIAL(info) << "load_external_preset" << boost::format(": change preset %1% inherit %2% 's value to %3% 's values")%original_name %inherits %path; + return &iter->config; + } + if (found && it->is_system) { + BOOST_LOG_TRIVIAL(info) << "load_external_preset" << boost::format(": change preset %1% 's value to %2% 's values")%original_name %path; + return &it->config; + } + return nullptr; + }, &keys); + std::string &inherits = Preset::inherits(cfg); //BBS: add config related logs BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" enter, type %1% , path %2%, name %3%, original_name %4%, inherits %5%")%Preset::get_type_string(m_type) %path %name %original_name %inherits; @@ -2827,6 +2889,18 @@ std::pair PresetCollection::load_external_preset( return std::make_pair(&preset, false); } +Preset& PresetCollection::append_preset(std::string &&path, const std::string &name, DynamicPrintConfig &&config) +{ + lock(); + Preset &preset = m_presets.emplace_back(m_type, name, false); + preset.file = std::move(path); + preset.config = std::move(config); + preset.loaded = true; + preset.is_dirty = false; + unlock(); + return preset; +} + Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select, Semver file_version) { lock(); @@ -3846,28 +3920,53 @@ bool PresetCollection::select_preset_by_name_strict(const std::string &name) return false; } -// Merge one vendor's presets with the other vendor's presets, report duplicates. -std::vector PresetCollection::merge_presets(PresetCollection &&other, const VendorMap &new_vendors) +std::vector> PresetCollection::merge_presets(const std::vector &others, const VendorMap &new_vendors) { - std::vector duplicates; - for (Preset &preset : other.m_presets) { - if (preset.is_default || preset.is_external) - continue; - Preset key(m_type, preset.name); - auto it = (m_type == Preset::TYPE_FILAMENT) - ? std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key, filament_preset_less) - : std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key); - if (it == m_presets.end() || it->name != preset.name) { + auto less = [this](const Preset &a, const Preset &b) { + return m_type == Preset::TYPE_FILAMENT ? filament_preset_less(a, b) : a < b; + }; + struct Incoming { Preset *preset; size_t source; }; + auto incoming_less = [&less](const Incoming &a, const Incoming &b) { return less(*a.preset, *b.preset); }; + // Each of `others` is sorted, so its presets form one sorted run. + std::vector incoming; + std::vector run_ends { 0 }; + for (size_t source = 0; source < others.size(); ++ source) { + for (Preset &preset : others[source]->m_presets) + if (! preset.is_default && ! preset.is_external) + incoming.push_back({ &preset, source }); + assert(std::is_sorted(incoming.begin() + run_ends.back(), incoming.end(), incoming_less)); + run_ends.push_back(incoming.size()); + } + // Merged pairwise and stably, so equal names stay in the order of `others`. + const size_t runs = others.size(); + for (size_t width = 1; width < runs; width *= 2) + for (size_t i = 0; i + width < runs; i += 2 * width) + std::inplace_merge(incoming.begin() + run_ends[i], incoming.begin() + run_ends[i + width], + incoming.begin() + run_ends[std::min(i + 2 * width, runs)], incoming_less); + + std::vector> duplicates(others.size()); + std::deque merged; + auto own = m_presets.begin() + m_num_default_presets; + std::move(m_presets.begin(), own, std::back_inserter(merged)); + // On equal names this collection's preset is kept, else the earliest of `others`, + // and each repeat is listed under the collection it came from. + for (auto next = incoming.begin(); own != m_presets.end() || next != incoming.end();) { + if (next == incoming.end() || (own != m_presets.end() && ! less(*next->preset, *own))) + merged.emplace_back(std::move(*own ++)); + else { + Preset &preset = *(next ++)->preset; if (preset.vendor != nullptr) { // Re-assign a pointer to the vendor structure in the new PresetBundle. auto it = new_vendors.find(preset.vendor->id); assert(it != new_vendors.end()); preset.vendor = &it->second; } - m_presets.emplace(it, std::move(preset)); - } else - duplicates.emplace_back(std::move(preset.name)); + merged.emplace_back(std::move(preset)); + } + for (; next != incoming.end() && next->preset->name == merged.back().name; ++ next) + duplicates[next->source].emplace_back(next->preset->name); } + m_presets = std::move(merged); return duplicates; } diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 5b32d90ac6..418ba19fc6 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -403,6 +403,15 @@ public: std::string get_current_printer_type(PresetBundle *preset_bundle); // get current preset type static void get_extruder_names_and_keysets(Type type, std::string& extruder_id_name, std::string& extruder_variant_name, std::set** p_key_set1, std::set** p_key_set2); + // Config of a preset loaded from a project or config file: the project's values over the type's + // default preset config, without the print-host keys. When different_settings_list is not empty, + // every key not listed in it is then refreshed from the base system preset, which find_base returns + // for the project's "inherits" (nullptr when there is none), with the listed per-variant values + // mapped onto the base's extruder variants. keys, if given, receives the keys taken from the project. + static DynamicPrintConfig load_external_config(Type type, const DynamicPrintConfig &default_config, const DynamicPrintConfig &project_config, + const std::set &different_settings_list, + const std::function &find_base, + t_config_option_keys *keys = nullptr); std::string get_printer_id() const { return vendor ? vendor->id : ""; } bool has_lidar(PresetBundle *preset_bundle); @@ -445,7 +454,10 @@ public: static std::string remove_suffix_modified(const std::string& name); static void normalize(DynamicPrintConfig &config); // Report configuration fields, which are misplaced into a wrong group, remove them from the config. - static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config); + // `added`, when given, is the diff applied over a copy of default_config, and only + // its keys are checked, since no other key can be missing from default_config. + static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config, + const DynamicPrintConfig *added = nullptr); // BBS: move constructor to public Preset(Type type, const std::string &name, bool is_default = false) : type(type), is_default(is_default), name(name) {} @@ -801,6 +813,8 @@ public: // Return number of presets including the "- default -" preset. size_t size() const { return m_presets.size(); } bool has_defaults_only() const { return m_presets.size() <= m_num_default_presets; } + // How many presets this collection refused or repaired while loading. + int error_count() const { return m_errors; } // For Print / Filament presets, disable those, which are not compatible with the printer. template @@ -874,8 +888,10 @@ protected: // This is a temporary state, which shall be fixed immediately by the following step. bool select_preset_by_name_strict(const std::string &name); - // Merge one vendor's presets with the other vendor's presets, report duplicates. - std::vector merge_presets(PresetCollection &&other, const VendorMap &new_vendors); + // Move the presets of `others` into this collection in one pass. A name this + // collection or an earlier one of `others` already has is left out, and reported + // in the list of the collection that repeats it. + std::vector> merge_presets(const std::vector &others, const VendorMap &new_vendors); // Update m_map_alias_to_profile_name from loaded system profiles. void update_map_alias_to_profile_name(); @@ -890,6 +906,43 @@ protected: void set_custom_preset_alias(Preset &preset); private: + // One preset file read and flattened against the presets already in this + // collection, before anything the collection shares has been touched. + struct UserPresetLoad + { + Preset preset; + // Joins the collection. A file that threw partway still joins it, without + // the steps that did not run. + bool install { false }; + // The whole of the load ran, so the preset is ready to be aliased. + bool complete { false }; + // A filament preset that named no compatible printer and was given one from + // its name, which commit writes back to its file. + bool save_compatible_printers { false }; + // Unreadable, so commit removes it and its .info file. + bool discard_file { false }; + // The .info file read beside the preset, which commit logs. + std::string info_file; + // Counted and logged by commit, in the order the directory listed the files. + std::vector errors; + PresetsConfigSubstitutions substitutions; + }; + + // Read and flatten one preset file. It reads only, and resolves against the presets + // loaded before this pass, never another file of the same pass, so the files of a + // pass are independent of each other. + UserPresetLoad resolve_user_preset(const boost::filesystem::path &file, const std::string &canonical_name, + const PresetOrigin &load_origin, ForwardCompatibilitySubstitutionRule substitution_rule, + const std::string &extruder_id_name, const std::string &extruder_variant_name, + std::set *key_set1, std::set *key_set2) const; + + // Install one resolved preset. The collection, its alias maps, the error count + // and the preset files on disk are touched here and only here. + void commit_user_preset(UserPresetLoad &&loaded, std::deque &presets_loaded, + PresetsConfigSubstitutions &substitutions, + const std::function &preset_loaded_fn, + bool read_only); + std::string canonical_preset_name(const std::string &name, const PresetOrigin &load_origin = PresetOrigin()) const; // Comparator that sorts "Generic " prefixed presets before others, then alphabetically within each group. @@ -901,6 +954,10 @@ private: return a.name < b.name; } + // Append a preset without keeping the collection sorted, for a caller installing + // many at once; find_preset() is unusable until sort_presets() runs. + Preset& append_preset(std::string &&path, const std::string &name, DynamicPrintConfig &&config); + // Sort presets: filament presets use generic-first ordering, others sort alphabetically. void sort_presets() { if (m_type == Preset::TYPE_FILAMENT) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index aadd330374..99ab3c4e3a 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -5,6 +5,7 @@ #include "PresetBundle.hpp" +#include "ParallelResolve.hpp" #include "PresetCacheFormat.hpp" #include "PrintConfig.hpp" #include "PublishSettings.hpp" @@ -19,6 +20,7 @@ #include #include +#include #include #include #include @@ -37,6 +39,8 @@ #include #include #include +#include +#include // Mark string for localization and translate. #define L(s) Slic3r::I18N::translate(s) @@ -199,7 +203,8 @@ DynamicPrintConfig PresetBundle::construct_full_config( if (num_filaments <= 1) { // BBS: update filament config related with variants DynamicPrintConfig filament_config = in_filament_presets[0].config; - if (apply_extruder && ((extruder_count > 1) || different_extruder)) + // Orca: a multi-variant filament resolves its variants on a single-variant printer too. + if (apply_extruder && ((extruder_count > 1) || different_extruder || filament_config.has_multi_variant_filament())) filament_config.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[0], (NozzleVolumeType)filament_volume_maps[0]); out.apply(filament_config); compatible_printers_condition.emplace_back(in_filament_presets[0].compatible_printers_condition()); @@ -223,7 +228,8 @@ DynamicPrintConfig PresetBundle::construct_full_config( filament_temp_configs.resize(num_filaments); for (size_t i = 0; i < num_filaments; ++i) { filament_temp_configs[i] = *(filament_configs[i]); - if (apply_extruder && ((extruder_count > 1) || different_extruder)) + // Orca: a multi-variant filament resolves its variants on a single-variant printer too. + if (apply_extruder && ((extruder_count > 1) || different_extruder || filament_temp_configs[i].has_multi_variant_filament())) filament_temp_configs[i].update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[i], (NozzleVolumeType)filament_volume_maps[i]); } @@ -575,18 +581,20 @@ bool PresetBundle::resolve_preset_config(DynamicPrintConfig &config, Preset::Typ const PresetBundle *PresetBundle::load_source_vendor(const boost::filesystem::path &root_dir, const std::string &vendor_id, ForwardCompatibilitySubstitutionRule compatibility_rule, - std::string &error) + std::string &error, bool allow_cache) { - auto key = std::make_tuple(root_dir.string(), vendor_id, compatibility_rule); + auto key = std::make_tuple(root_dir.string(), vendor_id, compatibility_rule, allow_cache); if (auto it = m_source_vendor_bundles.find(key); it != m_source_vendor_bundles.end()) return it->second.get(); // The library loads with no base of its own, so the tree a vendor inherits from // is the same one that resolves the library's own presets. - const PresetBundle *library = nullptr; + const std::string library_file = std::string(ORCA_FILAMENT_LIBRARY); + const PresetBundle *library = nullptr; if (vendor_id != ORCA_FILAMENT_LIBRARY && - boost::filesystem::is_regular_file(root_dir / (std::string(ORCA_FILAMENT_LIBRARY) + ".json"))) { - library = load_source_vendor(root_dir, ORCA_FILAMENT_LIBRARY, compatibility_rule, error); + (boost::filesystem::is_regular_file(root_dir / (library_file + ".json")) || + (allow_cache && boost::filesystem::is_regular_file(root_dir / (library_file + ".opc"))))) { + library = load_source_vendor(root_dir, ORCA_FILAMENT_LIBRARY, compatibility_rule, error, allow_cache); if (library == nullptr) { error = "OrcaFilamentLibrary contains invalid presets"; return nullptr; @@ -595,7 +603,7 @@ const PresetBundle *PresetBundle::load_source_vendor(const boost::filesystem::pa auto bundle = std::make_unique(); bundle->m_preserve_vendor_source_paths = true; - bundle->load_vendor_configs_from_json(root_dir.string(), vendor_id, LoadSystem, compatibility_rule, library, false); + bundle->load_vendor_configs_from_json(root_dir.string(), vendor_id, LoadSystem, compatibility_rule, library, allow_cache); if (bundle->error_count() != 0) { error = "Vendor bundle contains invalid presets"; return nullptr; @@ -638,6 +646,43 @@ bool PresetBundle::resolve_preset_config_type(DynamicPrintConfig &config, Preset return true; } +bool PresetBundle::resolve_system_preset(DynamicPrintConfig &config, Preset::Type type, const std::string &name, + ForwardCompatibilitySubstitutionRule compatibility_rule, std::string &error) +{ + const std::string vendor_id = find_preset_vendor(name, type); + if (vendor_id.empty()) { + error = "No vendor lists the preset"; + return false; + } + // Release builds ship a vendor as its preset cache alone, without the profile JSONs. + auto installed = [&vendor_id](const fs::path &root) { + return fs::is_regular_file(root / (vendor_id + ".json")) || fs::is_regular_file(root / (vendor_id + ".opc")); + }; + fs::path root_dir = fs::path(data_dir()) / PRESET_SYSTEM_DIR; + if (!installed(root_dir)) + root_dir = fs::path(resources_dir()) / PRESET_PROFILES_DIR; + const bool cache_only = !fs::is_regular_file(root_dir / (vendor_id + ".json")); + + try { + const PresetBundle *vendor = load_source_vendor(root_dir, vendor_id, compatibility_rule, error, cache_only); + if (vendor == nullptr) + return false; + const PresetCollection &collection = type == Preset::TYPE_PRINTER ? vendor->printers : + type == Preset::TYPE_PRINT ? vendor->prints : vendor->filaments; + const Preset *preset = collection.find_preset(name, false); + if (preset == nullptr) { + error = "Preset was not found in its vendor bundle"; + return false; + } + config = preset->config; + } catch (const std::exception &ex) { + error = ex.what(); + return false; + } + error.clear(); + return true; +} + PresetBundle::PresetBundle(const PresetBundle &rhs) { *this = rhs; @@ -2499,35 +2544,129 @@ std::pair PresetBundle::load_system_pre if (validation_mode) dir = (boost::filesystem::path(data_dir())).make_preferred(); - const auto load_t0 = std::chrono::steady_clock::now(); - // The vendors below are loaded whole and against each other — the filament // library first, then every other vendor with it as the base — so each parse // is complete enough to be worth caching. m_generate_vendor_caches = allow_cache && (m_generate_vendor_caches || !validation_mode); + // Sorted, so any duplicate-preset warning comes out in the same order on every run. + std::vector vendors; + for (const std::string& name : vendor_names_in(dir)) + if (name == ORCA_FILAMENT_LIBRARY || !(validation_mode && !vendor_to_validate.empty() && name != vendor_to_validate)) + vendors.push_back({ name, dir }); + auto result = this->load_vendors(vendors, compatibility_rule, allow_cache); + + this->update_system_maps(); + + //BBS: add config related logs + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" finished, errors_cummulative %1%")%result.second; + return result; +} + +std::pair PresetBundle::load_vendors(const std::vector& vendors, + ForwardCompatibilitySubstitutionRule compatibility_rule, bool allow_cache, const std::atomic* cancel, + std::vector* failed) +{ + const auto load_t0 = std::chrono::steady_clock::now(); + auto canceled = [cancel] { return cancel != nullptr && cancel->load(); }; + PresetsConfigSubstitutions substitutions; std::string errors_cummulative; bool first = true; - // Sorted, so any duplicate-preset warning below comes out in the same order on - // every run. - const std::set vendor_names = vendor_names_in(dir); - // Separate ORCA_FILAMENT_LIBRARY from other vendors. It must be loaded - // first because other vendors' filaments may inherit from it via the - // `base_bundle` lookup in parse_subfile. The remaining vendors are - // independent (no cross-vendor inheritance) and can be loaded in parallel. - std::string orca_lib_vendor; - std::vector other_vendors; - other_vendors.reserve(vendor_names.size()); - for (auto& vn : vendor_names) { - if (vn == ORCA_FILAMENT_LIBRARY) - orca_lib_vendor = vn; - else if (!(validation_mode && !vendor_to_validate.empty() && vn != vendor_to_validate)) - other_vendors.push_back(vn); + // Other vendors inherit from nothing but the library, and only installing them + // looks it up, so each is read while it loads and installed once both are done. + const VendorSource* orca_lib = nullptr; + std::vector other_vendors; + other_vendors.reserve(vendors.size()); + for (const VendorSource& vendor : vendors) { + if (vendor.name == ORCA_FILAMENT_LIBRARY) + orca_lib = &vendor; + else + other_vendors.push_back(&vendor); } - // Step 1: Load ORCA_FILAMENT_LIBRARY into `this` synchronously. - if (! orca_lib_vendor.empty()) { + // One of the other vendors, loaded into a PresetBundle of its own. + struct VendorLoad + { + const VendorSource* source { nullptr }; + std::unique_ptr bundle; + VendorRead read; + PresetsConfigSubstitutions substitutions; + std::string error; + // Counts the vendor's read and the library load; the second to finish installs it. + std::atomic ready { 0 }; + }; + std::vector loads(other_vendors.size()); + for (size_t i = 0; i < other_vendors.size(); ++i) + loads[i].source = other_vendors[i]; + + // Started slowest first, since the load ends when the slowest vendor does. + std::vector by_cost(loads.size()); + std::iota(by_cost.begin(), by_cost.end(), size_t(0)); + // A parse from JSON costs far more than any cache load, so parses go first, and + // within each group the bigger file, the cache or the .json that lists what + // to parse. A cache older than its profile is ordered as a parse. + const bool reads_caches = allow_cache && ! validation_mode; + std::vector> vendor_costs(loads.size()); + for (size_t i = 0; i < loads.size(); ++i) { + const VendorSource& vendor = *loads[i].source; + const boost::filesystem::path cache = vendor.dir / (vendor.name + ".opc"); + const boost::filesystem::path profile = vendor.dir / (vendor.name + ".json"); + boost::system::error_code ec, profile_ec; + const uintmax_t cache_size = reads_caches ? boost::filesystem::file_size(cache, ec) : 0; + if (reads_caches && ! ec) { + const std::time_t profile_time = boost::filesystem::last_write_time(profile, profile_ec); + if (profile_ec || profile_time <= boost::filesystem::last_write_time(cache, ec)) { + vendor_costs[i] = { false, cache_size }; + continue; + } + } + const uintmax_t profile_size = boost::filesystem::file_size(profile, profile_ec); + vendor_costs[i] = { true, profile_ec ? 0 : profile_size }; + } + std::stable_sort(by_cost.begin(), by_cost.end(), + [&](size_t a, size_t b) { return vendor_costs[a] > vendor_costs[b]; }); + + // A vendor that failed to read, or that is still to install when `cancel` is + // set, is left out. + auto install = [&](VendorLoad& load) { + if (load.bundle && ! canceled()) { + try { + load.substitutions = load.bundle->install_vendor_read(std::move(load.read), this).first; + } catch (const std::runtime_error &err) { + load.error = err.what(); + load.bundle.reset(); + } + } else + load.bundle.reset(); + load.read = VendorRead(); + }; + tbb::task_group group; + group.run([&] { + // An auto_partitioner splits the range only while a worker is asking for work, + // which at this size left every vendor on the calling thread. + tbb::parallel_for(tbb::blocked_range(0, loads.size(), 1), + [&](const tbb::blocked_range& range) { + for (size_t k = range.begin(); k < range.end(); ++k) { + VendorLoad& load = loads[by_cost[k]]; + if (! canceled()) { + try { + auto bundle = std::make_unique(); + bundle->set_is_validation_mode(validation_mode); + bundle->set_generate_vendor_caches(m_generate_vendor_caches); + load.read = bundle->read_vendor(load.source->dir.string(), load.source->name, + PresetBundle::LoadSystem, compatibility_rule, allow_cache); + load.bundle = std::move(bundle); + } catch (const std::runtime_error &err) { + load.error = err.what(); + } + } + if (++ load.ready == 2) + install(load); + } + }, tbb::simple_partitioner()); + }); + if (orca_lib != nullptr && ! canceled()) { try { // Match a fresh launch before parsing: hold aliases and the error // counter survive reset(), and would otherwise carry prior-cycle @@ -2535,66 +2674,55 @@ std::pair PresetBundle::load_system_pre this->clear_printer_hold_aliases(); this->m_errors = 0; append(substitutions, this->load_vendor_configs_from_json( - dir.string(), orca_lib_vendor, PresetBundle::LoadSystem, compatibility_rule, nullptr, allow_cache).first); + orca_lib->dir.string(), orca_lib->name, PresetBundle::LoadSystem, compatibility_rule, nullptr, allow_cache).first); first = false; } catch (const std::runtime_error &err) { if (validation_mode) throw err; errors_cummulative += err.what(); errors_cummulative += "\n"; + if (failed != nullptr) + failed->push_back(orca_lib->name); } } + for (size_t k : by_cost) + if (++ loads[k].ready == 2) + group.run([&install, &load = loads[k]] { install(load); }); + group.wait(); - // Step 2: Load remaining vendors in parallel. Each gets its own - // PresetBundle and uses `this` (which contains ORCA_FILAMENT_LIBRARY) - // as the base_bundle for cross-bundle inheritance lookups. - std::vector> parallel_bundles(other_vendors.size()); - std::vector parallel_substitutions(other_vendors.size()); - std::vector parallel_errors(other_vendors.size()); - - tbb::parallel_for(tbb::blocked_range(0, other_vendors.size()), - [&](const tbb::blocked_range& range) { - for (size_t i = range.begin(); i < range.end(); ++i) { - auto bundle = std::make_unique(); - bundle->set_is_validation_mode(validation_mode); - bundle->set_generate_vendor_caches(m_generate_vendor_caches); - try { - auto result = bundle->load_vendor_configs_from_json( - dir.string(), other_vendors[i], PresetBundle::LoadSystem, compatibility_rule, this, allow_cache); - parallel_substitutions[i] = std::move(result.first); - parallel_bundles[i] = std::move(bundle); - } catch (const std::runtime_error &err) { - parallel_errors[i] = err.what(); - } - } - }); - - // Step 3: Sequentially merge the parallel-loaded bundles into `this`. - // The merge order is the original vendor order so any duplicate-warning - // output stays stable across runs. - for (size_t i = 0; i < other_vendors.size(); ++i) { - if (!parallel_errors[i].empty()) { + // Merged in the original vendor order, so any duplicate-warning output stays + // stable across runs. + std::vector bundles; + for (VendorLoad& load : loads) + if (load.bundle) + bundles.push_back(load.bundle.get()); + const std::vector> duplicates = this->merge_presets(bundles); + size_t merged = 0; + for (VendorLoad& load : loads) { + if (! load.error.empty()) { if (validation_mode) - throw std::runtime_error(parallel_errors[i]); - errors_cummulative += parallel_errors[i]; + throw std::runtime_error(load.error); + errors_cummulative += load.error; errors_cummulative += "\n"; + if (failed != nullptr) + failed->push_back(load.source->name); continue; } - if (!parallel_bundles[i]) + if (! load.bundle) continue; - const std::string& vendor_name = other_vendors[i]; - append(substitutions, std::move(parallel_substitutions[i])); - std::vector duplicates = this->merge_presets(std::move(*parallel_bundles[i])); + const std::string& vendor_name = load.source->name; + const std::vector& vendor_duplicates = duplicates[merged ++]; + append(substitutions, std::move(load.substitutions)); first = false; - if (!duplicates.empty()) { + if (!vendor_duplicates.empty()) { errors_cummulative += "Found duplicated settings in vendor " + vendor_name + "'s json file lists: "; - for (size_t j = 0; j < duplicates.size(); ++j) { - if (j > 0) + for (size_t k = 0; k < vendor_duplicates.size(); ++k) { + if (k > 0) errors_cummulative += ", "; - errors_cummulative += duplicates[j]; + errors_cummulative += vendor_duplicates[k]; ++m_errors; - BOOST_LOG_TRIVIAL(error) << "Found duplicated preset: " + duplicates[j] + " in vendor: " + vendor_name + ": "; + BOOST_LOG_TRIVIAL(error) << "Found duplicated preset: " + vendor_duplicates[k] + " in vendor: " + vendor_name + ": "; } } } @@ -2604,14 +2732,9 @@ std::pair PresetBundle::load_system_pre this->reset(false); } - this->update_system_maps(); - const auto load_ms = std::chrono::duration_cast( std::chrono::steady_clock::now() - load_t0).count(); - BOOST_LOG_TRIVIAL(info) << "PresetBundle: " << vendor_names.size() << " vendor(s) loaded in " << load_ms << " ms"; - - //BBS: add config related logs - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" finished, errors_cummulative %1%")%errors_cummulative; + BOOST_LOG_TRIVIAL(info) << "PresetBundle: " << vendors.size() << " vendor(s) loaded in " << load_ms << " ms"; return std::make_pair(std::move(substitutions), errors_cummulative); } @@ -2680,7 +2803,7 @@ std::pair PresetBundle::load_system_fil // Report duplicate profiles. PresetBundle other; append(substitutions, other.load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem | PresetBundle::LoadFilamentOnly, compatibility_rule).first); - std::vector duplicates = this->merge_presets(std::move(other)); + std::vector duplicates = std::move(this->merge_presets({ &other }).front()); if (!duplicates.empty()) { errors_cummulative += "Found duplicated settings in vendor " + vendor_name + "'s json file lists: "; for (size_t i = 0; i < duplicates.size(); ++i) { @@ -2726,26 +2849,33 @@ VendorProfile PresetBundle::get_custom_vendor_models() const return vendor; } -// Merge one vendor's presets with the other vendor's presets, report duplicates. -std::vector PresetBundle::merge_presets(PresetBundle &&other) +std::vector> PresetBundle::merge_presets(const std::vector &others) { - this->vendors.insert(other.vendors.begin(), other.vendors.end()); - std::vector duplicate_prints = this->prints .merge_presets(std::move(other.prints), this->vendors); - std::vector duplicate_sla_prints = this->sla_prints .merge_presets(std::move(other.sla_prints), this->vendors); - std::vector duplicate_filaments = this->filaments .merge_presets(std::move(other.filaments), this->vendors); - std::vector duplicate_sla_materials = this->sla_materials.merge_presets(std::move(other.sla_materials), this->vendors); - std::vector duplicate_printers = this->printers .merge_presets(std::move(other.printers), this->vendors); - append(this->obsolete_presets.prints, std::move(other.obsolete_presets.prints)); - append(this->obsolete_presets.sla_prints, std::move(other.obsolete_presets.sla_prints)); - append(this->obsolete_presets.filaments, std::move(other.obsolete_presets.filaments)); - append(this->obsolete_presets.sla_materials, std::move(other.obsolete_presets.sla_materials)); - append(this->obsolete_presets.printers, std::move(other.obsolete_presets.printers)); - append(duplicate_prints, std::move(duplicate_sla_prints)); - append(duplicate_prints, std::move(duplicate_filaments)); - append(duplicate_prints, std::move(duplicate_sla_materials)); - append(duplicate_prints, std::move(duplicate_printers)); - m_errors += other.m_errors; - return duplicate_prints; + for (PresetBundle *other : others) + this->vendors.insert(other->vendors.begin(), other->vendors.end()); + std::vector> duplicates(others.size()); + auto merge = [&](auto collection) { + std::vector other_collections; + for (PresetBundle *other : others) + other_collections.push_back(&(other->*collection)); + std::vector> collection_duplicates = (this->*collection).merge_presets(other_collections, this->vendors); + for (size_t i = 0; i < others.size(); ++ i) + append(duplicates[i], std::move(collection_duplicates[i])); + }; + merge(&PresetBundle::prints); + merge(&PresetBundle::sla_prints); + merge(&PresetBundle::filaments); + merge(&PresetBundle::sla_materials); + merge(&PresetBundle::printers); + for (PresetBundle *other : others) { + append(this->obsolete_presets.prints, std::move(other->obsolete_presets.prints)); + append(this->obsolete_presets.sla_prints, std::move(other->obsolete_presets.sla_prints)); + append(this->obsolete_presets.filaments, std::move(other->obsolete_presets.filaments)); + append(this->obsolete_presets.sla_materials, std::move(other->obsolete_presets.sla_materials)); + append(this->obsolete_presets.printers, std::move(other->obsolete_presets.printers)); + m_errors += other->m_errors; + } + return duplicates; } void PresetBundle::update_system_maps() @@ -4354,8 +4484,17 @@ std::vector PresetBundle::get_filament_presets_for_machine(const std:: return compatible; } +int PresetBundle::get_filament_variant_index(const DynamicPrintConfig &filament_config, const DynamicPrintConfig &printer_config, + int extruder_id, NozzleVolumeType nozzle_volume_type) +{ + const auto *extruder_types = printer_config.option("extruder_type"); + const ExtruderType extruder_type = extruder_types && !extruder_types->empty() ? ExtruderType(extruder_types->get_at(extruder_id)) : etDirectDrive; + return std::max(0, filament_config.get_index_for_extruder(1, "", extruder_type, nozzle_volume_type, "filament_extruder_variant")); +} + bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray( - const std::string &printer_type, std::string& nozzle_diameter_str, std::string &setting_id, std::string &tag_uid, std::string &nozzle_temp_min, std::string &nozzle_temp_max, std::string& preset_setting_id) + const std::string &printer_type, std::string& nozzle_diameter_str, std::string &setting_id, std::string &tag_uid, std::string &nozzle_temp_min, std::string &nozzle_temp_max, std::string& preset_setting_id, + int extruder_id, NozzleVolumeType nozzle_volume_type) { bool is_equation = true; @@ -4378,13 +4517,15 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m // Compare only once if (!compared) { compared = true; + const Preset *printer = printers.find_preset(printer_str); + const int variant_index = printer ? get_filament_variant_index(preset->config, printer->config, extruder_id, nozzle_volume_type) : 0; bool min_temp_equation = false, max_temp_equation = false; int min_nozzle_temp = std::stoi(nozzle_temp_min); int max_nozzle_temp = std::stoi(nozzle_temp_max); ConfigOption *opt_min = const_cast(preset)->config.option("nozzle_temperature_range_low"); if (opt_min) { ConfigOptionInts *opt_min_ints = dynamic_cast(opt_min); - min_nozzle_temp = opt_min_ints->get_at(0); + min_nozzle_temp = opt_min_ints->get_at(variant_index); if (std::to_string(min_nozzle_temp) == nozzle_temp_min) min_temp_equation = true; else { @@ -4395,7 +4536,7 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m ConfigOption *opt_max = const_cast(preset)->config.option("nozzle_temperature_range_high"); if (opt_max) { ConfigOptionInts *opt_max_ints = dynamic_cast(opt_max); - max_nozzle_temp = opt_max_ints->get_at(0); + max_nozzle_temp = opt_max_ints->get_at(variant_index); if (std::to_string(max_nozzle_temp) == nozzle_temp_max) max_temp_equation = true; else { @@ -4605,6 +4746,15 @@ const std::set ignore_settings_list ={ "print_settings_id", "filament_settings_id", "printer_settings_id" }; +std::set PresetBundle::project_different_keys(const std::string &different_settings) +{ + std::vector keys; + Slic3r::unescape_strings_cstyle(different_settings, keys); + std::set keys_set(keys.begin(), keys.end()); + keys_set.insert(ignore_settings_list.begin(), ignore_settings_list.end()); + return keys_set; +} + DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optional> filament_maps_new, std::optional> filament_volume_maps_new) const { DynamicPrintConfig out; @@ -4695,7 +4845,8 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio if (num_filaments <= 1) { //BBS: update filament config related with variants DynamicPrintConfig filament_config = this->filaments.get_edited_preset().config; - if (apply_extruder && ((extruder_count > 1) || different_extruder)) + // Orca: a multi-variant filament resolves its variants on a single-variant printer too. + if (apply_extruder && ((extruder_count > 1) || different_extruder || filament_config.has_multi_variant_filament())) filament_config.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[0], (NozzleVolumeType)filament_volume_maps[0]); out.apply(filament_config); compatible_printers_condition.emplace_back(this->filaments.get_edited_preset().compatible_printers_condition()); @@ -4789,7 +4940,8 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio filament_temp_configs.resize(num_filaments); for (size_t i = 0; i < num_filaments; ++i) { filament_temp_configs[i] = *(filament_configs[i]); - if (apply_extruder && ((extruder_count > 1) || different_extruder)) + // Orca: a multi-variant filament resolves its variants on a single-variant printer too. + if (apply_extruder && ((extruder_count > 1) || different_extruder || filament_temp_configs[i].has_multi_variant_filament())) filament_temp_configs[i].update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[i], (NozzleVolumeType)filament_volume_maps[i]); } @@ -5310,15 +5462,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool if (!is_published) { //BBS: add different settings logic BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": load print preset from print_settings_id"); - std::vector print_different_keys_vector; - std::string print_different_settings = different_values[0]; - Slic3r::unescape_strings_cstyle(print_different_settings, print_different_keys_vector); - std::set print_different_keys_set(print_different_keys_vector.begin(), print_different_keys_vector.end()); - //if (!has_different_settings_to_system) { - // print_different_keys_set.clear(); - //} - //else - print_different_keys_set.insert(ignore_settings_list.begin(), ignore_settings_list.end()); + std::set print_different_keys_set = project_different_keys(different_values[0]); if (!print_compatible_printers.empty()) { ConfigOptionStrings* compatible_printers = config.option("compatible_printers", true); compatible_printers->values = print_compatible_printers; @@ -5329,15 +5473,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool //clear compatible printers clear_compatible_printers(config); - std::vector printer_different_keys_vector; - std::string printer_different_settings = different_values[num_filaments + 1]; - Slic3r::unescape_strings_cstyle(printer_different_settings, printer_different_keys_vector); - std::set printer_different_keys_set(printer_different_keys_vector.begin(), printer_different_keys_vector.end()); - //if (!has_different_settings_to_system) { - // printer_different_keys_set.clear(); - //} - //else - printer_different_keys_set.insert(ignore_settings_list.begin(), ignore_settings_list.end()); + std::set printer_different_keys_set = project_different_keys(different_values[num_filaments + 1]); //BBS: add config related logs BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": load printer preset from printer_settings_id"); load_preset(this->printers, num_filaments + 1, "printer_settings_id", printer_different_keys_set, std::string()); @@ -5356,15 +5492,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool Preset *loaded = nullptr; //BBS: add different settings logic - std::vector filament_different_keys_vector; - std::string filament_different_settings = different_values[1]; - Slic3r::unescape_strings_cstyle(filament_different_settings, filament_different_keys_vector); - std::set filament_different_keys_set(filament_different_keys_vector.begin(), filament_different_keys_vector.end()); - //if (!has_different_settings_to_system) { - // filament_different_keys_set.clear(); - //} - //else - filament_different_keys_set.insert(ignore_settings_list.begin(), ignore_settings_list.end()); + std::set filament_different_keys_set = project_different_keys(different_values[1]); std::string filament_id = filament_ids[0]; //BBS: add config related logs @@ -5427,15 +5555,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool cfg.opt_string("inherits", true) = inherits_values[i + 1]; //BBS: add different settings logic - std::vector filament_different_keys_vector; - std::string filament_different_settings = different_values[i+1]; - Slic3r::unescape_strings_cstyle(filament_different_settings, filament_different_keys_vector); - std::set filament_different_keys_set(filament_different_keys_vector.begin(), filament_different_keys_vector.end()); - //if (!has_different_settings_to_system) { - // filament_different_keys_set.clear(); - //} - //else - filament_different_keys_set.insert(ignore_settings_list.begin(), ignore_settings_list.end()); + std::set filament_different_keys_set = project_different_keys(different_values[i+1]); std::string filament_id = filament_ids[i]; @@ -6625,38 +6745,38 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": finished"); } -// Orca: load one source-form preset entry — parsed from its JSON subfile just -// now, or deserialized from the vendor's cache; the code is shared so a -// cache-loaded bundle cannot come out different from a JSON-loaded one. -// Resolves `inherits` against the presets loaded before this one -// (config_maps) or against base_bundle's filament library, layers each -// `include` (include_maps) under the preset's own keys, flattens, validates -// and registers the preset. Returns the reason loading failed, empty on -// success. -std::string PresetBundle::load_vendor_preset( - const CachedPreset& entry, - const std::string& path, const std::string& vendor_name, - const PresetBundle* base_bundle, - LoadConfigBundleAttributes flags, - ConfigSubstitutionContext& substitution_context, PresetsConfigSubstitutions& substitutions, - std::map& config_maps, std::map& include_maps, - std::map& filament_id_maps, - PresetCollection* presets_collection, size_t& count, bool is_from_lib, - const std::set* retain_configs, const std::set* retain_includes) +static ConfigurationError failed_loading_error(const std::string& file, const std::string& dir) { - const VendorProfile* current_vendor_profile = &this->vendors.at(vendor_name); - const std::string subfile = path + "/" + vendor_name + "/" + entry.sub_path; + return ConfigurationError((boost::format("Failed loading configuration file %1%\nSuggest cleaning the directory %2% firstly") % file % dir).str()); +} + +void PresetBundle::log_errors(const std::vector& errors) +{ + for (const std::string& error : errors) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << error; + } +} + +PresetBundle::PresetInstall PresetBundle::resolve_vendor_preset(const CachedPreset& entry, const VendorInstall& install) const +{ + const std::string& path = install.path; + const std::string& vendor_name = install.vendor_name; + const PresetBundle* base_bundle = install.base_bundle; + const PresetCollection& presets_collection = *install.presets; + const VendorProfile& current_vendor_profile = *install.vendor_profile; const std::string& preset_name = entry.name; - std::string alias_name, filament_id = entry.filament_id; - std::vector renamed_from = entry.renamed_from; - DynamicPrintConfig config; const DynamicPrintConfig* default_config = nullptr; - std::string reason; + const bool retain = install.is_from_lib || install.inherited.count(preset_name) != 0; + + PresetInstall out; + out.filament_id = entry.filament_id; + out.renamed_from = entry.renamed_from; //check whether it inherits other preset or not if (! entry.inherits.empty()) { - auto it2 = config_maps.find(entry.inherits); - if (it2 != config_maps.end()) + auto it2 = install.config_maps.find(entry.inherits); + if (it2 != install.config_maps.end()) default_config = &(it2->second); if (default_config == nullptr && base_bundle != nullptr) { auto base_it2 = base_bundle->m_config_maps.find(entry.inherits); @@ -6664,115 +6784,98 @@ std::string PresetBundle::load_vendor_preset( default_config = &(base_it2->second); } if (default_config != nullptr) { - if (filament_id.empty() && (presets_collection->type() == Preset::TYPE_FILAMENT)) { - auto filament_id_map_iter = filament_id_maps.find(entry.inherits); - if (filament_id_map_iter != filament_id_maps.end()) { - filament_id = filament_id_map_iter->second; + if (out.filament_id.empty() && (presets_collection.type() == Preset::TYPE_FILAMENT)) { + auto filament_id_map_iter = install.filament_id_maps.find(entry.inherits); + if (filament_id_map_iter != install.filament_id_maps.end()) { + out.filament_id = filament_id_map_iter->second; } - if (filament_id.empty() && base_bundle != nullptr) { + if (out.filament_id.empty() && base_bundle != nullptr) { auto base_filament_id_map_iter = base_bundle->m_filament_id_maps.find(entry.inherits); if (base_filament_id_map_iter != base_bundle->m_filament_id_maps.end()) { - filament_id = base_filament_id_map_iter->second; + out.filament_id = base_filament_id_map_iter->second; } } } } else { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not find inherits " << entry.inherits << " for " << preset_name; - // throw ConfigurationError(format("can not find inherits %1% for %2%", inherits, preset_name)); - reason = "Can not find inherits: " + entry.inherits; - return reason; + out.errors.push_back(std::string(__FUNCTION__) + ": can not find inherits " + entry.inherits + " for " + preset_name); + out.reason = "Can not find inherits: " + entry.inherits; + return out; } } else - default_config = &presets_collection->default_preset_for(entry.config_src).config; - config = *default_config; + default_config = &presets_collection.default_preset_for(entry.config_src).config; + out.config = *default_config; // Layer each included preset's own keys over the parent, in the order listed; // this preset's own keys go on top. for (const std::string& name : entry.includes) { - auto it = include_maps.find(name); - if (it == include_maps.end()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not find include " << name << " for " << preset_name; + auto it = install.include_maps.find(name); + if (it == install.include_maps.end()) { + out.errors.push_back(std::string(__FUNCTION__) + ": can not find include " + name + " for " + preset_name); continue; } - config.apply(it->second); + out.config.apply(it->second); } - config.apply(entry.config_src); + out.config.apply(entry.config_src); // Record what a base states, its diff against the default, for the presets // that include it. It is taken before extend_default_config_length pads every // per-variant key to the base's variant count: the padded defaults would // otherwise override the values each includer inherits. - if (entry.instantiation == "false" && (retain_includes == nullptr || retain_includes->count(preset_name) != 0)) { - DynamicPrintConfig included; - included.apply_only(config, config.diff(presets_collection->default_preset_for(config).config)); - include_maps.emplace(preset_name, std::move(included)); + if (entry.instantiation == "false" && install.included.count(preset_name) != 0) { + out.included.emplace(); + out.included->apply_only(out.config, out.config.diff(presets_collection.default_preset_for(out.config).config)); } - extend_default_config_length(config, true, *default_config); + extend_default_config_length(out.config, true, *default_config); + // Report configuration fields, which are misplaced into a wrong group, before + // Preset::normalize derives keys from them. An include diff holds only keys of the + // collection default, so only the entry's own keys can be missing from default_config. + std::string incorrect_keys = Preset::remove_invalid_keys(out.config, *default_config, &entry.config_src); + if (!incorrect_keys.empty()) + out.errors.push_back(std::string(__FUNCTION__) + ": The config " + path + "/" + vendor_name + "/" + entry.sub_path + + " contains incorrect keys: " + incorrect_keys + ", which were removed"); if (entry.instantiation == "false" && "Template" != vendor_name) { - // Report configuration fields, which are misplaced into a wrong group. - std::string incorrect_keys = Preset::remove_invalid_keys(config, *default_config); - if (!incorrect_keys.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": The config " << subfile << " contains incorrect keys: " << incorrect_keys - << ", which were removed"; - } - - if (retain_configs == nullptr || retain_configs->count(preset_name) != 0) - config_maps.emplace(preset_name, std::move(config)); - if ((presets_collection->type() == Preset::TYPE_FILAMENT) && (!filament_id.empty())) - filament_id_maps.emplace(preset_name, filament_id); - return reason; + out.config_only = true; + if (retain) + out.retained = std::move(out.config); + return out; } - if (config.has("alias")) - alias_name = (dynamic_cast(config.option("alias")))->value; - Preset::normalize(config); + if (out.config.has("alias")) + out.alias = (dynamic_cast(out.config.option("alias")))->value; - // Report configuration fields, which are misplaced into a wrong group. - std::string incorrect_keys = Preset::remove_invalid_keys(config, *default_config); - if (!incorrect_keys.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": The config " << subfile << " contains incorrect keys: " << incorrect_keys - << ", which were removed"; - } + Preset::normalize(out.config); - if (presets_collection->type() == Preset::TYPE_PRINTER) { + if (presets_collection.type() == Preset::TYPE_PRINTER) { // Filter out printer presets, which are not mentioned in the vendor profile. // These presets are considered not installed. - auto printer_model = config.opt_string("printer_model"); + auto printer_model = out.config.opt_string("printer_model"); if (printer_model.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << - preset_name << "\" defines no printer model, it will be ignored."; - reason = std::string("can not find printer_model"); - return reason; + out.errors.push_back("Error in a Vendor Config Bundle \"" + path + "\": The printer preset \"" + + preset_name + "\" defines no printer model, it will be ignored."); + out.reason = std::string("can not find printer_model"); + return out; } - auto printer_variant = config.opt_string("printer_variant"); + auto printer_variant = out.config.opt_string("printer_variant"); if (printer_variant.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << - preset_name << "\" defines no printer variant, it will be ignored."; - reason = std::string("can not find printer_variant"); - return reason; + out.errors.push_back("Error in a Vendor Config Bundle \"" + path + "\": The printer preset \"" + + preset_name + "\" defines no printer variant, it will be ignored."); + out.reason = std::string("can not find printer_variant"); + return out; } - auto it_model = std::find_if(current_vendor_profile->models.cbegin(), current_vendor_profile->models.cend(), + auto it_model = std::find_if(current_vendor_profile.models.cbegin(), current_vendor_profile.models.cend(), [&](const VendorProfile::PrinterModel &m) { return m.id == printer_model; } ); - if (it_model == current_vendor_profile->models.end()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << - preset_name << "\" defines invalid printer model \"" << printer_model << "\", it will be ignored."; - reason = std::string("can not find printer model in vendor profile"); - return reason; + if (it_model == current_vendor_profile.models.end()) { + out.errors.push_back("Error in a Vendor Config Bundle \"" + path + "\": The printer preset \"" + + preset_name + "\" defines invalid printer model \"" + printer_model + "\", it will be ignored."); + out.reason = std::string("can not find printer model in vendor profile"); + return out; } auto it_variant = it_model->variant(printer_variant); if (it_variant == nullptr) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << - preset_name << "\" defines invalid printer variant \"" << printer_variant << "\", it will be ignored."; - reason = std::string("can not find printer_variant in vendor profile"); - return reason; + out.errors.push_back("Error in a Vendor Config Bundle \"" + path + "\": The printer preset \"" + + preset_name + "\" defines invalid printer variant \"" + printer_variant + "\", it will be ignored."); + out.reason = std::string("can not find printer_variant in vendor profile"); + return out; } // An instantiation printer profile's nozzle_diameter must match the numeric (diameter) // prefix of its printer_variant: "0.4" -> {0.4}, "0.8HF" -> {0.8} (a trailing @@ -6783,7 +6886,7 @@ std::string PresetBundle::load_vendor_preset( // validated, not variant uniqueness. Validation-only so the app keeps loading existing // profiles unchanged. if (validation_mode && entry.instantiation == "true") { - const auto *nd = config.option("nozzle_diameter"); + const auto *nd = out.config.option("nozzle_diameter"); std::set nozzles, variant_nozzles; if (nd != nullptr) nozzles.insert(nd->values.begin(), nd->values.end()); @@ -6798,34 +6901,71 @@ std::string PresetBundle::load_vendor_preset( variant_nozzles.insert(d); } if (!variant_ok || variant_nozzles != nozzles) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << - preset_name << "\" has printer_variant \"" << printer_variant << - "\" that does not match its nozzle_diameter \"" << (nd ? nd->serialize() : std::string()) << "\". " + out.errors.push_back("Error in a Vendor Config Bundle \"" + path + "\": The printer preset \"" + + preset_name + "\" has printer_variant \"" + printer_variant + + "\" that does not match its nozzle_diameter \"" + (nd ? nd->serialize() : std::string()) + "\". " "printer_variant must begin with the nozzle diameter, optionally followed by a non-numeric suffix " "(e.g. \"0.4\", \"0.8HF\"); for multi-nozzle printers, join the per-nozzle diameters with \"+\" in " - "nozzle order (e.g. \"0.4+0.6\")."; + "nozzle order (e.g. \"0.4+0.6\")."); } } } - const Preset *preset_existing = presets_collection->find_preset(preset_name, false); - if (preset_existing != nullptr) { + + // Derive the profile logical name aka alias from the preset name if the alias was not stated explicitely. + if (out.alias.empty()) { + size_t end_pos = preset_name.find_first_of("@"); + if (end_pos != std::string::npos) { + out.alias = preset_name.substr(0, end_pos); + if (out.renamed_from.empty()) + // Add the preset name with the '@' character removed into the "renamed_from" list. + out.renamed_from.emplace_back(out.alias + preset_name.substr(end_pos + 1)); + boost::trim_right(out.alias); + } + } + + out.file_path = (boost::filesystem::path(data_dir()) / PRESET_SYSTEM_DIR / vendor_name / entry.sub_path).make_preferred().string(); + if (validation_mode) + out.file_path = (boost::filesystem::path(data_dir()) / vendor_name / entry.sub_path).make_preferred().string(); + if (m_preserve_vendor_source_paths) + out.file_path = (boost::filesystem::path(path) / vendor_name / entry.sub_path).make_preferred().string(); + if (retain) + out.retained = out.config; + return out; +} + +std::string PresetBundle::commit_vendor_preset(const CachedPreset& entry, PresetInstall&& resolved, + ConfigSubstitutions&& substitutions, VendorInstall& install) +{ + const std::string& path = install.path; + const std::string& vendor_name = install.vendor_name; + PresetCollection* presets_collection = install.presets; + const VendorProfile* current_vendor_profile = install.vendor_profile; + const std::string& preset_name = entry.name; + + log_errors(resolved.errors); + if (resolved.included) + install.include_maps.emplace(preset_name, std::move(*resolved.included)); + if (! resolved.reason.empty()) + return resolved.reason; + + if (resolved.config_only) { + if (resolved.retained) + install.config_maps.emplace(preset_name, std::move(*resolved.retained)); + if ((presets_collection->type() == Preset::TYPE_FILAMENT) && (!resolved.filament_id.empty())) + install.filament_id_maps.emplace(preset_name, resolved.filament_id); + return std::string(); + } + + if (! install.installed_names.insert(preset_name).second) { ++m_errors; BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << preset_name << "\" has already been loaded from another Config Bundle."; - reason = std::string("duplicated defines"); - return reason; + return std::string("duplicated defines"); } - auto file_path = (boost::filesystem::path(data_dir()) / PRESET_SYSTEM_DIR / vendor_name / entry.sub_path).make_preferred(); - if (validation_mode) - file_path = (boost::filesystem::path(data_dir()) / vendor_name / entry.sub_path).make_preferred(); - if (m_preserve_vendor_source_paths) - file_path = (boost::filesystem::path(path) / vendor_name / entry.sub_path).make_preferred(); - // Load the preset into the list of presets, save it to disk. - Preset &loaded = presets_collection->load_preset(file_path.string(), preset_name, std::move(config), false); - if (flags.has(LoadConfigBundleAttribute::LoadSystem)) { + Preset &loaded = presets_collection->append_preset(std::move(resolved.file_path), preset_name, std::move(resolved.config)); + if (install.flags.has(LoadConfigBundleAttribute::LoadSystem)) { loaded.is_system = true; loaded.vendor = current_vendor_profile; loaded.version = current_vendor_profile->config_version; @@ -6838,51 +6978,126 @@ std::string PresetBundle::load_vendor_preset( if (loaded.setting_id.empty() && entry.instantiation == "true") loaded.setting_id = generate_preset_setting_id( vendor_name, Preset::get_type_string(presets_collection->type()), preset_name); - loaded.filament_id = filament_id; - loaded.m_from_orca_filament_lib = is_from_lib; - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " " << __LINE__ << ", " << loaded.name << " load filament_id: " << filament_id; + loaded.filament_id = resolved.filament_id; + loaded.m_from_orca_filament_lib = install.is_from_lib; if (presets_collection->type() == Preset::TYPE_FILAMENT) { - if (filament_id.empty() && "Template" != vendor_name) { + if (resolved.filament_id.empty() && "Template" != vendor_name) { ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": can not find filament_id for " << preset_name; //throw ConfigurationError(format("can not find inherits %1% for %2%", inherits, preset_name)); - reason = "Can not find filament_id for " + preset_name; - return reason; + return "Can not find filament_id for " + preset_name; } else { - filament_id_maps.emplace(preset_name, filament_id); + install.filament_id_maps.emplace(preset_name, resolved.filament_id); } } } - // Derive the profile logical name aka alias from the preset name if the alias was not stated explicitely. - if (alias_name.empty()) { - size_t end_pos = preset_name.find_first_of("@"); - if (end_pos != std::string::npos) { - alias_name = preset_name.substr(0, end_pos); - if (renamed_from.empty()) - // Add the preset name with the '@' character removed into the "renamed_from" list. - renamed_from.emplace_back(alias_name + preset_name.substr(end_pos + 1)); - boost::trim_right(alias_name); - } - } - if (alias_name.empty()) + if (resolved.alias.empty()) loaded.alias = preset_name; else { - loaded.alias = std::move(alias_name); + loaded.alias = std::move(resolved.alias); filaments.set_printer_hold_alias(loaded.alias, loaded); } - loaded.renamed_from = std::move(renamed_from); - if (! substitution_context.empty()) - substitutions.push_back({ + loaded.renamed_from = std::move(resolved.renamed_from); + if (! substitutions.empty()) + install.substitutions->push_back({ preset_name, presets_collection->type(), PresetConfigSubstitutions::Source::ConfigBundle, - std::string(), std::move(substitution_context.substitutions) }); - if (retain_configs == nullptr || retain_configs->count(preset_name) != 0) - config_maps.emplace(preset_name, loaded.config); - ++count; + std::string(), std::move(substitutions) }); + if (resolved.retained) + install.config_maps.emplace(preset_name, std::move(*resolved.retained)); + ++install.count; //BBS: add config related logs - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", got preset %1%, from %2%")%loaded.name %subfile; - return reason; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ", got preset " << loaded.name << ", filament_id " << loaded.filament_id + << ", from " << path << "/" << vendor_name << "/" << entry.sub_path; + return std::string(); +} + +void PresetBundle::install_vendor_entries(VendorInstall& install, const std::vector& entries, + std::vector* parsed) +{ + assert(parsed == nullptr || parsed->size() == entries.size()); + for (const CachedPreset& entry : entries) { + if (! entry.inherits.empty()) + install.inherited.insert(entry.inherits); + install.included.insert(entry.includes.begin(), entry.includes.end()); + } + // The names an appended preset may not repeat, since the collection cannot be + // searched until it is sorted again. + for (const Preset& preset : install.presets->m_presets) + install.installed_names.insert(preset.name); + // Held until the collection is sorted again, also when an entry throws, so a reader + // holding the lock never finds it unsorted. + install.presets->lock(); + ScopeGuard sort_on_exit([&install] { + install.presets->sort_presets(); + install.presets->unlock(); + }); + + auto resolve = [&](size_t i) { return resolve_vendor_preset(entries[i], install); }; + auto commit = [&](size_t i, PresetInstall&& resolved) { + ConfigSubstitutions substitutions; + if (parsed != nullptr) { + log_errors((*parsed)[i].errors); + for (const std::string& warning : (*parsed)[i].warnings) + BOOST_LOG_TRIVIAL(error) << warning; + substitutions = std::move((*parsed)[i].substitutions); + } + const std::string reason = commit_vendor_preset(entries[i], std::move(resolved), std::move(substitutions), install); + if (! reason.empty()) { + ++m_errors; + const std::string subfile_path = install.path + "/" + install.vendor_name + "/" + entries[i].sub_path; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not install " << entries[i].name << " from " << subfile_path << ": " << reason; + throw failed_loading_error(subfile_path, install.path); + } + }; + // A run of entries resolves together and commits in listing order, and ends + // before an entry that inherits or includes one already in it. So no entry + // resolves against a registration from its own run, and the result matches + // installing one at a time. + std::unordered_set run_names; + size_t run_begin = 0; + auto install_run = [&](size_t run_end) { + resolve_then_commit(run_end - run_begin, + [&](size_t k) { return resolve(run_begin + k); }, + [&](size_t k, PresetInstall&& resolved) { commit(run_begin + k, std::move(resolved)); }); + run_names.clear(); + run_begin = run_end; + }; + auto in_run = [&](const std::string& name) { return run_names.count(name) != 0; }; + for (size_t i = 0; i < entries.size(); ++ i) { + const CachedPreset& entry = entries[i]; + if (in_run(entry.inherits) || std::any_of(entry.includes.begin(), entry.includes.end(), in_run)) + install_run(i); + if (install.inherited.count(entry.name) != 0 || install.included.count(entry.name) != 0) + run_names.insert(entry.name); + } + install_run(entries.size()); +} + +size_t PresetBundle::install_vendor(const std::string& path, const std::string& vendor_name, const PresetBundle* base_bundle, + LoadConfigBundleAttributes flags, const VendorCacheData& entries, + VendorParse* parsed, bool complete, PresetsConfigSubstitutions& substitutions) +{ + const bool is_orca_lib = vendor_name == ORCA_FILAMENT_LIBRARY; + const VendorProfile* vendor_profile = &this->vendors.at(vendor_name); + size_t count = 0; + auto install_collection = [&](const std::vector& list, std::vector* list_parsed, + PresetCollection* presets, bool is_from_lib) { + VendorInstall install { path, vendor_name, vendor_profile, base_bundle, flags, presets, is_from_lib, &substitutions }; + install_vendor_entries(install, list, list_parsed); + count += install.count; + return install; + }; + install_collection(entries.process_entries, parsed ? &parsed->process_entries : nullptr, &this->prints, false); + VendorInstall filaments = install_collection(entries.filament_entries, parsed ? &parsed->filament_entries : nullptr, + &this->filaments, is_orca_lib); + if (is_orca_lib && complete) { + m_config_maps = std::move(filaments.config_maps); + m_filament_id_maps = std::move(filaments.filament_id_maps); + } + install_collection(entries.machine_entries, parsed ? &parsed->machine_entries : nullptr, &this->printers, false); + return count; } //BBS: Load a config bundle file from json @@ -6890,12 +7105,14 @@ std::pair PresetBundle::load_vendor_configs_ const std::string &dir, const std::string &vendor_name, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule, const PresetBundle* base_bundle, bool allow_cache) { - // Enable substitutions for user config bundle, throw an exception when loading a system profile. - ConfigSubstitutionContext substitution_context { compatibility_rule }; - PresetsConfigSubstitutions substitutions; - // Errors already on this bundle when the load began; the cache stamp below - // counts only what this parse adds. - const int errors_at_entry = m_errors; + return this->install_vendor_read(this->read_vendor(dir, vendor_name, flags, compatibility_rule, allow_cache), base_bundle); +} + +PresetBundle::VendorRead PresetBundle::read_vendor(const std::string& dir, const std::string& vendor_name, + LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule, bool allow_cache) +{ + VendorRead read { dir, vendor_name, flags, compatibility_rule }; + read.errors_at_entry = m_errors; //BBS: add config related logs BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" enter, path %1%, compatibility_rule %2%")%dir.c_str()%compatibility_rule; @@ -6905,16 +7122,34 @@ std::pair PresetBundle::load_vendor_configs_ // Orca: only a whole-vendor load has a cache — the vendor-only and filament-only // scans want a slice of one. Validation reads the JSONs whatever is cached. - const boost::filesystem::path dir_path(dir); - const bool cacheable = allow_cache && flags.has(LoadConfigBundleAttribute::LoadSystem) && ! flags.has(LoadConfigBundleAttribute::LoadFilamentOnly); - if (cacheable && ! validation_mode && this->load_vendor_cache(dir_path, vendor_name, base_bundle)) { - size_t presets_loaded = 0; - for (const PresetCollection* coll : std::initializer_list{ - &this->prints, &this->sla_prints, &this->filaments, &this->sla_materials, &this->printers }) - presets_loaded += coll->m_presets.size() - coll->m_num_default_presets; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", %1% served from its preset cache, %2% presets")%vendor_name%presets_loaded; - return std::make_pair(std::move(substitutions), presets_loaded); + read.cacheable = allow_cache && flags.has(LoadConfigBundleAttribute::LoadSystem) && ! flags.has(LoadConfigBundleAttribute::LoadFilamentOnly); + if (read.cacheable && ! validation_mode) { + // A vendor is loaded from where it is installed and nowhere else; resources + // reaches the app by being installed into `dir` first. The cache there is + // judged against the profile beside it — or, where the cache is the whole + // of the installation, against nothing, since nothing on disk can then be + // newer than it. That state is Semver::inf(), which no real profile carries. + const boost::filesystem::path dir_path(dir); + const boost::filesystem::path profile = dir_path / (vendor_name + ".json"); + const Semver version = boost::filesystem::exists(profile) ? get_version_from_json(profile.string()) : Semver::inf(); + read.cache_path = (dir_path / (vendor_name + ".opc")).string(); + read.from_cache = VendorCacheFile::load(read.cache_path, vendor_name, version, read.data); + if (read.from_cache) + return read; } + this->parse_vendor_json(read); + return read; +} + +void PresetBundle::parse_vendor_json(VendorRead& read) +{ + // Starts over from what read_vendor was asked for, since a cache that could + // not be installed leaves its own state behind. + read = VendorRead { std::move(read.dir), std::move(read.vendor_name), read.flags, read.compatibility_rule, + read.errors_at_entry, read.cacheable }; + const std::string& dir = read.dir; + const std::string& vendor_name = read.vendor_name; + LoadConfigBundleAttributes flags = read.flags; // 1) load the vroot json and construct the vendor profile VendorProfile vendor_profile(vendor_name); @@ -7135,21 +7370,21 @@ std::pair PresetBundle::load_vendor_configs_ BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", loaded vendor profile, name %1%, id %2%, version %3%")%vendor_profile.name%vendor_profile.id%vendor_profile.config_version.to_string(); - if (flags.has(LoadConfigBundleAttribute::LoadVendorOnly)) - return std::make_pair(PresetsConfigSubstitutions{}, 0); + if (flags.has(LoadConfigBundleAttribute::LoadVendorOnly)) { + read.vendor_only = true; + return; + } // 3) paste the process/filament/print configs - PresetCollection *presets = nullptr; - size_t presets_loaded = 0; // Parse one subfile into a source-form entry — everything the JSON states, - // nothing resolved. Loading the entry (load_vendor_preset) is the - // same code whether the entry was parsed just now or deserialized from the + // nothing resolved. Installing the entries (install_vendor) is the + // same code whether they were parsed just now or deserialized from the // vendor's cache. - auto parse_subfile = [this, dir, vendor_name]( + auto parse_subfile = [&dir, &vendor_name]( ConfigSubstitutionContext& substitution_context, const std::pair& subfile_iter, - CachedPreset& entry) -> std::string { + CachedPreset& entry, std::vector& errors, std::vector& warnings) -> std::string { std::string subfile = dir + "/" + vendor_name + "/" + subfile_iter.second; std::string reason; @@ -7161,8 +7396,7 @@ std::pair PresetBundle::load_vendor_configs_ entry.sub_path = subfile_iter.second; entry.config_src.load_from_json(subfile, substitution_context, false, key_values, reason); if (!reason.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": load config file "< PresetBundle::load_vendor_configs_ entry.name = subfile_iter.first; } if(key_values.find(BBL_JSON_KEY_INSTANTIATION) == key_values.end()) - { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Missing instantiation attribute for " << entry.name; - ++m_errors; - } + errors.push_back(std::string(__FUNCTION__) + ": Missing instantiation attribute for " + entry.name); entry.instantiation = key_values[BBL_JSON_KEY_INSTANTIATION]; - if(entry.instantiation != "false" && entry.instantiation != "true"){ - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Missing instantiation attribute for " << entry.name; - ++m_errors; - } + if(entry.instantiation != "false" && entry.instantiation != "true") + errors.push_back(std::string(__FUNCTION__) + ": Missing instantiation attribute for " + entry.name); auto setting_it = key_values.find(BBL_JSON_KEY_SETTING_ID); if (setting_it != key_values.end()) entry.setting_id = setting_it->second; @@ -7198,8 +7427,7 @@ std::pair PresetBundle::load_vendor_configs_ // An `inherits` key naming nothing can never resolve; fail it // here so install can key off the empty string as "no inherits". if (entry.inherits.empty()) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": can not find inherits " << entry.inherits << " for " << entry.name; + errors.push_back(std::string(__FUNCTION__) + ": can not find inherits " + entry.inherits + " for " + entry.name); reason = "Can not find inherits: " + entry.inherits; return reason; } @@ -7212,96 +7440,108 @@ std::pair PresetBundle::load_vendor_configs_ for (const auto& name : includes) { if (name.is_string()) entry.includes.push_back(name.get()); - else { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": invalid include " << name.dump() << " for " << entry.name; - } + else + errors.push_back(std::string(__FUNCTION__) + ": invalid include " + name.dump() + " for " + entry.name); } } if (key_values.find(ORCA_JSON_KEY_RENAMED_FROM) != key_values.end()) { - if (!unescape_strings_cstyle(key_values[ORCA_JSON_KEY_RENAMED_FROM], entry.renamed_from)) { - BOOST_LOG_TRIVIAL(error) << "Error in a Config \"" << dir << "\": The preset \"" << entry.name - << "\" contains invalid \"renamed_from\" key, which is being ignored."; - } + if (!unescape_strings_cstyle(key_values[ORCA_JSON_KEY_RENAMED_FROM], entry.renamed_from)) + warnings.push_back("Error in a Config \"" + dir + "\": The preset \"" + entry.name + + "\" contains invalid \"renamed_from\" key, which is being ignored."); } } catch(nlohmann::detail::parse_error &err) { - ++m_errors; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<< subfile <<" got a nlohmann::detail::parse_error, reason = " << err.what(); + errors.push_back(std::string(__FUNCTION__) + ": parse " + subfile + " got a nlohmann::detail::parse_error, reason = " + err.what()); reason = std::string("json parse error") + err.what(); return reason; } return reason; }; - std::map configs, include_maps; - std::map filament_id_maps; // Orca: whether to (re)write the vendor's cache after this parse, leaving it // in step with the profile so the next run reads it instead. It is written // where the vendor was looked for, even when the profile came from resources, // and stamped with the version that profile claims — a profile without one // cannot be judged for staleness later, and a cache nothing can invalidate is // worse than none. - const bool will_cache = cacheable && m_generate_vendor_caches && vendor_profile.config_version.valid(); - VendorCacheData cache_data; + read.will_cache = read.cacheable && m_generate_vendor_caches && vendor_profile.config_version.valid(); + read.version = vendor_profile.config_version.to_string(); + // Enable substitutions for user config bundle, throw an exception when loading a system profile. + ConfigSubstitutionContext substitution_context { read.compatibility_rule }; + // Parsed up to the first sub-file that fails, and the ones before it are + // installed before that failure is raised, since the filament library and a + // filament-only scan keep what a throwing load installed. + auto parse_subfiles = [&](const std::vector>& subfiles, + std::vector& entries, std::vector& entries_parsed, const char* kind) { + for (const auto& subfile : subfiles) { + CachedPreset entry; + std::vector errors, warnings; + read.reason = parse_subfile(substitution_context, subfile, entry, errors, warnings); + if (! read.reason.empty()) { + read.failed_subfile = subfile.second; + read.failed_kind = kind; + read.failed_errors = std::move(errors); + return false; + } + entries.emplace_back(std::move(entry)); + entries_parsed.push_back({ std::move(substitution_context.substitutions), std::move(errors), std::move(warnings) }); + } + return true; + }; + // One setter for every sub-file, so the ones load_from_json makes have + // nothing to set. + CNumericLocalesSetter locales_setter; + if (parse_subfiles(process_subfiles, read.data.process_entries, read.parsed.process_entries, "process") && + parse_subfiles(filament_subfiles, read.data.filament_entries, read.parsed.filament_entries, "filament")) + parse_subfiles(machine_subfiles, read.data.machine_entries, read.parsed.machine_entries, "printer"); +} + +std::pair PresetBundle::install_vendor_read(VendorRead&& read, const PresetBundle* base_bundle) +{ + const std::string& dir = read.dir; + const std::string& vendor_name = read.vendor_name; + PresetsConfigSubstitutions substitutions; + if (read.from_cache) { + if (this->install_vendor_cache(read.cache_path, vendor_name, std::move(read.data), base_bundle)) { + size_t presets_loaded = 0; + for (const PresetCollection* coll : std::initializer_list{ + &this->prints, &this->sla_prints, &this->filaments, &this->sla_materials, &this->printers }) + presets_loaded += coll->m_presets.size() - coll->m_num_default_presets; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", %1% served from its preset cache, %2% presets")%vendor_name%presets_loaded; + return std::make_pair(std::move(substitutions), presets_loaded); + } + this->parse_vendor_json(read); + } + if (read.vendor_only) + return std::make_pair(PresetsConfigSubstitutions{}, 0); + + int parse_errors = 0; + for (const std::vector* list : { &read.parsed.process_entries, &read.parsed.filament_entries, &read.parsed.machine_entries }) + for (const EntryParse& entry_parsed : *list) + parse_errors += int(entry_parsed.errors.size()); + const int errors_before_install = m_errors; + const size_t presets_loaded = install_vendor(dir, vendor_name, base_bundle, read.flags, read.data, &read.parsed, + read.reason.empty(), substitutions); // Errors added by install are counted apart: a cache load runs install again, // so the parse_errors stamped into the cache must hold only what a cache load // will not recount. - int install_errors = 0; - auto load_subfiles = [&](std::vector>& subfiles, - std::vector& entries, const char* kind, bool is_from_lib = false) { - configs.clear(); - include_maps.clear(); - filament_id_maps.clear(); - for (auto& subfile : subfiles) { - CachedPreset entry; - std::string reason = parse_subfile(substitution_context, subfile, entry); - if (reason.empty()) { - const int errors_before_install = m_errors; - reason = load_vendor_preset(entry, dir, vendor_name, base_bundle, flags, - substitution_context, substitutions, configs, include_maps, filament_id_maps, - presets, presets_loaded, is_from_lib); - install_errors += m_errors - errors_before_install; - } - if (!reason.empty()) { - ++m_errors; - //parse error - std::string subfile_path = dir + "/" + vendor_name + "/" + subfile.second; - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", got error when parse %1% setting from %2%") % kind % subfile_path; - throw ConfigurationError((boost::format("Failed loading configuration file %1%\nSuggest cleaning the directory %2% firstly") % subfile_path % dir).str()); - } - if (will_cache) - entries.emplace_back(std::move(entry)); - } - }; - - // The section order below — process, filaments (with the ORCA-lib map copy), - // printers — is mirrored by load_vendor_cache's install loops; keep the two - // in lockstep. - //3.1) paste the process - presets = &this->prints; - load_subfiles(process_subfiles, cache_data.process_entries, "process"); - - //3.2) paste the filaments - presets = &this->filaments; - const auto is_orca_lib = vendor_name == ORCA_FILAMENT_LIBRARY; - load_subfiles(filament_subfiles, cache_data.filament_entries, "filament", is_orca_lib); - if (is_orca_lib) { - m_config_maps = configs; - m_filament_id_maps = filament_id_maps; + const int install_errors = m_errors - errors_before_install - parse_errors; + if (! read.reason.empty()) { + log_errors(read.failed_errors); + ++m_errors; + //parse error + std::string subfile_path = dir + "/" + vendor_name + "/" + read.failed_subfile; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", got error when parse %1% setting from %2%") % read.failed_kind % subfile_path; + throw failed_loading_error(subfile_path, dir); } - //3.3) paste the printers - presets = &this->printers; - load_subfiles(machine_subfiles, cache_data.machine_entries, "printer"); - - if (will_cache) { + if (read.will_cache) { // Clamped: the count is a difference of three tallies, and a stamp that // wrapped would be added to every future load of this vendor. - cache_data.parse_errors = uint64_t(std::max(0, m_errors - errors_at_entry - install_errors)); - cache_data.vendors = this->vendors; - if (! VendorCacheFile::save((dir_path / (vendor_name + ".opc")).string(), vendor_name, - vendor_profile.config_version.to_string(), cache_data)) + read.data.parse_errors = uint64_t(std::max(0, m_errors - read.errors_at_entry - install_errors)); + read.data.vendors = this->vendors; + if (! VendorCacheFile::save((boost::filesystem::path(dir) / (vendor_name + ".opc")).string(), vendor_name, + read.version, read.data)) BOOST_LOG_TRIVIAL(warning) << "PresetBundle: failed to save vendor cache for " << vendor_name; } @@ -8016,82 +8256,42 @@ bool BundleMetadata::save_to_json(const std::string& path) const // ---- Per-vendor preset cache: install into this bundle ------------------- // The file format itself lives in PresetCacheFormat.cpp (VendorCacheFile). -bool PresetBundle::load_vendor_cache(const boost::filesystem::path& dir, const std::string& vendor_name, const PresetBundle* base_bundle) -{ - // A vendor is loaded from where it is installed and nowhere else; resources - // reaches the app by being installed into `dir` first. The cache there is - // judged against the profile beside it — or, where the cache is the whole - // of the installation, against nothing, since nothing on disk can then be - // newer than it. That state is Semver::inf(), which no real profile carries. - const boost::filesystem::path profile = dir / (vendor_name + ".json"); - const Semver version = boost::filesystem::exists(profile) ? get_version_from_json(profile.string()) - : Semver::inf(); - return this->load_vendor_cache((dir / (vendor_name + ".opc")).string(), vendor_name, version, base_bundle); -} - bool PresetBundle::load_vendor_cache(const std::string& cache_path, const std::string& expected_vendor_name, const Semver& expected_vendor_version, const PresetBundle* base_bundle) { - // What this bundle had counted before the cache was tried. The caller - // measures its own parse against this same baseline, so a rejection must - // put it back rather than reset it to zero. - const int errors_at_entry = this->m_errors; // Read and validated before this bundle is touched: a rejected file leaves // no state to roll back. VendorCacheData data; if (! VendorCacheFile::load(cache_path, expected_vendor_name, expected_vendor_version, data)) return false; + // VendorCacheFile::load checked the names match. + return this->install_vendor_cache(cache_path, expected_vendor_name, std::move(data), base_bundle); +} + +bool PresetBundle::install_vendor_cache(const std::string& cache_path, const std::string& vendor_name, VendorCacheData&& data, + const PresetBundle* base_bundle) +{ + // What this bundle had counted before the cache was tried. The caller + // measures its own parse against this same baseline, so a rejection must + // put it back rather than reset it to zero. + const int errors_at_entry = this->m_errors; try { - const std::string& vendor_name = expected_vendor_name; // VendorCacheFile::load checked they match this->vendors = std::move(data.vendors); // What the parse counted before install took over; install recounts its // own below, so m_errors comes out as a JSON parse would leave it. m_errors += int(data.parse_errors); - // Install the entries exactly as load_vendor_configs_from_json installs - // them straight after parsing — same code, same order. The substitution - // context stays empty (the entries were substituted when they were - // parsed), so no substitutions are reported, as before. - ConfigSubstitutionContext substitution_context { ForwardCompatibilitySubstitutionRule::EnableSilent }; + // Stays empty, since the entries were substituted when they were parsed. PresetsConfigSubstitutions substitutions; - std::map configs, include_maps; - std::map filament_id_maps; - const std::string path = boost::filesystem::path(cache_path).parent_path().string(); - size_t count = 0; - auto install_entries = [&](const std::vector& entries, PresetCollection* presets, bool is_from_lib) { - configs.clear(); - include_maps.clear(); - filament_id_maps.clear(); - // Only configs of presets that other entries inherit or include are - // ever looked up again; registering just those skips one full config - // copy for every leaf preset. The library's filaments are all retained - // — they become the m_config_maps other vendors resolve against. - std::set inherited, included; - for (const CachedPreset& entry : entries) { - if (! entry.inherits.empty()) - inherited.insert(entry.inherits); - included.insert(entry.includes.begin(), entry.includes.end()); - } - const std::set* retain_configs = is_from_lib ? nullptr : &inherited; - for (const CachedPreset& entry : entries) { - const std::string reason = load_vendor_preset(entry, path, vendor_name, - base_bundle, LoadConfigBundleAttribute::LoadSystem, substitution_context, substitutions, - configs, include_maps, filament_id_maps, presets, count, is_from_lib, retain_configs, &included); - if (! reason.empty()) - throw std::runtime_error("entry " + entry.name + " failed to install: " + reason); - } - }; - install_entries(data.process_entries, &this->prints, false); - const bool is_orca_lib = vendor_name == ORCA_FILAMENT_LIBRARY; - install_entries(data.filament_entries, &this->filaments, is_orca_lib); - if (is_orca_lib) { - m_config_maps = configs; - m_filament_id_maps = filament_id_maps; - } - install_entries(data.machine_entries, &this->printers, false); + install_vendor(boost::filesystem::path(cache_path).parent_path().string(), vendor_name, base_bundle, + LoadConfigBundleAttribute::LoadSystem, data, nullptr, true, substitutions); return true; } catch (const std::exception& e) { + // A cancellation of the caller's task group stops the install without + // anything being wrong with the cache. + if (tbb::is_current_task_group_canceling()) + throw; BOOST_LOG_TRIVIAL(warning) << "PresetBundle: rejecting vendor cache " << cache_path << ": " << e.what(); // Restore a clean state so the caller can fall back to the JSON parse. this->reset(false); diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 1c5160a19b..fb5cd37598 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -234,6 +235,9 @@ public: // ORCA: utility function to find the vendor for a given preset name static std::string find_preset_vendor(const std::string& preset_name, Preset::Type type); + // Keys a project keeps when its presets are loaded: those listed in its escaped + // "different_settings_to_system" entry for the preset, plus the preset bookkeeping keys. + static std::set project_different_keys(const std::string &different_settings); PresetBundle(); PresetBundle(const PresetBundle &rhs); @@ -273,6 +277,10 @@ public: const std::string &source_file, ForwardCompatibilitySubstitutionRule compatibility_rule, std::string &error, bool allow_source_manifest = true); + // Resolve a system preset by name. The vendor tree is read from data_dir()/system when installed + // there, as the GUI reads it, and from the bundled profiles otherwise. + bool resolve_system_preset(DynamicPrintConfig &config, Preset::Type type, const std::string &name, + ForwardCompatibilitySubstitutionRule compatibility_rule, std::string &error); // Load selections (current print, current filaments, current printer) from config.ini // This is done just once on application start up. @@ -402,13 +410,22 @@ public: std::vector get_filament_presets_for_machine(const std::string &printer_type, const std::string &nozzle_diameter_str, bool include_user_presets); + // Orca: the variant index of a filament preset's per-variant options on extruder extruder_id of a printer + // preset, with the nozzle volume type the machine reports; 0 when the filament has no such variant. + static int get_filament_variant_index(const DynamicPrintConfig &filament_config, + const DynamicPrintConfig &printer_config, + int extruder_id, + NozzleVolumeType nozzle_volume_type); + // extruder_id and nozzle_volume_type identify the tray's nozzle, whose variant the temperature range is compared for. bool check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray(const std::string &printer_type, std::string & nozzle_diameter_str, std::string & setting_id, std::string & tag_uid, std::string & nozzle_temp_min, std::string & nozzle_temp_max, - std::string & preset_setting_id); + std::string & preset_setting_id, + int extruder_id, + NozzleVolumeType nozzle_volume_type); Preset * get_similar_printer_preset(std::string printer_model, std::string printer_variant); PresetCollection prints; @@ -625,36 +642,180 @@ public: // default_filament_profile must resolve to a system filament. bool check_printer_default_materials() const; - // Merge one vendor's presets with the other vendor's presets, report duplicates. - // Public so per-vendor-cache consumers (e.g. the setup wizard) can assemble a - // bundle out of several per-vendor caches loaded into separate PresetBundle instances. - std::vector merge_presets(PresetBundle &&other); + // One vendor to load, and the directory it is installed in. + struct VendorSource + { + std::string name; + boost::filesystem::path dir; + }; + + // Load `vendors` into this bundle, the Orca filament library directly and every + // other vendor in parallel into a bundle of its own that inherits from it, merged + // in the order given. A vendor that cannot be loaded has its error added to the + // returned text, or thrown in validation mode, and its name to `failed`; it is + // left out, except for the library, which keeps what it installed before the + // failure. Once `cancel` is set, no further vendor starts loading. + std::pair load_vendors(const std::vector& vendors, + ForwardCompatibilitySubstitutionRule compatibility_rule, bool allow_cache, + const std::atomic* cancel = nullptr, std::vector* failed = nullptr); private: - // Load one vendor from the preset cache installed in `dir`, judged against - // the vendor profile there. False, with this bundle left clean, when there - // is no usable cache and the vendor has to be parsed. This is how - // load_vendor_configs_from_json reads a cache. - bool load_vendor_cache(const boost::filesystem::path& dir, const std::string& vendor_name, const PresetBundle* base_bundle); + // Move the presets and vendor profiles of `others` into this bundle, in one pass + // over each collection. A preset whose name this bundle or an earlier one of + // `others` already has is left out and listed under the bundle that repeats it. + std::vector> merge_presets(const std::vector &others); - // Load one source-form preset entry into this bundle: resolve `inherits` - // and `include`, flatten, validate and register the preset. Returns the - // reason loading failed, empty on success. See the definition for the - // sharing contract between the JSON parse and the cache load. - // retain_configs / retain_includes, when non-null, name the only presets - // registered into config_maps / include_maps (a config copy each). The - // cache load passes the names its entries inherit / include — the only - // ones ever looked up again; the JSON parse retains all, not knowing what - // later subfiles name. - std::string load_vendor_preset(const CachedPreset& entry, - const std::string& path, const std::string& vendor_name, - const PresetBundle* base_bundle, - LoadConfigBundleAttributes flags, - ConfigSubstitutionContext& substitution_context, PresetsConfigSubstitutions& substitutions, - std::map& config_maps, std::map& include_maps, - std::map& filament_id_maps, - PresetCollection* presets_collection, size_t& count, bool is_from_lib, - const std::set* retain_configs = nullptr, const std::set* retain_includes = nullptr); + // What parsing one entry's JSON sub-file reported. Its errors and warnings are + // logged when the entry installs, so they come out in listing order with the + // entry's install errors, as parsing and installing one entry at a time leaves them. + struct EntryParse + { + ConfigSubstitutions substitutions; + // Counted in the bundle's error count. + std::vector errors; + std::vector warnings; + }; + + // An EntryParse for each entry of the VendorCacheData list of the same name. + struct VendorParse + { + std::vector process_entries; + std::vector filament_entries; + std::vector machine_entries; + }; + + // One vendor read from its cache or its JSONs by read_vendor, for + // install_vendor_read to install. + struct VendorRead + { + std::string dir; + std::string vendor_name; + LoadConfigBundleAttributes flags; + ForwardCompatibilitySubstitutionRule compatibility_rule; + // The errors this bundle had counted before the read, which the cache stamp leaves out. + int errors_at_entry { 0 }; + // A whole-vendor load, which can read a cache and write one. + bool cacheable { false }; + // Read from the cache at cache_path, which install can still reject. + bool from_cache { false }; + std::string cache_path; + // Only the vendor profile was asked for. + bool vendor_only { false }; + VendorCacheData data; + // What each entry's JSON parse reported, and whether and with which version + // the cache is written once the entries install. + VendorParse parsed; + bool will_cache { false }; + std::string version; + // The sub-file the parse stopped at, its kind, why, and the errors it reported. + std::string reason; + std::string failed_subfile; + const char* failed_kind { nullptr }; + std::vector failed_errors; + }; + + // Read a vendor into this bundle's vendor profiles and `data`, from its cache + // when one covers it, else from its JSONs; nothing is installed. Throws + // ConfigurationError when the vendor's own JSON cannot be parsed. + VendorRead read_vendor(const std::string& dir, const std::string& vendor_name, LoadConfigBundleAttributes flags, + ForwardCompatibilitySubstitutionRule compatibility_rule, bool allow_cache); + + // Parse the vendor's JSONs into `read`, up to the first sub-file that fails. + void parse_vendor_json(VendorRead& read); + + // Install what read_vendor read, against base_bundle's filament library. A cache + // that cannot be installed is replaced by a parse of the JSONs. Throws + // ConfigurationError at the first entry that cannot be installed, or after + // installing the entries before a sub-file that could not be parsed. + std::pair install_vendor_read(VendorRead&& read, const PresetBundle* base_bundle); + + // Install a cache's entries. False, with this bundle left clean, when one of them + // cannot be installed. + bool install_vendor_cache(const std::string& cache_path, const std::string& vendor_name, VendorCacheData&& data, + const PresetBundle* base_bundle); + + // Log and count errors reported by a resolve or a parse. + void log_errors(const std::vector& errors); + + // The state of installing one collection of one vendor, which + // resolve_vendor_preset reads through a const reference and only + // commit_vendor_preset writes. + struct VendorInstall + { + // The directory holding /, whose sub-paths the entries name. + std::string path; + std::string vendor_name; + const VendorProfile* vendor_profile; + const PresetBundle* base_bundle; + LoadConfigBundleAttributes flags; + PresetCollection* presets; + // The Orca filament library, which keeps every config for other vendors to + // resolve against. + bool is_from_lib; + PresetsConfigSubstitutions* substitutions; + // The names some entry inherits / includes, the only ones whose configs / + // include diffs are looked up again. + std::set inherited; + std::set included; + std::map config_maps; + std::map include_maps; + std::map filament_id_maps; + std::unordered_set installed_names; + size_t count { 0 }; + }; + + // Install a vendor's source-form entries, parsed from its JSON or read from its + // cache: processes, then filaments, then printers. Both loads go through here, + // so a cache-loaded bundle cannot come out different from a JSON-loaded one. + // `parsed` is given for entries parsed just now. `complete` says the entries + // are the vendor's whole lists; only then are the filament library's configs + // and filament ids left in m_config_maps and m_filament_id_maps. Returns the + // number of presets installed, and throws ConfigurationError at the first + // entry that cannot be installed. + size_t install_vendor(const std::string& path, const std::string& vendor_name, const PresetBundle* base_bundle, + LoadConfigBundleAttributes flags, const VendorCacheData& entries, + VendorParse* parsed, bool complete, PresetsConfigSubstitutions& substitutions); + + // Install one collection's entries in the order they are listed. + void install_vendor_entries(VendorInstall& install, const std::vector& entries, + std::vector* parsed); + + // One entry flattened against the preset it inherits, before anything this + // bundle shares has been touched. + struct PresetInstall + { + DynamicPrintConfig config; + std::string file_path; + // Empty when the preset is its own alias. + std::string alias; + std::string filament_id; + std::vector renamed_from; + // Reported by commit, so resolving entries together leaves the log and + // the error count as one entry at a time produces them. + std::vector errors; + // What a base states for the presets that include it, when it is retained. + std::optional included; + // The config kept for the entries that inherit this one, or for other + // vendors when this is the filament library. + std::optional retained; + // Not instantiated, so it contributes a config and no preset. + bool config_only { false }; + // Non-empty when the entry is rejected, and says why. + std::string reason; + }; + + // Flatten one entry against the config it inherits, from this collection's + // config_maps or base_bundle's filament library, with the include diffs it + // names layered in. It looks up nothing but the names the entry inherits and + // includes, and writes nothing. + PresetInstall resolve_vendor_preset(const CachedPreset& entry, const VendorInstall& install) const; + + // Install a resolved entry. The collections, the maps in `install` and the + // error count are touched here and only here, one entry at a time. + // Presets are appended, so a repeated name is caught with `installed_names`, + // and the collection is sorted once every entry is in. + std::string commit_vendor_preset(const CachedPreset& entry, PresetInstall&& resolved, + ConfigSubstitutions&& substitutions, VendorInstall& install); // Clear every collection's m_printer_hold_alias, which reset() leaves alone. void clear_printer_hold_aliases(); @@ -666,13 +827,14 @@ private: // Vendor trees loaded by resolve_preset_config's manifest path, so every preset // resolved through this bundle shares one load per source root and vendor. The // filament library is one such tree, shared by every vendor under its root. - std::map, std::unique_ptr> + // A tree read from its preset cache is kept apart: its presets carry no source file. + std::map, std::unique_ptr> m_source_vendor_bundles; const PresetBundle *load_source_vendor(const boost::filesystem::path &root_dir, const std::string &vendor_id, ForwardCompatibilitySubstitutionRule compatibility_rule, - std::string &error); + std::string &error, bool allow_cache = false); // Orca: validation only - flag any printer with two or more compatible // filament presets sharing one filament_id (ambiguous AMS subtype match). diff --git a/src/libslic3r/PresetCacheFormat.hpp b/src/libslic3r/PresetCacheFormat.hpp index 2c90c07882..52c40bea21 100644 --- a/src/libslic3r/PresetCacheFormat.hpp +++ b/src/libslic3r/PresetCacheFormat.hpp @@ -109,7 +109,7 @@ void skip_config(cereal::BinaryInputArchive& ar, const CacheDictionary& dict); // One preset as its JSON subfile states it: the config diff, the names of the // preset it inherits and the presets it includes, and the parse metadata — -// everything the parse phase of load_vendor_configs_from_json extracts and +// everything PresetBundle::parse_vendor_json extracts and // nothing it derives. Inheritance and includes are resolved when the entry is // installed, against whatever filament library is loaded then, so a cache // carries no other vendor's values and no other vendor's update can make it diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ed3ac6de88..5f5592cfce 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2439,12 +2439,18 @@ StringObjectException Print::validate(std::vector *warnin if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter) warn(L("The precise wall option will be ignored for outer-inner or inner-outer-inner wall sequences."), "precise_outer_wall"); - // check adaptive pressure advance model - for (unsigned int extruder_id : extruders) { - if (m_config.adaptive_pressure_advance.get_at(extruder_id) && - m_config.enable_pressure_advance.get_at(extruder_id)) { - - const std::string pa_model = m_config.adaptive_pressure_advance_model.get_at(extruder_id); + // check adaptive pressure advance model of every extruder variant column of the used filaments + const std::vector &self_index = m_config.filament_self_index.values; + const size_t pa_columns = std::max(m_config.adaptive_pressure_advance_model.size(), size_t(extruders.back()) + 1); + for (size_t column = 0; column < pa_columns; ++column) { + // filament_self_index maps a column to its filament once the filament arrays hold one column per variant + const unsigned int filament_id = self_index.size() == pa_columns ? self_index[column] - 1 : column; + if (!std::binary_search(extruders.begin(), extruders.end(), filament_id)) + continue; + if (m_config.adaptive_pressure_advance.get_at(column) && + m_config.enable_pressure_advance.get_at(column)) { + + const std::string pa_model = m_config.adaptive_pressure_advance_model.get_at(column); if (!pa_model.empty()) { std::string validation_error = AdaptivePAProcessor::validate_adaptive_pa_model(pa_model); if (!validation_error.empty()) { @@ -3938,6 +3944,9 @@ void Print::update_filament_maps_to_config(std::vector f_maps, std::vector< { int extruder_count = 1, extruder_volume_type_count = 1; bool support_multi = m_ori_full_print_config.support_different_extruders(extruder_count); + // Orca: resolve the filament variants wherever Print::apply does, a multi-variant filament + // on a single-variant printer included. + const bool expand_filaments = (extruder_count > 1) || support_multi || m_ori_full_print_config.has_multi_variant_filament(); std::vector> nozzle_volume_types; extruder_volume_type_count = m_ori_full_print_config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); @@ -3978,7 +3987,7 @@ void Print::update_filament_maps_to_config(std::vector f_maps, std::vector< m_full_print_config = m_ori_full_print_config; std::set filament_keys = filament_options_with_variant; filament_keys.insert("filament_self_index"); - if ((extruder_count > 1) || support_multi) + if (expand_filaments) m_full_print_config.update_values_to_printer_extruders_for_multiple_filaments(m_full_print_config, extruder_count, extruder_volume_type_count, filament_keys, "filament_self_index", "filament_extruder_variant"); const std::vector &extruder_retract_keys = print_config_def.extruder_retract_keys(); @@ -3995,7 +4004,7 @@ void Print::update_filament_maps_to_config(std::vector f_maps, std::vector< compute_filament_override_value(opt_key, opt_old_machine, opt_new_machine, opt_new_filament, m_full_print_config, print_diff, filament_overrides, m_config.filament_map_2.values); } - if ((extruder_count > 1) || support_multi) { + if (expand_filaments) { t_config_option_keys keys(filament_options_with_variant.begin(), filament_options_with_variant.end()); keys.push_back("filament_self_index"); m_config.apply_only(m_full_print_config, keys, true); @@ -4320,9 +4329,9 @@ bool Print::is_dynamic_group_reorder() const return true; } -int Print::get_filament_config_indx(int filament_id, int layer_id) +int Print::get_filament_config_indx(int filament_id, int layer_id, bool use_cache) { - return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, m_filament_index_map); + return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, use_cache ? &m_filament_index_map : nullptr); } void Print::update_filament_self_index_cache() @@ -4365,7 +4374,7 @@ int Print::get_nozzle_config_index(int filament_id, int layer_id) return get_config_index(filament_id, layer_id, m_default_region_config.print_extruder_variant.values, m_default_region_config.print_extruder_id.values, m_nozzle_index_map); } -int Print::get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, FilamentIndexMap &index_map) +int Print::get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, FilamentIndexMap *index_map) { auto group_result = get_layered_nozzle_group_result(); // Orca: defensive — when no grouping producer has published a result yet, fall back to the @@ -4376,7 +4385,8 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vectorextruder_id)); NozzleVolumeType nozzle_volume_type = nozzle_info->volume_type; + if (!index_map) + return get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list); FilamentIndexKey key{filament_id, extruder_type, nozzle_volume_type}; - auto iter = index_map.find(key); - if (iter == index_map.end()) { + auto iter = index_map->find(key); + if (iter == index_map->end()) { int index = get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list); - index_map[key] = index; + (*index_map)[key] = index; return index; } else { - return index_map[key]; + return iter->second; } } @@ -5049,6 +5061,7 @@ DynamicConfig PrintStatistics::config() const config.set_key_value("total_wipe_tower_filament", new ConfigOptionFloat(this->total_wipe_tower_filament)); config.set_key_value("initial_tool", new ConfigOptionInt(static_cast(this->initial_tool))); config.set_key_value("initial_extruder", new ConfigOptionInt(static_cast(this->initial_tool))); + config.set_key_value("initial_no_support_extruder", new ConfigOptionInt(static_cast(this->initial_no_support_tool))); return config; } @@ -5058,7 +5071,7 @@ DynamicConfig PrintStatistics::placeholders() for (const std::string key : { "print_time", "normal_print_time", "silent_print_time", "used_filament", "extruded_volume", "extruded_volume_total", "total_cost", "total_weight", "extruded_weight_total", - "initial_tool", "initial_extruder", "total_toolchanges", "total_wipe_tower_cost", "total_wipe_tower_filament"}) + "initial_tool", "initial_extruder", "initial_no_support_extruder", "total_toolchanges", "total_wipe_tower_cost", "total_wipe_tower_filament"}) config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); return config; } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 12be35ea3c..f185962b1e 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -470,6 +470,10 @@ public: std::vector slice_support_volumes(const ModelVolumeType model_volume_type) const; std::vector slice_support_blockers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_BLOCKER); } std::vector slice_support_enforcers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_ENFORCER); } + // Shared slicing path; multiple volumes are united per layer. + std::vector slice_modifier_volumes(const std::vector &volumes) const; + // Keep Precise Seam volumes separate so their individual priority is preserved. + std::vector slice_single_volume(const ModelVolume* volume) const { return this->slice_modifier_volumes({volume}); } // Helpers to project custom facets on slices void project_and_append_custom_facets(bool seam, EnforcerBlockerType type, std::vector& expolys, std::vector>* vertical_points=nullptr) const; @@ -830,6 +834,7 @@ struct PrintStatistics double total_wipe_tower_cost; double total_wipe_tower_filament; unsigned int initial_tool; + unsigned int initial_no_support_tool; std::map filament_stats; // Config with the filled in print statistics. @@ -848,6 +853,7 @@ struct PrintStatistics total_wipe_tower_cost = 0.; total_wipe_tower_filament = 0.; initial_tool = 0; + initial_no_support_tool = 0; filament_stats.clear(); } static const std::string FilamentUsedG; @@ -1216,7 +1222,9 @@ public: // Post-slicing config-slot resolvers: map a (filament, layer) pair to the index of its // per-(extruder x volume type) column in the expanded variant arrays, cached by grouping context. - int get_filament_config_indx(int filament_id, int layer_id); + // Orca: without use_cache, the filament resolver leaves the cache alone, for the G-code export + // pipeline's cooling stage, which runs concurrently with the generator stage filling it. + int get_filament_config_indx(int filament_id, int layer_id, bool use_cache = true); int get_nozzle_config_index(int filament_id, int layer_id); // Orca: Implement prusa's filament shrink compensation approach @@ -1276,7 +1284,7 @@ protected: }; using FilamentIndexMap = std::unordered_map; using PrintIndexMap = std::unordered_map; - int get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, FilamentIndexMap &index_map); + int get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, FilamentIndexMap *index_map); int get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, PrintIndexMap &index_map); // Invalidates the step, and its depending steps in Print. diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 90d60b5917..21e2251b65 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -8,12 +8,12 @@ namespace Slic3r { -// Add or remove support modifier ModelVolumes from model_object_dst to match the ModelVolumes of model_object_new +// Add or remove support and Precise Seam modifier ModelVolumes from model_object_dst to match the ModelVolumes of model_object_new // in the exact order and with the same IDs. -// It is expected, that the model_object_dst already contains the non-support volumes of model_object_new in the correct order. +// Other volume types must already match model_object_new in the correct order. // Friend to ModelVolume to allow copying. // static is not accepted by gcc if declared as a friend of ModelObject. -/* static */ void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_new) +/* static */ void model_volume_list_update_supports_and_seams(ModelObject &model_object_dst, const ModelObject &model_object_new) { typedef std::pair ModelVolumeWithStatus; std::vector old_volumes; @@ -33,18 +33,22 @@ namespace Slic3r { assert(! it->second); // not consumed yet it->second = true; ModelVolume *model_volume_dst = const_cast(it->first); - // For support modifiers, the type may have been switched from blocker to enforcer and vice versa. - assert((model_volume_dst->is_support_modifier() && model_volume_src->is_support_modifier()) || model_volume_dst->type() == model_volume_src->type()); + // Type may switch within support family, within precise_seam family, or between them. + assert((model_volume_dst->is_support_modifier() && model_volume_src->is_support_modifier()) || + (model_volume_dst->is_precise_seam() && model_volume_src->is_precise_seam()) || + (model_volume_dst->is_support_modifier() && model_volume_src->is_precise_seam()) || + (model_volume_dst->is_precise_seam() && model_volume_src->is_support_modifier()) || + model_volume_dst->type() == model_volume_src->type()); model_object_dst.volumes.emplace_back(model_volume_dst); - if (model_volume_dst->is_support_modifier()) { - // For support modifiers, the type may have been switched from blocker to enforcer and vice versa. + if (model_volume_dst->is_support_modifier() || model_volume_dst->is_precise_seam()) { + // Type may have been switched within or between support/precise_seam families. model_volume_dst->set_type(model_volume_src->type()); model_volume_dst->set_transformation(model_volume_src->get_transformation()); } assert(model_volume_dst->get_matrix().isApprox(model_volume_src->get_matrix())); } else { // The volume was not found in the old list. Create a new copy. - assert(model_volume_src->is_support_modifier()); + assert(model_volume_src->is_support_modifier() || model_volume_src->is_precise_seam()); model_object_dst.volumes.emplace_back(new ModelVolume(*model_volume_src)); model_object_dst.volumes.back()->set_model_object(&model_object_dst); } @@ -55,17 +59,20 @@ namespace Slic3r { delete mv_with_status.first; } -static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, const ModelObject &model_object_src, const ModelVolumeType type) +// Copy configs of ModelVolumes matching type_filter predicate from src to dst. +// Mirrors the template pattern of model_volume_list_changed() in Model.cpp. +template +static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, const ModelObject &model_object_src, TypeFilterFn type_filter) { size_t i_src, i_dst; for (i_src = 0, i_dst = 0; i_src < model_object_src.volumes.size() && i_dst < model_object_dst.volumes.size();) { const ModelVolume &mv_src = *model_object_src.volumes[i_src]; ModelVolume &mv_dst = *model_object_dst.volumes[i_dst]; - if (mv_src.type() != type) { + if (! type_filter(mv_src.type())) { ++ i_src; continue; } - if (mv_dst.type() != type) { + if (! type_filter(mv_dst.type())) { ++ i_dst; continue; } @@ -88,6 +95,20 @@ static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, } } +// Convenience overload: single volume type. +static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, const ModelObject &model_object_src, const ModelVolumeType type) +{ + model_volume_list_copy_configs(model_object_dst, model_object_src, [type](const ModelVolumeType t) { return t == type; }); +} + +// Convenience overload: multiple volume types at once (e.g. all precise seam types). +static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, const ModelObject &model_object_src, const std::initializer_list &types) +{ + model_volume_list_copy_configs(model_object_dst, model_object_src, [&types](const ModelVolumeType t) { + return std::find(types.begin(), types.end(), t) != types.end(); + }); +} + static inline void layer_height_ranges_copy_configs(t_layer_config_ranges &lr_dst, const t_layer_config_ranges &lr_src) { assert(lr_dst.size() == lr_src.size()); @@ -1296,7 +1317,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ extruder_count, extruder_volume_type_count, filament_keys, "filament_self_index", "filament_extruder_variant", &dynamic_slot_indices); - else if ((extruder_count > 1) || different_extruder) + // Orca: also on a printer with a single extruder variant once a filament defines several + // (e.g. Standard and High Flow), so each filament takes its variant for that extruder. + else if ((extruder_count > 1) || different_extruder || new_full_config.has_multi_variant_filament()) new_full_config.update_values_to_printer_extruders_for_multiple_filaments(m_ori_full_print_config, extruder_count, extruder_volume_type_count, filament_keys, "filament_self_index", "filament_extruder_variant"); } @@ -1618,6 +1641,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // 3) Synchronize ModelObjects & PrintObjects. const std::initializer_list solid_or_modifier_types { ModelVolumeType::MODEL_PART, ModelVolumeType::NEGATIVE_VOLUME, ModelVolumeType::PARAMETER_MODIFIER }; + const std::initializer_list precise_seam_types { + ModelVolumeType::PRECISE_SEAM_CENTER, ModelVolumeType::PRECISE_SEAM_LEFT, + ModelVolumeType::PRECISE_SEAM_RIGHT, ModelVolumeType::PRECISE_SEAM_ENFORCED, + ModelVolumeType::PRECISE_SEAM_BLOCKED, ModelVolumeType::PRECISE_SEAM_NEUTRAL + }; for (size_t idx_model_object = 0; idx_model_object < model.objects.size(); ++ idx_model_object) { ModelObject &model_object = *m_model.objects[idx_model_object]; ModelObjectStatus &model_object_status = const_cast(model_object_status_db.reuse(model_object)); @@ -1635,6 +1663,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ model_fuzzy_skin_data_changed(model_object, model_object_new); bool supports_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_BLOCKER) || model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_ENFORCER); + bool precise_seam_differ = model_volume_list_changed(model_object, model_object_new, precise_seam_types); bool layer_height_ranges_differ = ! layer_height_ranges_equal(model_object.layer_config_ranges, model_object_new.layer_config_ranges, model_object_new.layer_height_profile.empty()); bool model_origin_translation_differ = model_object.origin_translation != model_object_new.origin_translation; bool brim_points_differ = model_brim_points_data_changed(model_object, model_object_new); @@ -1677,13 +1706,20 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // Invalidate just the supports step. for (const PrintObjectStatus &print_object_status : print_objects_range) update_apply_status(print_object_status.print_object->invalidate_step(posSupportMaterial)); - if (supports_differ) { - // Copy just the support volumes. - model_volume_list_update_supports(model_object, model_object_new); - } + } + if (precise_seam_differ) { + // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list. + this->call_cancel_callback(); + update_apply_status(false); + // Invalidate seam placement (affects G-code export). + update_apply_status(this->invalidate_step(psGCodeExport)); } else if (model_custom_seam_data_changed(model_object, model_object_new)) { update_apply_status(this->invalidate_step(psGCodeExport)); } + // Synchronize both families once, after cancellation and all affected-step invalidations. + // This also handles type changes between supports and Precise Seam before copying configs below. + if (supports_differ || precise_seam_differ) + model_volume_list_update_supports_and_seams(model_object, model_object_new); if (brim_points_differ) { model_object.brim_points = model_object_new.brim_points; update_apply_status(this->invalidate_all_steps()); @@ -1708,6 +1744,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ //FIXME What to do with m_material_id? model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, ModelVolumeType::MODEL_PART); model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, ModelVolumeType::PARAMETER_MODIFIER); + // Synchronize Precise Seam modifier volumes + model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, precise_seam_types); layer_height_ranges_copy_configs(model_object.layer_config_ranges /* dst */, model_object_new.layer_config_ranges /* src */); // Copy the ModelObject name, input_file and instances. The instances will be compared against PrintObject instances in the next step. model_object.name = model_object_new.name; diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index d4f99c764e..f1b158e51f 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -62,7 +62,8 @@ public: SlicingReplaceInitEmptyLayers, SlicingNeedSupportOn, SlicingEmptyGcodeLayers, - SlicingGcodeOverlap + SlicingGcodeOverlap, + SlicingPreciseSeamWarning }; typedef size_t TimeStamp; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1d994d7874..d4d0c90272 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -626,7 +626,9 @@ static const t_config_enum_values s_keys_map_NozzleVolumeType = { { "Standard", nvtStandard }, { "High Flow", nvtHighFlow }, { "TPU High Flow", nvtTPUHighFlow }, - { "Hybrid", nvtHybrid } + { "Hybrid", nvtHybrid }, + { "E3D High Flow", nvtE3DHighFlow }, + { "Extra High Flow", nvtExtraHighFlow } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NozzleVolumeType) @@ -676,9 +678,34 @@ int get_config_index_base(NozzleVolumeType volume_type, ExtruderType extruder_ty for (int index = 0; index < int(variant_list.size()); ++index) { if (extruder_variant == variant_list[index] && variant_ids_1based[index] == variant_id_1based) { return index; } } + // Without this variant, use the id's own first variant (usually Standard), not variant index 0, + // which belongs to the first filament or extruder. + for (int index = 0; index < int(variant_list.size()); ++index) { + if (variant_ids_1based[index] == variant_id_1based) { return index; } + } return 0; } +std::set get_extruder_supported_nozzle_volume_types(const DynamicPrintConfig &printer_config, int extruder_id) +{ + std::set supported_types; + + auto *variant_list = printer_config.option("extruder_variant_list"); + auto *extruder_types = printer_config.option("extruder_type"); + if (!variant_list || !extruder_types || extruder_id < 0 || + extruder_id >= (int) variant_list->values.size() || extruder_id >= (int) extruder_types->values.size()) + return supported_types; + + const ExtruderType extruder_type = ExtruderType(extruder_types->values[extruder_id]); + for (NozzleVolumeType volume_type : get_valid_nozzle_volume_type()) { + // An unsupported extruder type yields an empty name, which would match any list. + const std::string variant = get_extruder_variant_string(extruder_type, volume_type); + if (!variant.empty() && variant_list->values[extruder_id].find(variant) != std::string::npos) + supported_types.insert(volume_type); + } + return supported_types; +} + std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type) { if (nozzle_volume_type > nvtMaxNozzleVolumeType) { @@ -5923,15 +5950,20 @@ void PrintConfigDef::init_fff_params() def->label = "Nozzle Volume Type"; def->tooltip = "Nozzle volume type for extruders."; def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); - // Order must match the NozzleVolumeType enum values (Standard=0, High Flow=1, Hybrid=2, TPU High Flow=3). + // Listed in display order. A position is not the enum value (E3D High Flow is 5, after the reserved 4), + // so map a position to its NozzleVolumeType through enum_keys_map. def->enum_values.push_back(L("Standard")); def->enum_values.push_back(L("High Flow")); def->enum_values.push_back(L("Hybrid")); def->enum_values.push_back(L("TPU High Flow")); + def->enum_values.push_back(L("E3D High Flow")); + def->enum_values.push_back(L("Extra High Flow")); def->enum_labels.push_back(L("Standard")); def->enum_labels.push_back(L("High Flow")); def->enum_labels.push_back(L("Hybrid")); def->enum_labels.push_back(L("TPU High Flow")); + def->enum_labels.push_back(L("E3D High Flow")); + def->enum_labels.push_back(L("Extra High Flow")); def->mode = comSimple; def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard }); @@ -5944,10 +5976,14 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back(L("High Flow")); def->enum_values.push_back(L("Hybrid")); def->enum_values.push_back(L("TPU High Flow")); + def->enum_values.push_back(L("E3D High Flow")); + def->enum_values.push_back(L("Extra High Flow")); def->enum_labels.push_back(L("Standard")); def->enum_labels.push_back(L("High Flow")); def->enum_labels.push_back(L("Hybrid")); def->enum_labels.push_back(L("TPU High Flow")); + def->enum_labels.push_back(L("E3D High Flow")); + def->enum_labels.push_back(L("Extra High Flow")); def->mode = comDevelop; def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard }); @@ -5986,7 +6022,7 @@ void PrintConfigDef::init_fff_params() // Per-nozzle volume type. Forward-compat-only registration with no slicing consumer — nothing in // src/ reads it; the engine resolves per-nozzle volume types from `extruder_nozzle_stats` tokens // instead. Kept registered so a project/config carrying it loads without an unknown-option - // substitution warning. Registers Standard/High Flow/TPU High Flow only (no Hybrid). + // substitution warning. Registers the physical types only (no Hybrid). // Internal use only, no translation. def = this->add("extruder_nozzle_volume_type", coEnums); def->label = "Extruder nozzle volume type"; @@ -5995,9 +6031,13 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("Standard"); def->enum_values.push_back("High Flow"); def->enum_values.push_back("TPU High Flow"); + def->enum_values.push_back("E3D High Flow"); + def->enum_values.push_back("Extra High Flow"); def->enum_labels.push_back("Standard"); def->enum_labels.push_back("High Flow"); def->enum_labels.push_back("TPU High Flow"); + def->enum_labels.push_back("E3D High Flow"); + def->enum_labels.push_back("Extra High Flow"); def->mode = comDevelop; def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard }); @@ -9363,6 +9403,10 @@ void PrintConfigDef::handle_legacy_composite(DynamicPrintConfig &config) } config.set_key_value("wiping_volumes_use_custom_matrix", new ConfigOptionBool(custom)); } + + // Orca: a config saved before a key joined filament_options_with_variant stores it once per filament + // rather than once per filament variant, and one exported by an older CLI may store a single value. + normalize_filament_values_to_variants(config); } const PrintConfigDef print_config_def; @@ -9465,6 +9509,23 @@ std::set filament_options_with_variant = { "filament_ironing_spacing", "filament_ironing_inset", "filament_ironing_speed", + // Orca: pressure advance + "enable_pressure_advance", + "pressure_advance", + "adaptive_pressure_advance", + "adaptive_pressure_advance_model", + "adaptive_pressure_advance_overhangs", + "adaptive_pressure_advance_bridges", + // Orca: cooling fans, multi-tool ramming and recommended nozzle temperature range + "fan_min_speed", + "fan_max_speed", + "additional_cooling_fan_speed", + "filament_minimal_purge_on_wipe_tower", + "filament_multitool_ramming", + "filament_multitool_ramming_volume", + "filament_multitool_ramming_flow", + "nozzle_temperature_range_low", + "nozzle_temperature_range_high", "activate_air_filtration", "activate_air_filtration_during_print", "activate_air_filtration_on_completion", @@ -10070,6 +10131,13 @@ bool DynamicPrintConfig::is_using_different_extruders() return ret; } +bool DynamicPrintConfig::has_multi_variant_filament() const +{ + auto variants = dynamic_cast(this->option("filament_extruder_variant")); + auto diameters = dynamic_cast(this->option("filament_diameter")); + return variants && diameters && variants->size() > diameters->size(); +} + bool DynamicPrintConfig::support_different_extruders(int& extruder_count) const { std::set variant_set; @@ -10665,6 +10733,25 @@ void set_variant_override(ConfigOptionVectorBase &target, const ConfigOptionVect target.set_to_index(&source, indices, stride); } +void normalize_filament_values_to_variants(DynamicPrintConfig &config) +{ + const auto *self_index = config.option("filament_self_index"); + if (self_index == nullptr || self_index->empty()) + return; + const int filament_count = *std::max_element(self_index->values.begin(), self_index->values.end()); + if (filament_count <= 0 || size_t(filament_count) >= self_index->size()) + return; + for (const std::string &key : filament_options_with_variant) { + auto *opt = dynamic_cast(config.option(key)); + if (opt == nullptr || (opt->size() != size_t(filament_count) && opt->size() != 1)) + continue; + std::unique_ptr per_filament(opt->clone()); + // set_at() takes the first value for a filament past the end of a single-value vector + for (size_t variant = 0; variant < self_index->size(); ++variant) + opt->set_at(per_filament.get(), variant, self_index->values[variant] - 1); + } +} + //used for object/region config //use the smallest of multiple to single @@ -11070,6 +11157,11 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen return; } std::vector filament_maps = opt_filament_map->values; + auto opt_ids = id_name.empty()? nullptr: dynamic_cast(this->option(id_name)); + // Orca: a map shorter than the filament count must not drop the filaments past its end; + // they take the first extruder. + if (opt_ids && !opt_ids->values.empty()) + filament_maps.resize(std::max(filament_maps.size(), *std::max_element(opt_ids->values.begin(), opt_ids->values.end())), 1); size_t filament_count = filament_maps.size(); //apply process settings auto opt_extruder_type = dynamic_cast(printer_config.option("extruder_type")); @@ -11088,7 +11180,6 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen // indexed out of bounds. if (opt_filament_volume_maps && opt_filament_volume_maps->values.size() == filament_count) filament_volume_maps = opt_filament_volume_maps->values; - auto opt_ids = id_name.empty()? nullptr: dynamic_cast(this->option(id_name)); std::vector variant_index; variant_index.resize(filament_count, -1); @@ -11105,9 +11196,10 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen //variant index variant_index[f_index] = get_index_for_extruder(f_index+1, id_name, extruder_type, nozzle_volume_type, variant_name); if (variant_index[f_index] < 0) { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, filament_index %4%, extruder index %5%") + // Orca: a filament need not define every extruder variant (a Direct Drive filament on a + // Bowden printer), so this is not an invalid state: the filament's first variant is used. + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, filament_index %4%, extruder index %5%") %__LINE__ %s_keys_names_ExtruderType[extruder_type] % s_keys_names_NozzleVolumeType[nozzle_volume_type] % (f_index+1) %filament_maps[f_index]; - assert(false); //for some updates happens in a invalid state(caused by popup window) //we need to avoid crash variant_index[f_index] = 0; @@ -11876,6 +11968,21 @@ PRINT_CONFIG_CACHE_INITIALIZE(( SLAMaterialConfig, SLAPrintConfig, SLAPrintObjectConfig, SLAPrinterConfig, SLAFullPrintConfig)) static int print_config_static_initialized = print_config_static_initializer(); +// The same set() calls ConfigBase::apply_only() makes, without looking every key up by name. Out of line so the +// option list is expanded for this once, not in every file that includes PrintConfig.hpp. +#define PRINT_CONFIG_APPLY_TO_DEFINITION(r, data, CLASS_NAME) \ + bool CLASS_NAME::apply_to(ConfigBase &target) const \ + { \ + auto *dst = dynamic_cast(&target); \ + if (dst == nullptr) \ + return false; \ + visit_option_pairs(*dst, *this, [](const char*, ConfigOption &a, const ConfigOption &b) { a.set(&b); return true; }); \ + return true; \ + } +BOOST_PP_SEQ_FOR_EACH(PRINT_CONFIG_APPLY_TO_DEFINITION, _, (PrintObjectConfig)(PrintRegionConfig)(MachineEnvelopeConfig)(GCodeConfig) + (SLAMaterialConfig)(SLAPrintConfig)(SLAPrintObjectConfig)(SLAPrinterConfig)) +#undef PRINT_CONFIG_APPLY_TO_DEFINITION + //BBS: remove unused command currently CLIActionsConfigDef::CLIActionsConfigDef() { @@ -12513,6 +12620,7 @@ OtherSlicingStatesConfigDef::OtherSlicingStatesConfigDef() new_def("initial_no_support_extruder", coInt, "Initial no support extruder", "Zero-based index of the first extruder used for printing without support. Same as initial_no_support_tool."); new_def("in_head_wrap_detect_zone", coBool, "In head wrap detect zone", "Indicates if the first layer overlaps with the head wrap zone."); + new_def("curr_bed_type", coString, "Current bed type", "Name of the currently selected bed plate type (e.g. 'Textured PEI Plate', 'Smooth High Temp Plate')."); } PrintStatisticsConfigDef::PrintStatisticsConfigDef() diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 679811d699..bbd92079c0 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -30,6 +30,8 @@ namespace Slic3r { +class DynamicPrintConfig; + enum GCodeFlavor : unsigned char { gcfMarlinLegacy, gcfKlipper, @@ -519,8 +521,11 @@ enum NozzleVolumeType { // with more than one sub-nozzle (extruder_max_nozzle_count > 1); matched as Standard for // preset lookup and never emitted in profile variant strings nvtTPUHighFlow, // physical variant, used on H2D/H2DP 0.4 nozzles only + // 4 is reserved: E3D High Flow is 5 in BambuStudio's slice_info and device numbering. + nvtE3DHighFlow = 5, // physical variant, E3D high-flow hotend on 0.4/0.6 nozzles + nvtExtraHighFlow = 6, // Orca: physical variant with no BambuStudio or device counterpart; only profiles name it // Integer values are serialized as raw ints in 3mf plate metadata and device MQTT, so they MUST stay stable. - nvtMaxNozzleVolumeType = nvtTPUHighFlow + nvtMaxNozzleVolumeType = nvtExtraHighFlow }; enum FilamentMapMode { @@ -558,11 +563,19 @@ static std::set get_valid_nozzle_volume_type() { // Hybrid is not a physical nozzle variant: presets never define it, so it must not // produce a variant string. if (t == nvtHybrid) continue; + // Skip the reserved gap between nvtTPUHighFlow (3) and nvtE3DHighFlow (5). + if (i > nvtTPUHighFlow && i < nvtE3DHighFlow) continue; type.insert(t); } return type; } +// The nozzle volume types the given extruder physically provides, as declared by the printer +// profile's extruder_variant_list. An empty set means the profile could not be read and must be +// treated as "unknown", not as "none". nvtHybrid is never reported: it describes an extruder +// holding a mix of nozzles, not a nozzle the profile can offer. +extern std::set get_extruder_supported_nozzle_volume_types(const DynamicPrintConfig &printer_config, int extruder_id); + std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type); static std::string bed_type_to_gcode_string(const BedType type) @@ -699,8 +712,6 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SurfaceFillOrder) #undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS -class DynamicPrintConfig; - // Defines each and every configuration option of Slic3r, including the properties of the GUI dialogs. // Does not store the actual values, but defines default values. class PrintConfigDef : public ConfigDef @@ -821,6 +832,10 @@ public: //BBS bool is_using_different_extruders(); bool support_different_extruders(int& extruder_count) const; + // Whether any filament defines more than one variant (filament_extruder_variant longer than + // filament_diameter). Its variants then have to be resolved even on a printer with a single + // extruder variant, which picks the filament's variant of the same variant string. + bool has_multi_variant_filament() const; // Counts the config slots of a printer: one per (extruder x nozzle volume type) as described by // extruder_nozzle_stats, or simply one per extruder when the stats are absent/mismatched. // Fills nozzle_volume_types with each extruder's volume types in ascending enum order. @@ -869,6 +884,11 @@ extern std::set empty_options; void set_variant_override(ConfigOptionVectorBase &target, const ConfigOptionVectorBase &source, const std::vector &variant_index, int stride = 1); +// Orca: lays every filament_options_with_variant option out one value per filament variant, as +// filament_self_index maps the variants to filaments. An option holding one value per filament, or a +// single value, gives every variant of a filament that filament's value; other lengths are left alone. +void normalize_filament_values_to_variants(DynamicPrintConfig &config); + extern std::set filament_dev_options; extern void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPrintConfig& dest_config, std::vector variant_index, std::set& key_set1, int stride = 1); @@ -1013,9 +1033,10 @@ public: \ #define PRINT_CONFIG_CLASS_ELEMENT_DEFINITION(r, data, elem) BOOST_PP_TUPLE_ELEM(0, elem) BOOST_PP_TUPLE_ELEM(1, elem); #define PRINT_CONFIG_CLASS_ELEMENT_VISIT(r, data, elem) if (! f(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(1, elem)), this->BOOST_PP_TUPLE_ELEM(1, elem), rhs.BOOST_PP_TUPLE_ELEM(1, elem))) return; +#define PRINT_CONFIG_CLASS_ELEMENT_VISIT_SELF(r, data, elem) if (! f(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(1, elem)), self.BOOST_PP_TUPLE_ELEM(1, elem), rhs.BOOST_PP_TUPLE_ELEM(1, elem))) return; // Each option list is expanded into the members and again into for_each_option_pair(), which calls // f(key, this->option, rhs.option) in declaration order and stops when f returns false. hash(), -// operator==, operator< and initialize() iterate the options through that visitor. +// operator==, operator<, initialize() and apply_to() iterate the options through that visitor. #define PRINT_CONFIG_CLASS_COMMON_BODY(CLASS_NAME) \ size_t hash() const throw() \ { \ @@ -1047,11 +1068,16 @@ class CLASS_NAME : public StaticPrintConfig { \ STATIC_PRINT_CONFIG_CACHE(CLASS_NAME) \ public: \ BOOST_PP_SEQ_FOR_EACH(PRINT_CONFIG_CLASS_ELEMENT_DEFINITION, _, PARAMETER_DEFINITION_SEQ) \ - template void for_each_option_pair(const CLASS_NAME &rhs, F &&f) const \ - { \ - BOOST_PP_SEQ_FOR_EACH(PRINT_CONFIG_CLASS_ELEMENT_VISIT, _, PARAMETER_DEFINITION_SEQ) \ - } \ + template void for_each_option_pair(const CLASS_NAME &rhs, F &&f) const { visit_option_pairs(*this, rhs, f); } \ + /* Defined in PrintConfig.cpp. */ \ + bool apply_to(ConfigBase &target) const override; \ PRINT_CONFIG_CLASS_COMMON_BODY(CLASS_NAME) \ +private: \ + /* The one expansion of the option list, for a const self and for apply_to()'s mutable target. */ \ + template static void visit_option_pairs(Self &self, const CLASS_NAME &rhs, F &&f) \ + { \ + BOOST_PP_SEQ_FOR_EACH(PRINT_CONFIG_CLASS_ELEMENT_VISIT_SELF, _, PARAMETER_DEFINITION_SEQ) \ + } \ }; #define PRINT_CONFIG_CLASS_DERIVED_CLASS_LIST_ITEM(r, data, i, elem) BOOST_PP_COMMA_IF(i) public elem @@ -1072,6 +1098,8 @@ class CLASS_NAME : PRINT_CONFIG_CLASS_DERIVED_CLASS_LIST(CLASSES_PARENTS_TUPLE) public: \ PARAMETER_DEFINITION \ template void for_each_option_pair(const CLASS_NAME &rhs, F &&f) const { PARAMETER_VISIT } \ + /* Its parents each apply themselves to a target member by member, so this one keeps the lookup by name. */ \ + bool apply_to(ConfigBase &/*target*/) const override { return false; } \ size_t hash() const throw() \ { \ size_t seed = 0; \ @@ -2162,6 +2190,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE0( #undef STATIC_PRINT_CONFIG_CACHE_DERIVED #undef PRINT_CONFIG_CLASS_ELEMENT_DEFINITION #undef PRINT_CONFIG_CLASS_ELEMENT_VISIT +#undef PRINT_CONFIG_CLASS_ELEMENT_VISIT_SELF #undef PRINT_CONFIG_CLASS_COMMON_BODY #undef PRINT_CONFIG_CLASS_DEFINE #undef PRINT_CONFIG_CLASS_DERIVED_CLASS_LIST diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index d16e381604..14bd65c9cf 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -1551,12 +1551,19 @@ ExPolygons PrintObject::_shrink_contour_holes(double contour_delta, double hole_ std::vector PrintObject::slice_support_volumes(const ModelVolumeType model_volume_type) const { - auto it_volume = this->model_object()->volumes.begin(); - auto it_volume_end = this->model_object()->volumes.end(); - for (; it_volume != it_volume_end && (*it_volume)->type() != model_volume_type; ++ it_volume) ; + // Supports merge every matching volume; Precise Seam calls the shared slicer one volume at a time. + std::vector volumes; + for (const ModelVolume *volume : this->model_object()->volumes) + if (volume->type() == model_volume_type) + volumes.push_back(volume); + return this->slice_modifier_volumes(volumes); +} + +std::vector PrintObject::slice_modifier_volumes(const std::vector &volumes) const +{ std::vector slices; - if (it_volume != it_volume_end) { - // Found at least a single support volume of model_volume_type. + if (!volumes.empty()) { + // Share layer heights, transforms and cancellation handling across the selected volumes. std::vector zs = zs_from_layers(this->layers()); std::vector merge_layers; bool merge = false; @@ -1564,27 +1571,26 @@ std::vector PrintObject::slice_support_volumes(const ModelVolumeType m auto throw_on_cancel_callback = std::function([print](){ print->throw_if_canceled(); }); MeshSlicingParamsEx params; params.trafo = this->trafo_centered(); - for (; it_volume != it_volume_end; ++ it_volume) - if ((*it_volume)->type() == model_volume_type) { - std::vector slices2 = slice_volume(*(*it_volume), zs, params, throw_on_cancel_callback); - if (slices.empty()) { - slices.reserve(slices2.size()); - for (ExPolygons &src : slices2) - slices.emplace_back(to_polygons(std::move(src))); - } else if (!slices2.empty()) { - if (merge_layers.empty()) - merge_layers.assign(zs.size(), false); - for (size_t i = 0; i < zs.size(); ++ i) { - if (slices[i].empty()) - slices[i] = to_polygons(std::move(slices2[i])); - else if (! slices2[i].empty()) { - append(slices[i], to_polygons(std::move(slices2[i]))); - merge_layers[i] = true; - merge = true; - } + for (const ModelVolume *volume : volumes) { + std::vector slices2 = slice_volume(*volume, zs, params, throw_on_cancel_callback); + if (slices.empty()) { + slices.reserve(slices2.size()); + for (ExPolygons &src : slices2) + slices.emplace_back(to_polygons(std::move(src))); + } else if (!slices2.empty()) { + if (merge_layers.empty()) + merge_layers.assign(zs.size(), false); + for (size_t i = 0; i < zs.size(); ++ i) { + if (slices[i].empty()) + slices[i] = to_polygons(std::move(slices2[i])); + else if (! slices2[i].empty()) { + append(slices[i], to_polygons(std::move(slices2[i]))); + merge_layers[i] = true; + merge = true; } } } + } if (merge) { std::vector to_merge; to_merge.reserve(zs.size()); diff --git a/src/libslic3r/TextureBake/TextureBakeDebug.cpp b/src/libslic3r/TextureBake/TextureBakeDebug.cpp new file mode 100644 index 0000000000..9465080e21 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeDebug.cpp @@ -0,0 +1,219 @@ +#include "TextureBakeDebug.hpp" + +#include +#include +#include + +#include +#include + +namespace Slic3r { + +namespace { + +// Half-edge key, low index first so both sides of an edge form the same one. +inline uint64_t edge_key(int a, int b) +{ + const uint32_t lo = uint32_t(std::min(a, b)), hi = uint32_t(std::max(a, b)); + return (uint64_t(lo) << 32) | uint64_t(hi); +} + +} // namespace + +void bake_stage_topology(const BakeStageMesh &mesh, size_t &open_edges, size_t &non_manifold_edges, + size_t °enerate) +{ + open_edges = non_manifold_edges = degenerate = 0; + + // Sorted half-edges rather than a hash map: same answer, but it is one allocation and a sort + // instead of three million node allocations, which on a stage this size is the whole cost. + std::vector keys; + keys.reserve(mesh.indices.size() * 3); + for (const Vec3i32 &t : mesh.indices) { + if (t[0] == t[1] || t[1] == t[2] || t[0] == t[2]) { + ++degenerate; + continue; // a collapsed face has no edges worth counting + } + const Vec3f &a = mesh.vertices[size_t(t[0])]; + if ((mesh.vertices[size_t(t[1])] - a).cross(mesh.vertices[size_t(t[2])] - a).squaredNorm() <= 0.f) + ++degenerate; // zero area but three distinct corners: still counted as an edge carrier + for (int e = 0; e < 3; ++e) + keys.push_back(edge_key(t[e], t[(e + 1) % 3])); + } + std::sort(keys.begin(), keys.end()); + for (size_t i = 0; i < keys.size();) { + size_t j = i + 1; + while (j < keys.size() && keys[j] == keys[i]) + ++j; + const size_t incident = j - i; + if (incident == 1) + ++open_edges; + else if (incident > 2) + ++non_manifold_edges; + i = j; + } +} + +void BakeStageRecorder::finish(BakeStageSnapshot &s) +{ + s.triangles = s.mesh.indices.size(); + s.vertices = s.mesh.vertices.size(); + if (m_check_topology) + bake_stage_topology(s.mesh, s.open_edges, s.non_manifold_edges, s.degenerate); + s.topology_checked = m_check_topology; + if (s.triangles > m_mesh_cap) { + s.mesh_dropped = true; + s.mesh.vertices.clear(); + s.mesh.vertices.shrink_to_fit(); + s.mesh.indices.clear(); + s.mesh.indices.shrink_to_fit(); + } + m_stages.push_back(std::move(s)); +} + +void BakeStageRecorder::capture(const char *name, const TextureBake::TriSoup &soup, double ms, + const std::string &detail) +{ + if (!m_enabled) + return; + + BakeStageSnapshot s; + s.name = name; + s.detail = detail; + s.ms = ms; + + // The pipeline works on non-indexed soup, so welding here is what turns it back into something + // renderable. The geometry grid, matching to_indexed_triangle_set(), so the debug view shows the + // same sharing the bake's own output would have. + const size_t n = soup.pos.size(); + TextureBake::QuantizedPointMap map(TextureBake::WELD_GRID_GEOMETRY, std::min(n, size_t(1) << 22)); + std::vector id(n); + s.mesh.vertices.reserve(n / 3); + for (size_t i = 0; i < n; ++i) { + id[i] = map.get_or_set(soup.pos[i], int(s.mesh.vertices.size())); + if (map.inserted()) + s.mesh.vertices.push_back(soup.pos[i]); + } + s.mesh.indices.reserve(n / 3); + for (size_t t = 0; t + 2 < n; t += 3) { + // Corners that welded together carry no area; the bake's own conversion drops them too, so + // dropping them here keeps the stage count honest against what would be committed. + if (id[t] == id[t + 1] || id[t + 1] == id[t + 2] || id[t] == id[t + 2]) + continue; + s.mesh.indices.emplace_back(id[t], id[t + 1], id[t + 2]); + } + finish(s); +} + +void BakeStageRecorder::capture(const char *name, const std::vector &vertices, + const std::vector &indices, double ms, + const std::string &detail) +{ + if (!m_enabled) + return; + BakeStageSnapshot s; + s.name = name; + s.detail = detail; + s.ms = ms; + s.mesh.vertices = vertices; + s.mesh.indices = indices; + finish(s); +} + +void BakeStageRecorder::capture_note(const char *name, double ms, const std::string &detail) +{ + if (!m_enabled) + return; + BakeStageSnapshot s; + s.name = name; + s.detail = detail; + s.ms = ms; + s.topology_checked = false; + m_stages.push_back(std::move(s)); +} + +void BakeStageRecorder::rebase(size_t from, const Transform3d *to_local, bool flip_winding) +{ + for (size_t i = from; i < m_stages.size(); ++i) { + BakeStageMesh &m = m_stages[i].mesh; + if (to_local != nullptr) + for (Vec3f &v : m.vertices) + v = (*to_local * v.cast()).cast(); + if (flip_winding) + for (Vec3i32 &t : m.indices) + std::swap(t[1], t[2]); + } +} + +double BakeStageRecorder::total_ms() const +{ + double sum = 0.0; + for (const BakeStageSnapshot &s : m_stages) + sum += s.ms; + return sum; +} + +size_t dump_bake_stages(const std::vector &stages, const std::string &dir) +{ + boost::system::error_code ec; + boost::filesystem::create_directories(dir, ec); + if (ec) { + BOOST_LOG_TRIVIAL(error) << "BakeStageRecorder: cannot create " << dir << ": " << ec.message(); + return 0; + } + + size_t written = 0; + for (size_t i = 0; i < stages.size(); ++i) { + const BakeStageSnapshot &s = stages[i]; + if (s.mesh.empty()) + continue; + + // Stage names carry spaces and punctuation; keep the filename to what every shell and viewer + // handles without quoting. + std::string safe; + for (const char c : s.name) + safe += (std::isalnum(static_cast(c)) != 0) ? c : '_'; + + char path[1024]; + std::snprintf(path, sizeof(path), "%s/%02zu_%s.obj", dir.c_str(), i, safe.c_str()); + std::FILE *f = std::fopen(path, "wb"); + if (f == nullptr) { + BOOST_LOG_TRIVIAL(error) << "BakeStageRecorder: cannot write " << path; + continue; + } + std::fprintf(f, "# texture bake stage %zu: %s\n", i, s.name.c_str()); + if (!s.detail.empty()) + std::fprintf(f, "# %s\n", s.detail.c_str()); + std::fprintf(f, "# %zu triangles, %.2f ms\n", s.triangles, s.ms); + for (const Vec3f &v : s.mesh.vertices) + std::fprintf(f, "v %.6f %.6f %.6f\n", double(v.x()), double(v.y()), double(v.z())); + for (const Vec3i32 &t : s.mesh.indices) // OBJ indices are 1-based + std::fprintf(f, "f %d %d %d\n", t[0] + 1, t[1] + 1, t[2] + 1); + std::fclose(f); + ++written; + } + + char summary[1024]; + std::snprintf(summary, sizeof(summary), "%s/stages.txt", dir.c_str()); + if (std::FILE *f = std::fopen(summary, "wb"); f != nullptr) { + std::fprintf(f, "%-3s %-24s %10s %12s %10s %8s %8s %8s %s\n", "#", "stage", "ms", "triangles", + "vertices", "open", "nonman", "degen", "detail"); + double total = 0.0; + for (size_t i = 0; i < stages.size(); ++i) { + const BakeStageSnapshot &s = stages[i]; + total += s.ms; + std::fprintf(f, "%-3zu %-24s %10.2f %12zu %10zu ", i, s.name.c_str(), s.ms, s.triangles, + s.vertices); + if (s.topology_checked) + std::fprintf(f, "%8zu %8zu %8zu", s.open_edges, s.non_manifold_edges, s.degenerate); + else + std::fprintf(f, "%8s %8s %8s", "-", "-", "-"); + std::fprintf(f, " %s%s\n", s.detail.c_str(), s.mesh_dropped ? " [mesh over cap, not written]" : ""); + } + std::fprintf(f, "\ntotal %.2f ms across %zu stages\n", total, stages.size()); + std::fclose(f); + } + return written; +} + +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeDebug.hpp b/src/libslic3r/TextureBake/TextureBakeDebug.hpp new file mode 100644 index 0000000000..5c6d987e44 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeDebug.hpp @@ -0,0 +1,123 @@ +#pragma once + +// Step-by-step capture of a bake. +// +// A bake is a chain of stages that each rewrite the whole mesh, so when the result looks wrong the +// only useful question is which stage made it wrong. This records the geometry, the wall time and the +// topology after every stage, which is what the gizmo's debug view steps through and what the +// benchmark's --dump-stages writes out. +// +// Deliberately independent of TriangleMesh: a stage is held as a plain vertex/index pair, which is +// layout-compatible with indexed_triangle_set's own members (stl_vertex is Vec3f, +// stl_triangle_vertex_indices is Vec3i32), so the GUI assigns rather than converts and the standalone +// benchmark does not have to link admesh to use this. +// +// Recording is off unless enable(true) was called, and every capture site is a null-pointer check, so +// a normal bake pays nothing for this being here. + +#include +#include +#include +#include + +#include "TextureBakeIndex.hpp" + +namespace Slic3r { + +struct BakeStageMesh +{ + std::vector vertices; + std::vector indices; + + bool empty() const { return indices.empty(); } + size_t triangle_count() const { return indices.size(); } +}; + +struct BakeStageSnapshot +{ + std::string name; // "remesh", "subdivide", ... + std::string detail; // whatever the stage has to say: collapse counts, rejected moves, ... + BakeStageMesh mesh; // empty when the stage was over the memory cap - see mesh_dropped + + double ms = 0.0; + size_t triangles = 0; + size_t vertices = 0; + + // Filled only when the recorder was asked to check topology: it is a sort over every half-edge, + // which on a multi-million triangle stage costs more than the stage being measured. + size_t open_edges = 0; + size_t non_manifold_edges = 0; + size_t degenerate = 0; + bool topology_checked = false; + + // The geometry was dropped to stay inside the memory cap; every count above is still real. + bool mesh_dropped = false; +}; + +// Edge and area defects of a captured stage. Split out so a caller can run it on its own. +void bake_stage_topology(const BakeStageMesh &mesh, size_t &open_edges, size_t &non_manifold_edges, + size_t °enerate); + +// Writes `/NN_name.obj` for every stage that still holds geometry, plus a `stages.txt` summary. +// Returns how many meshes were written. Existing files with the same names are overwritten. +// +// A free function rather than a recorder method because by the time anyone wants the files the +// recorder is usually gone and only the stages survive - that is how the gizmo holds them. +size_t dump_bake_stages(const std::vector &stages, const std::string &dir); + +class BakeStageRecorder +{ +public: + // Nothing is recorded until this is on. + void enable(bool on) { m_enabled = on; } + bool enabled() const { return m_enabled; } + + // The edge scan is optional because it is O(n log n) over every half-edge, and a debug run that + // only wants to see the geometry should not pay for it on every stage. + void set_check_topology(bool on) { m_check_topology = on; } + bool check_topology() const { return m_check_topology; } + + // Stages above this keep their counts but not their geometry. A debug run holds every stage at + // once, and a 4 M triangle stage is about 150 MB on its own, so without a cap stepping through a + // fine bake would need more memory than the bake did. + void set_mesh_cap(size_t triangles) { m_mesh_cap = triangles; } + size_t mesh_cap() const { return m_mesh_cap; } + + // `ms` is passed in rather than measured here: the caller is already timing the stage, and the + // capture itself (a weld, a copy, possibly an edge scan) must not land inside that measurement. + void capture(const char *name, const TextureBake::TriSoup &soup, double ms, + const std::string &detail = {}); + void capture(const char *name, const std::vector &vertices, + const std::vector &indices, double ms, const std::string &detail = {}); + // For a stage that changed nothing a caller can still show, e.g. a skipped remesh. + void capture_note(const char *name, double ms, const std::string &detail); + + // Index of the next stage to be recorded. Paired with rebase() to fix up a range afterwards. + size_t mark() const { return m_stages.size(); } + + // Brings stages [from, end) into the caller's own space and winding. The bake runs in world + // millimetres and, for a mirrored placement, against a reversed winding; the debug view draws in + // the volume's local frame, so a captured range has to be brought back the same way the bake's + // own result is. `to_local` may be null for no transform. + void rebase(size_t from, const Transform3d *to_local, bool flip_winding); + + const std::vector &stages() const { return m_stages; } + std::vector take() { return std::move(m_stages); } + void clear() { m_stages.clear(); } + bool empty() const { return m_stages.empty(); } + + // Total recorded wall time, which is the bake's own time minus whatever it does outside a stage. + double total_ms() const; + + size_t dump_obj(const std::string &dir) const { return dump_bake_stages(m_stages, dir); } + +private: + void finish(BakeStageSnapshot &s); + + std::vector m_stages; + bool m_enabled = false; + bool m_check_topology = true; + size_t m_mesh_cap = 4'000'000; +}; + +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeDecimate.cpp b/src/libslic3r/TextureBake/TextureBakeDecimate.cpp new file mode 100644 index 0000000000..ee335cff3c --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeDecimate.cpp @@ -0,0 +1,562 @@ +#include "TextureBakeDecimate.hpp" + +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace Slic3r { +namespace TextureBake { + +namespace { + +// Symmetric 4x4 quadric, as its 10 upper-triangle values. +struct Quadric +{ + std::array q{}; + + void add_plane(double a, double b, double c, double d) + { + q[0] += a * a; q[1] += a * b; q[2] += a * c; q[3] += a * d; + q[4] += b * b; q[5] += b * c; q[6] += b * d; + q[7] += c * c; q[8] += c * d; + q[9] += d * d; + } + void operator+=(const Quadric &o) + { + for (int i = 0; i < 10; ++i) + q[size_t(i)] += o.q[size_t(i)]; + } + double eval(double x, double y, double z) const + { + return q[0] * x * x + 2 * q[1] * x * y + 2 * q[2] * x * z + 2 * q[3] * x + + q[4] * y * y + 2 * q[5] * y * z + 2 * q[6] * y + + q[7] * z * z + 2 * q[8] * z + q[9]; + } +}; + +double eval_sum(const std::vector &qs, int v1, int v2, const Vec3d &p) +{ + return qs[size_t(v1)].eval(p.x(), p.y(), p.z()) + qs[size_t(v2)].eval(p.x(), p.y(), p.z()); +} + +// The position minimising the summed quadric, if the system is well conditioned enough to trust. +bool solve_q(const std::vector &qs, int v1, int v2, Vec3d &out) +{ + const auto &A = qs[size_t(v1)].q; + const auto &B = qs[size_t(v2)].q; + const double a00 = A[0] + B[0], a01 = A[1] + B[1], a02 = A[2] + B[2]; + const double a11 = A[4] + B[4], a12 = A[5] + B[5], a22 = A[7] + B[7]; + const double b0 = -(A[3] + B[3]), b1 = -(A[6] + B[6]), b2 = -(A[8] + B[8]); + + const double det = a00 * (a11 * a22 - a12 * a12) - a01 * (a01 * a22 - a12 * a02) + + a02 * (a01 * a12 - a11 * a02); + const double max_el = std::max({ std::abs(a00), std::abs(a01), std::abs(a02), std::abs(a11), + std::abs(a12), std::abs(a22) }); + // Scaled with the matrix, so it means the same at any model scale. + const double threshold = max_el * max_el * max_el * 1e-10; + if (std::abs(det) < std::max(threshold, 1e-30)) + return false; + + const double inv = 1.0 / det; + out.x() = inv * (b0 * (a11 * a22 - a12 * a12) - a01 * (b1 * a22 - a12 * b2) + a02 * (b1 * a12 - a11 * b2)); + out.y() = inv * (a00 * (b1 * a22 - a12 * b2) - b0 * (a01 * a22 - a12 * a02) + a02 * (a01 * b2 - b1 * a02)); + out.z() = inv * (a00 * (a11 * b2 - b1 * a12) - a01 * (a01 * b2 - b1 * a02) + b0 * (a01 * a12 - a11 * a02)); + return true; +} + +Vec3d face_normal_unit(const std::vector &pos, int a, int b, int c) +{ + const Vec3d n = (pos[size_t(b)] - pos[size_t(a)]).cross(pos[size_t(c)] - pos[size_t(a)]); + const double len = n.norm(); + return (len > 0.0) ? Vec3d(n / len) : Vec3d::Zero(); +} + +// Versions are captured at push time; a mismatch on pop means a later collapse invalidated the entry. +// Lazy deletion, far cheaper than removing entries eagerly - but it means the heap accumulates stale +// duplicates, so its size has to be reserved up front and it is compacted once the dead entries +// dominate (see maybe_compact below). +// +// The collapse target is not stored. A matching version stamp means neither endpoint's quadric nor its +// position has changed since the push, so the target recomputes to exactly the same value on pop - and +// the entry drops from 40 bytes to 24. Sifting is most of this stage's time, and it is memory traffic. +struct HeapEntry +{ + double cost; + int v1, v2; + uint32_t ver1, ver2; + bool operator>(const HeapEntry &o) const { return cost > o.cost; } +}; + +} // namespace + +DecimateResult decimate(const TriSoup &geometry, size_t target_triangles, bool harvest_flat, + double harvest_tol, const std::vector &locked_faces, + const DecimateProgressFn &on_progress, const std::vector &face_color) +{ + DecimateResult result; + const size_t n = geometry.pos.size(); + if (n < 3) { + result.geometry = geometry; + return result; + } + + // The finest grid. Anything coarser fuses distinct fine-feature vertices on a displaced mesh, + // leaving it non-manifold before decimation starts and producing open edges afterwards. + QuantizedPointMap vert_map(WELD_GRID_DECIMATION, std::min(n, size_t(1) << 22)); + std::vector pos; + std::vector remap(n); + for (size_t i = 0; i < n; ++i) { + const int idx = vert_map.get_or_set(geometry.pos[i], int(pos.size())); + if (vert_map.inserted()) + pos.push_back(geometry.pos[i].cast()); + remap[i] = idx; + } + const size_t vert_count = pos.size(); + const size_t face_count = n / 3; + std::vector faces(face_count * 3); + for (size_t i = 0; i < n; ++i) + faces[i] = remap[i]; + + if (face_count <= target_triangles && !harvest_flat) { + result.geometry = geometry; + return result; + } + + // An edge with a locked endpoint never reaches the heap. + std::vector locked_vert; + size_t locked_face_count = 0; + if (!locked_faces.empty()) { + locked_vert.assign(vert_count, 0); + for (size_t f = 0; f < face_count && f < locked_faces.size(); ++f) { + if (!locked_faces[f]) + continue; + ++locked_face_count; + for (int k = 0; k < 3; ++k) + locked_vert[size_t(faces[f * 3 + size_t(k)])] = 1; + } + } + // With the locked faces alone at the target, chasing it would grind the free region to its guard + // limit for nothing - harvest only, and say so. + const bool locked_over_budget = + !locked_vert.empty() && face_count > target_triangles && locked_face_count >= target_triangles; + result.locked_over_budget = locked_over_budget; + if (locked_over_budget && !harvest_flat) { + result.geometry = geometry; + return result; + } + + std::vector quadrics(vert_count); + { + // The plane per face is independent; accumulating it into the three incident vertices is not, + // so only the first half is parallel. + std::vector planes(face_count, Vec4d::Zero()); + tbb::parallel_for(tbb::blocked_range(0, face_count), + [&](const tbb::blocked_range &range) { + for (size_t f = range.begin(); f < range.end(); ++f) { + const int a = faces[f * 3], b = faces[f * 3 + 1], c = faces[f * 3 + 2]; + if (a < 0) + continue; + const Vec3d nrm = face_normal_unit(pos, a, b, c); + if (nrm.isZero()) + continue; + planes[f] = Vec4d(nrm.x(), nrm.y(), nrm.z(), -nrm.dot(pos[size_t(a)])); + } + }); + for (size_t f = 0; f < face_count; ++f) { + const Vec4d &pl = planes[f]; + if (pl.head<3>().isZero()) + continue; + for (int k = 0; k < 3; ++k) + quadrics[size_t(faces[f * 3 + size_t(k)])].add_plane(pl.x(), pl.y(), pl.z(), pl.w()); + } + } + + // Two penalty planes per endpoint on a sharp interior edge, each perpendicular to one adjacent + // face and containing the edge, constraining the vertex to the crease line. + { + struct EdgeRec { int va, vb, f0, f1; uint8_t count; }; + std::vector edges; + QuantizedPointMap edge_idx(1.0, std::min(face_count * 3, size_t(1) << 22)); + for (size_t f = 0; f < face_count; ++f) { + if (faces[f * 3] < 0) + continue; + for (int e = 0; e < 3; ++e) { + const int va = faces[f * 3 + size_t(e)]; + const int vb = faces[f * 3 + size_t((e + 1) % 3)]; + const int lo = std::min(va, vb), hi = std::max(va, vb); + const int ei = edge_idx.get_or_set_key(lo, hi, 0, int(edges.size())); + if (edge_idx.inserted()) + edges.push_back({ lo, hi, int(f), -1, 1 }); + else if (edges[size_t(ei)].count == 1) { + edges[size_t(ei)].f1 = int(f); + edges[size_t(ei)].count = 2; + } else + // Non-manifold; never feeds a crease. + edges[size_t(ei)].count = 3; + } + } + + const double sqrt_w = std::sqrt(DECIMATE_CREASE_WEIGHT); + for (const EdgeRec &er : edges) { + if (er.count != 2) + continue; // boundary or non-manifold + const Vec3d n0 = face_normal_unit(pos, faces[size_t(er.f0) * 3], faces[size_t(er.f0) * 3 + 1], + faces[size_t(er.f0) * 3 + 2]); + const Vec3d n1 = face_normal_unit(pos, faces[size_t(er.f1) * 3], faces[size_t(er.f1) * 3 + 1], + faces[size_t(er.f1) * 3 + 2]); + const bool color_edge = face_color.size() > std::max(size_t(er.f0), size_t(er.f1)) && + face_color[size_t(er.f0)] != face_color[size_t(er.f1)]; + if (!color_edge && n0.dot(n1) >= DECIMATE_CREASE_COS) + continue; // smooth enough to be no crease, and no colour changes across it + + const Vec3d e = pos[size_t(er.vb)] - pos[size_t(er.va)]; + const double elen = e.norm(); + if (elen <= 0.0) + continue; + const Vec3d ed = e / elen; + for (const Vec3d &fn : { n0, n1 }) { + Vec3d pn = fn.cross(ed); + const double plen = pn.norm(); + if (plen < 1e-10) + continue; // edge parallel to the face normal + pn /= plen; + const double d = -pn.dot(pos[size_t(er.va)]); + // sqrt(w) on the inputs gives w times the accumulated products. + for (const int v : { er.va, er.vb }) + quadrics[size_t(v)].add_plane(pn.x() * sqrt_w, pn.y() * sqrt_w, pn.z() * sqrt_w, + d * sqrt_w); + } + } + } + + // Vertex-face incidence as intrusive linked lists of slots over flat arrays, with each list's length. + const size_t S = face_count * 3; + std::vector vf_head(vert_count, -1), vf_count(vert_count, 0), slot_face(S), slot_vert(S), + slot_next(S, -1), slot_prev(S, -1), face_slot(S, -1); + for (size_t f = 0; f < face_count; ++f) + for (int k = 0; k < 3; ++k) { + const int s = int(f) * 3 + k; + const int v = faces[size_t(s)]; + slot_face[size_t(s)] = int(f); + slot_vert[size_t(s)] = v; + slot_next[size_t(s)] = vf_head[size_t(v)]; + slot_prev[size_t(s)] = -1; + if (vf_head[size_t(v)] >= 0) + slot_prev[size_t(vf_head[size_t(v)])] = s; + vf_head[size_t(v)] = s; + face_slot[size_t(s)] = s; + ++vf_count[size_t(v)]; + } + const auto unlink_slot = [&](int s) { + const int p = slot_prev[size_t(s)], nx = slot_next[size_t(s)], v = slot_vert[size_t(s)]; + if (p >= 0) slot_next[size_t(p)] = nx; + else vf_head[size_t(v)] = nx; + if (nx >= 0) slot_prev[size_t(nx)] = p; + --vf_count[size_t(v)]; + }; + const auto move_slot = [&](int s, int nv) { + unlink_slot(s); + slot_next[size_t(s)] = vf_head[size_t(nv)]; + slot_prev[size_t(s)] = -1; + if (vf_head[size_t(nv)] >= 0) + slot_prev[size_t(vf_head[size_t(nv)])] = s; + vf_head[size_t(nv)] = s; + slot_vert[size_t(s)] = nv; + ++vf_count[size_t(nv)]; + }; + + std::vector active(vert_count, 1); + std::vector version(vert_count, 0); + std::vector nb_stamp(vert_count, 0), lk_stamp(vert_count, 0); + uint32_t epoch = 1, lk_epoch = 1; + size_t active_faces = face_count; + + // A plain vector driven by the heap algorithms, so the capacity can be reserved. Lazy deletion + // means roughly one entry per edge plus one per re-push after each collapse; the reserve below is + // sized from the edge count and simply grows if a mesh needs more. + std::vector heap; + heap.reserve(std::min(face_count * 3, size_t(1) << 24)); + const auto heap_push = [&](HeapEntry e) { + heap.push_back(e); + std::push_heap(heap.begin(), heap.end(), std::greater()); + }; + const auto heap_pop = [&]() { + std::pop_heap(heap.begin(), heap.end(), std::greater()); + const HeapEntry e = heap.back(); + heap.pop_back(); + return e; + }; + size_t pops = 0, stale_pops = 0, compactions = 0; + + // An entry is stale once either endpoint has been removed or moved by a later collapse. + const auto is_stale = [&](const HeapEntry &e) { + return !active[size_t(e.v1)] || !active[size_t(e.v2)] || version[size_t(e.v1)] != e.ver1 || + version[size_t(e.v2)] != e.ver2; + }; + // Measured on a 2.4 M -> 750 k run, 82% of pops were stale: every collapse re-pushes the survivor's + // edges and orphans the old ones, so the heap grows to several times the live edge set and every + // sift walks that much further through memory. Dropping the dead entries and re-heapifying once + // they dominate costs one linear pass, amortised against the growth that triggered it. + // + // Keyed to the live face count rather than to the heap's own size: lazy popping keeps the heap from + // ever doubling, but the live edge set (about 1.5 per face) shrinks as decimation proceeds, so by the + // end the heap is several times what is still collapsible. Compact once it passes twice that. + const auto maybe_compact = [&]() { + if (heap.size() < std::max(size_t(1) << 16, active_faces * 3)) + return; + heap.erase(std::remove_if(heap.begin(), heap.end(), is_stale), heap.end()); + std::make_heap(heap.begin(), heap.end(), std::greater()); + ++compactions; + }; + + // Where an edge collapses to. Also re-run on pop instead of stored - see HeapEntry. + const auto collapse_target = [&](int v1, int v2) -> Vec3d { + Vec3d p; + if (!solve_q(quadrics, v1, v2, p)) { + const Vec3d mid = (pos[size_t(v1)] + pos[size_t(v2)]) * 0.5; + const double e1 = eval_sum(quadrics, v1, v2, pos[size_t(v1)]); + const double e2 = eval_sum(quadrics, v1, v2, pos[size_t(v2)]); + const double em = eval_sum(quadrics, v1, v2, mid); + const double emin = std::min({ e1, e2, em }); + const double etol = emin * 1e-2 + 1e-12; + // The midpoint when the three are near-equal, i.e. flat: it moves adjacent triangles + // least, so fewer normal flips and no stalling on coplanar geometry. + if (em <= emin + etol) p = mid; + else if (e1 <= e2) p = pos[size_t(v1)]; + else p = pos[size_t(v2)]; + } + return p; + }; + const auto push_edge = [&](int v1, int v2) { + const Vec3d p = collapse_target(v1, v2); + // The cost is evaluated at the exact target and the collapse moves to its float rounding - + // the same split as when the rounded target was stored in the entry, so no ordering changes. + // Where quadric costs are all near zero, shorter edges first keeps triangle quality up. + const double len2 = (pos[size_t(v2)] - pos[size_t(v1)]).squaredNorm(); + heap_push({ eval_sum(quadrics, v1, v2, p) + len2 * 1e-8, v1, v2, version[size_t(v1)], + version[size_t(v2)] }); + }; + + { + QuantizedPointMap seed_seen(1.0, std::min(face_count * 3, size_t(1) << 22)); + for (size_t f = 0; f < face_count; ++f) { + if (faces[f * 3] < 0) + continue; + for (int e = 0; e < 3; ++e) { + const int va = faces[f * 3 + size_t(e)]; + const int vb = faces[f * 3 + size_t((e + 1) % 3)]; + if (!locked_vert.empty() && (locked_vert[size_t(va)] || locked_vert[size_t(vb)])) + continue; + seed_seen.get_or_set_key(std::min(va, vb), std::max(va, vb), 0, 1); + if (seed_seen.inserted()) + push_edge(va, vb); + } + } + } + + // 0 means a stale entry, 1 a boundary edge, 2 or more safe. + const auto shared_face_count = [&](int v1, int v2) { + int count = 0; + for (int s = vf_head[size_t(v1)]; s >= 0; s = slot_next[size_t(s)]) { + const int f = slot_face[size_t(s)]; + if (faces[size_t(f) * 3] < 0) + continue; + for (int k = 0; k < 3; ++k) + if (faces[size_t(f) * 3 + size_t(k)] == v2) { + if (++count >= 2) + return 2; + break; + } + } + return count; + }; + + // Safe only when the sole common neighbours of the endpoints are the apexes of the faces the edge + // already shares; any other would pile a third triangle onto an edge after the collapse. + const auto has_link_violation = [&](int v1, int v2, uint32_t ep) { + for (int s = vf_head[size_t(v1)]; s >= 0; s = slot_next[size_t(s)]) { + const int f = slot_face[size_t(s)]; + if (faces[size_t(f) * 3] < 0) + continue; + for (int k = 0; k < 3; ++k) + if (const int x = faces[size_t(f) * 3 + size_t(k)]; x != v1) + lk_stamp[size_t(x)] = ep; + } + int shared = 0; + for (int s = vf_head[size_t(v1)]; s >= 0; s = slot_next[size_t(s)]) { + const int f = slot_face[size_t(s)]; + if (faces[size_t(f) * 3] < 0) + continue; + const int a = faces[size_t(f) * 3], b = faces[size_t(f) * 3 + 1], c = faces[size_t(f) * 3 + 2]; + if (a == v2 || b == v2 || c == v2) { + ++shared; + const int apex = (a != v1 && a != v2) ? a : (b != v1 && b != v2) ? b : c; + lk_stamp[size_t(apex)] = ep + 1; // a legal shared-face apex + } + } + if (shared > 2) + return true; // already non-manifold + for (int s = vf_head[size_t(v2)]; s >= 0; s = slot_next[size_t(s)]) { + const int f = slot_face[size_t(s)]; + if (faces[size_t(f) * 3] < 0) + continue; + for (int k = 0; k < 3; ++k) { + const int x = faces[size_t(f) * 3 + size_t(k)]; + if (x != v2 && x != v1 && lk_stamp[size_t(x)] == ep) + return true; + } + } + return false; + }; + + // Squared-dot, so no square root or division. Faces containing the other endpoint are the ones + // being removed, so they are skipped. + const auto check_flipped = [&](int vc, int vo, const Vec3d &np) { + for (int s = vf_head[size_t(vc)]; s >= 0; s = slot_next[size_t(s)]) { + const size_t f = size_t(slot_face[size_t(s)]); + if (faces[f * 3] < 0) + continue; + const int fa = faces[f * 3], fb = faces[f * 3 + 1], fc = faces[f * 3 + 2]; + if (fa == vo || fb == vo || fc == vo) + continue; + const Vec3d oa = pos[size_t(fa)], ob = pos[size_t(fb)], oc = pos[size_t(fc)]; + const Vec3d on = (ob - oa).cross(oc - oa); + const Vec3d na = (fa == vc) ? np : oa; + const Vec3d nb = (fb == vc) ? np : ob; + const Vec3d nc = (fc == vc) ? np : oc; + const Vec3d nn = (nb - na).cross(nc - na); + const double raw = on.dot(nn); + if (raw < 0.0) + return true; + if (raw * raw < DECIMATE_FLIP_DOT * DECIMATE_FLIP_DOT * on.squaredNorm() * nn.squaredNorm()) + return true; + } + return false; + }; + + const size_t init_faces = active_faces; + const size_t to_remove = std::max(1, init_faces > target_triangles + ? init_faces - target_triangles : init_faces); + const double harvest_ceil = harvest_tol * harvest_tol; + bool reached_target = locked_over_budget; + double last_progress = 0.0; + + while (!heap.empty()) { + if (active_faces <= target_triangles) { + if (!harvest_flat) + break; + reached_target = true; + } + + const HeapEntry top = heap_pop(); + ++pops; + if (on_progress) { + // Every 16 k pops as well as whenever the fraction moves: this is the only place a cancel + // is seen, and past the target the fraction stops moving. + const double p = std::min(1.0, double(init_faces - active_faces) / double(to_remove)); + if (p - last_progress > 0.005 || (pops & 0x3fff) == 0) { + last_progress = p; + if (!on_progress(p)) + break; + } + } + // The popped entry is the cheapest left, so exceeding the tolerance ends the run. + if (reached_target && top.cost > harvest_ceil) + break; + + const int v1 = top.v1, v2 = top.v2; + if (is_stale(top)) { + ++stale_pops; + continue; + } + // Ahead of the checks below, which walk the fans (see DECIMATE_MAX_VALENCE). The two shared + // faces, counted in both fans, go. + if (vf_count[size_t(v1)] + vf_count[size_t(v2)] - 4 > DECIMATE_MAX_VALENCE) + continue; + if (shared_face_count(v1, v2) < 2) + continue; + lk_epoch += 2; // +2 so ep and ep+1 cannot collide with the next call + if (has_link_violation(v1, v2, lk_epoch)) + continue; + const Vec3d target = collapse_target(v1, v2).cast().cast(); + if (check_flipped(v1, v2, target) || check_flipped(v2, v1, target)) + continue; + if (!reached_target && top.cost > harvest_ceil) + result.target_cost_detail = true; + + // v1 survives at the new position, v2 goes. + pos[size_t(v1)] = target; + quadrics[size_t(v1)] += quadrics[size_t(v2)]; + ++version[size_t(v1)]; + + for (int s = vf_head[size_t(v2)]; s >= 0;) { + const size_t f = size_t(slot_face[size_t(s)]); + const int s_next = slot_next[size_t(s)]; // read before the list is modified + if (faces[f * 3] >= 0) { + for (int k = 0; k < 3; ++k) + if (faces[f * 3 + size_t(k)] == v2) { + faces[f * 3 + size_t(k)] = v1; + break; + } + const int fa = faces[f * 3], fb = faces[f * 3 + 1], fc = faces[f * 3 + 2]; + if (fa == fb || fb == fc || fa == fc) { + for (int k = 0; k < 3; ++k) + if (const int sk = face_slot[f * 3 + size_t(k)]; sk >= 0) { + unlink_slot(sk); + face_slot[f * 3 + size_t(k)] = -1; + } + faces[f * 3] = faces[f * 3 + 1] = faces[f * 3 + 2] = -1; + --active_faces; + } else + move_slot(s, v1); + } + s = s_next; + } + active[size_t(v2)] = 0; + + ++epoch; + for (int sv = vf_head[size_t(v1)]; sv >= 0; sv = slot_next[size_t(sv)]) { + const size_t f = size_t(slot_face[size_t(sv)]); + if (faces[f * 3] < 0) + continue; + for (int k = 0; k < 3; ++k) { + const int nb = faces[f * 3 + size_t(k)]; + if (nb == v1 || nb_stamp[size_t(nb)] == epoch) + continue; + nb_stamp[size_t(nb)] = epoch; + // v1 is never locked - a locked edge never entered the heap. + if (active[size_t(nb)] && (locked_vert.empty() || !locked_vert[size_t(nb)])) + push_edge(v1, nb); + } + } + maybe_compact(); + } + + BOOST_LOG_TRIVIAL(info) << "TextureBake decimate: pops=" << pops << " stale=" << stale_pops + << " compactions=" << compactions << " heap_peak=" << heap.capacity() + << " faces=" << active_faces; + + // Rebuild from the surviving faces, with per-face normals. + TriSoup &out = result.geometry; + for (size_t f = 0; f < face_count; ++f) { + if (faces[f * 3] < 0) + continue; + const Vec3f a = pos[size_t(faces[f * 3])].cast(); + const Vec3f b = pos[size_t(faces[f * 3 + 1])].cast(); + const Vec3f c = pos[size_t(faces[f * 3 + 2])].cast(); + const Vec3f nrm = (b - a).cross(c - a).normalized(); + out.pos.insert(out.pos.end(), { a, b, c }); + out.nrm.insert(out.nrm.end(), { nrm, nrm, nrm }); + } + return result; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeDecimate.hpp b/src/libslic3r/TextureBake/TextureBakeDecimate.hpp new file mode 100644 index 0000000000..5579778050 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeDecimate.hpp @@ -0,0 +1,68 @@ +#pragma once + +// Quadric error metric decimation (Garland & Heckbert), with two additions that matter on a +// displaced mesh. +// +// Crease quadrics: an interior edge sharper than the threshold gets penalty planes at both endpoints, +// perpendicular to each adjacent face and through the edge, weighted so such edges collapse last or +// not at all. A texture's hard step keeps its geometry while the flat ground around it reduces. +// +// Flat-face harvesting: the loop keeps going past the triangle target while each collapse's error +// stays under an absolute bound, so flat faces that cost nothing to remove are not left behind. + +#include +#include +#include + +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +// Reject a collapse deviating more than about 78 degrees from the old face normal. +static constexpr double DECIMATE_FLIP_DOT = 0.2; +// Edges sharper than 60 degrees are treated as creases. +static constexpr double DECIMATE_CREASE_COS = 0.5; +// Quadric penalty weight for a crease plane. +static constexpr double DECIMATE_CREASE_WEIGHT = 1e4; +// Most faces a collapse may leave around its surviving vertex. Uncapped, a pinned vertex on flat +// ground grows a fan of thousands of slivers, and validating each of its edges walks the whole fan, +// which turns a decimation of a second or two into minutes. At 64 the triangle count moves by about +// 1% at most, and by far less on large bakes. +static constexpr int DECIMATE_MAX_VALENCE = 64; + +// Upper bound in mm on the deviation a harvested collapse may introduce; the real one is smaller, +// since the cost sums squared distances over all incident faces. +// +// Absolute, not relative to the cost at which the target was crossed. A relative band fails in the +// case with the most to shed: when the target is reached with a large flat surplus left, the crossing +// cost is essentially zero, so the band is too and nothing is harvested. +static constexpr double DECIMATE_DEFAULT_HARVEST_TOL = 0.005; + +// Returns false to cancel. +using DecimateProgressFn = std::function; + +struct DecimateResult +{ + TriSoup geometry; + // The locked faces alone met the target, so it was unreachable without touching preserved + // geometry. + bool locked_over_budget = false; + // Reaching the target took a collapse costing more than harvest_tol, so the target removed detail + // and not only flat faces a harvest would have taken anyway. + bool target_cost_detail = false; +}; + +// `locked_faces`: one entry per input triangle; a vertex touching one may neither move nor be +// removed, which also pins the ring between the two regions. +// `face_color`: optional, one entry per input triangle. An edge between two faces of different +// colour is treated as a crease, so the simplified triangles never span a colour boundary and the +// boundary keeps its place - a per-triangle colour read off the result then has nothing to smear. +DecimateResult decimate(const TriSoup &geometry, size_t target_triangles, bool harvest_flat = true, + double harvest_tol = DECIMATE_DEFAULT_HARVEST_TOL, + const std::vector &locked_faces = {}, + const DecimateProgressFn &on_progress = {}, + const std::vector &face_color = {}); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeDisplace.cpp b/src/libslic3r/TextureBake/TextureBakeDisplace.cpp new file mode 100644 index 0000000000..6e306b1c43 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeDisplace.cpp @@ -0,0 +1,285 @@ +#include "TextureBakeDisplace.hpp" + +#include +#include +#include + +#include +#include + +namespace Slic3r { +namespace TextureBake { + +TriSoup apply_displacement(const TriSoup &geometry, const HeightSampleFn &sample, + const DisplaceSettings &settings, const DisplaceBounds &bounds, + const DisplaceProgressFn &on_progress) +{ + TriSoup out; + const size_t count = geometry.pos.size(); + if (count == 0 || !sample) + return geometry; + + out.pos.resize(count); + out.nrm.resize(count); + + // Everything below is keyed by this id, which is what makes one vector per position expressible. + const bool need_id_positions = settings.boundary_falloff > 0.f; + QuantizedPointMap dedup(WELD_GRID_GEOMETRY, std::min(count, size_t(1) << 22)); + std::vector vertex_id(count); + std::vector id_pos; + int next_id = 0; + for (size_t i = 0; i < count; ++i) { + const int id = dedup.get_or_set(geometry.pos[i], next_id); + if (dedup.inserted()) { + ++next_id; + if (need_id_positions) + id_pos.push_back(geometry.pos[i]); + } + vertex_id[i] = id; + } + const size_t unique_count = size_t(next_id); + + // Pass 1: area-weighted smooth normals per position, plus what masking and falloff need. + std::vector smooth_nrm(unique_count, Vec3d::Zero()); + std::vector masked_area(unique_count, 0.0), total_area(unique_count, 0.0); + const bool have_weights = !geometry.exclude_weight.empty(); + std::vector user_excluded_face(have_weights ? count / 3 : 0, 0); + std::vector excluded_pos(have_weights ? unique_count : 0, 0); + + for (size_t t = 0; t + 2 < count; t += 3) { + const Vec3d a = geometry.pos[t].cast(); + const Vec3d face_n = (geometry.pos[t + 1].cast() - a).cross(geometry.pos[t + 2].cast() - a); + const double face_area = face_n.norm(); // twice the triangle area, so weighting is natural + const double nz = face_area > 1e-12 ? face_n.z() / face_area : 0.0; + const double face_angle = std::acos(std::min(1.0, std::abs(nz))) * (180.0 / M_PI); + const bool angle_masked = + nz < 0.0 ? (settings.bottom_angle_limit > 0.f && face_angle <= settings.bottom_angle_limit) + : (settings.top_angle_limit > 0.f && face_angle <= settings.top_angle_limit); + + // Thresholded high, not at a half: merging by maximum leaves a face bordering an excluded one + // with two corners at 1.0, averaging about 0.67, which a half threshold would misread. + bool user_excluded = false; + if (have_weights) { + const float avg = (geometry.exclude_weight[t] + geometry.exclude_weight[t + 1] + + geometry.exclude_weight[t + 2]) / 3.f; + user_excluded = avg > 0.99f; + if (user_excluded) + user_excluded_face[t / 3] = 1; + } + + for (int v = 0; v < 3; ++v) { + const size_t vid = size_t(vertex_id[t + size_t(v)]); + if (user_excluded && have_weights) + excluded_pos[vid] = 1; + // Subdivision split vertices at sharp edges, so these are smooth across soft edges and + // sharp across hard ones - no faceting on round surfaces, no rounding of corners. + smooth_nrm[vid] += geometry.nrm[t + size_t(v)].cast() * face_area; + if (angle_masked) + masked_area[vid] += face_area; + total_area[vid] += face_area; + } + } + + // The pre-normalisation magnitude over the total area says how much the neighbouring faces agree: + // near 1 they do, near 0 they cancelled, meaning a knife edge with no usable surface direction. + std::vector reliability(unique_count, 0.0); + for (size_t id = 0; id < unique_count; ++id) { + const double len = smooth_nrm[id].norm(); + reliability[id] = (len > 0.0 && total_area[id] > 0.0) ? len / total_area[id] : 0.0; + smooth_nrm[id] = (len > 0.0) ? Vec3d(smooth_nrm[id] / len) : Vec3d(0.0, 0.0, 1.0); + } + + // Pass 1.5: the smoothed blend normal - see the header for why it is separate. + std::vector blend_nrm = smooth_nrm; + if (settings.blend_normal_smoothing > 0 && unique_count > 0) { + // CSR adjacency over the welded graph, deliberately a multigraph: duplicates weight a pair by + // how often it shares an edge, so a well-connected surface couples more strongly. + std::vector degree(unique_count, 0); + const auto add_degree = [&](int a, int b) { + if (a != b) { ++degree[size_t(a)]; ++degree[size_t(b)]; } + }; + for (size_t t = 0; t + 2 < count; t += 3) { + const int a = vertex_id[t], b = vertex_id[t + 1], c = vertex_id[t + 2]; + add_degree(a, b); add_degree(b, c); add_degree(c, a); + } + std::vector csr_start(unique_count + 1, 0); + for (size_t id = 0; id < unique_count; ++id) + csr_start[id + 1] = csr_start[id] + degree[id]; + std::vector neighbors(csr_start[unique_count]); + std::vector cursor(unique_count, 0); + const auto add_edge = [&](int a, int b) { + if (a == b) + return; + neighbors[csr_start[size_t(a)] + cursor[size_t(a)]++] = uint32_t(b); + neighbors[csr_start[size_t(b)] + cursor[size_t(b)]++] = uint32_t(a); + }; + for (size_t t = 0; t + 2 < count; t += 3) { + const int a = vertex_id[t], b = vertex_id[t + 1], c = vertex_id[t + 2]; + add_edge(a, b); add_edge(b, c); add_edge(c, a); + } + + std::vector cur = smooth_nrm, nxt(unique_count, Vec3d::Zero()); + for (int iter = 0; iter < settings.blend_normal_smoothing; ++iter) { + // Jacobi, so every vertex reads the previous iteration and the rows are independent. + tbb::parallel_for(tbb::blocked_range(0, unique_count, 4096), [&](const tbb::blocked_range &r) { + for (size_t id = r.begin(); id < r.end(); ++id) { + const uint32_t s = csr_start[id], e = csr_start[id + 1]; + if (e == s) { + nxt[id] = cur[id]; + continue; + } + Vec3d sum = Vec3d::Zero(); + for (uint32_t k = s; k < e; ++k) + sum += cur[neighbors[k]]; + sum /= double(e - s); + const double len = sum.norm(); + // Cancelling neighbours mean a knife edge; keep what we had. + nxt[id] = (len > 1e-12) ? Vec3d(sum / len) : cur[id]; + } + }); + cur.swap(nxt); + } + blend_nrm = std::move(cur); + } + + // A boundary position borders both masked and unmasked faces, or sits on the exclusion seam. + // Every other position gets its distance to the nearest one, ramped to 1 at the falloff distance. + std::vector falloff; + if (settings.boundary_falloff > 0.f && unique_count > 0) { + std::vector boundary; + for (size_t id = 0; id < unique_count; ++id) { + const double frac = total_area[id] > 0.0 ? masked_area[id] / total_area[id] : 0.0; + const bool on_excl = !excluded_pos.empty() && excluded_pos[id] != 0; + if (on_excl || (frac > 0.0 && frac < 1.0)) + boundary.push_back(id_pos[id]); + } + falloff.assign(unique_count, 1.0); + if (!boundary.empty()) { + // A uniform grid: the query is nearest-point only, so a tree costs more than it saves. + Vec3f lo = boundary.front(), hi = boundary.front(); + for (const Vec3f &p : boundary) { + lo = lo.cwiseMin(p); + hi = hi.cwiseMax(p); + } + const Vec3f span = (hi - lo).cwiseMax(Vec3f(1e-6f, 1e-6f, 1e-6f)); + const int res = std::clamp(int(std::ceil(std::cbrt(double(boundary.size())) * 2.0)), 4, 128); + const Vec3f cell = span / float(res); + const float cell_min = cell.minCoeff(); + const auto cell_of = [&](const Vec3f &p) { + Vec3i32 c; + for (int k = 0; k < 3; ++k) + c[k] = std::clamp(int((p[k] - lo[k]) / span[k] * float(res)), 0, res - 1); + return c; + }; + const auto cell_index = [&](int x, int y, int z) { + return size_t(z) * size_t(res) * size_t(res) + size_t(y) * size_t(res) + size_t(x); + }; + std::vector> grid(size_t(res) * size_t(res) * size_t(res)); + for (size_t i = 0; i < boundary.size(); ++i) { + const Vec3i32 c = cell_of(boundary[i]); + grid[cell_index(c.x(), c.y(), c.z())].push_back(int(i)); + } + + const double radius = double(settings.boundary_falloff); + for (size_t id = 0; id < unique_count; ++id) { + const Vec3f &p = id_pos[id]; + const Vec3i32 c = cell_of(p); + double best = std::numeric_limits::max(); + // Anything in shell r is at least (r - 1) cells away, so once the best found is within + // that bound nothing closer can be hiding further out. + for (int r = 0; r < res; ++r) { + for (int dz = -r; dz <= r; ++dz) + for (int dy = -r; dy <= r; ++dy) + for (int dx = -r; dx <= r; ++dx) { + // The shell only; its interior was covered by a smaller r. + if (r > 0 && std::abs(dx) != r && std::abs(dy) != r && std::abs(dz) != r) + continue; + const int qx = c.x() + dx, qy = c.y() + dy, qz = c.z() + dz; + if (qx < 0 || qy < 0 || qz < 0 || qx >= res || qy >= res || qz >= res) + continue; + for (const int bi : grid[cell_index(qx, qy, qz)]) + best = std::min(best, double((boundary[size_t(bi)] - p).norm())); + } + if (best <= double(r) * double(cell_min)) + break; + } + falloff[id] = (best == std::numeric_limits::max() || radius <= 0.0) + ? 1.0 + : std::clamp(best / radius, 0.0, 1.0); + } + } + } + + // Pass 2: one sample per unique position. A representative corner is picked first so the sampling + // itself is a flat parallel loop - it is a texture fetch plus projection maths per layer, and by + // far the most expensive thing in this stage. + std::vector grey(unique_count, 0.0); + std::vector representative(unique_count, -1); + for (size_t i = 0; i < count; ++i) + if (representative[size_t(vertex_id[i])] < 0) + representative[size_t(vertex_id[i])] = int(i); + tbb::parallel_for(tbb::blocked_range(0, unique_count), + [&](const tbb::blocked_range &range) { + for (size_t vid = range.begin(); vid < range.end(); ++vid) { + const int rep = representative[vid]; + if (rep < 0) + continue; + grey[vid] = double(sample(geometry.pos[size_t(rep)], + smooth_nrm[vid].cast(), + blend_nrm[vid].cast())); + } + }); + + // Pass 3: move every copy of a position by the identical vector. Each iteration writes only its + // own output slot, so the loop is independent per corner. + tbb::parallel_for(tbb::blocked_range(0, count), [&](const tbb::blocked_range &range) { + for (size_t i = range.begin(); i < range.end(); ++i) { + const Vec3f &p = geometry.pos[i]; + const size_t vid = size_t(vertex_id[i]); + + // Only angle masking uses the per-position blend, so an excluded face never dims its + // neighbours through a shared vertex. + const bool face_excluded = !user_excluded_face.empty() && user_excluded_face[i / 3] != 0; + // Pinned where an included face shares a position with an excluded one, sealing the boundary. + const bool sealed_boundary = + !face_excluded && !excluded_pos.empty() && excluded_pos[vid] != 0; + const double masked_frac = total_area[vid] > 0.0 ? masked_area[vid] / total_area[vid] : 0.0; + const double centered = settings.symmetric ? (grey[vid] - 0.5) : grey[vid]; + const double ramp = falloff.empty() ? 1.0 : falloff[vid]; + const double disp = (face_excluded || sealed_boundary) + ? 0.0 + : ramp * (1.0 - masked_frac) * centered * double(settings.amplitude); + + Vec3d moved = p.cast() + smooth_nrm[vid] * disp; + + // Stop a partly masked vertex poking through the surface it borders. + if (masked_frac > 0.0) { + if (settings.bottom_angle_limit > 0.f && moved.z() < double(p.z())) moved.z() = double(p.z()); + if (settings.top_angle_limit > 0.f && moved.z() > double(p.z())) moved.z() = double(p.z()); + } + if (settings.no_downward_z && moved.z() < double(p.z())) + moved.z() = double(p.z()); + // A vertex starting on the bottom plane stays there: otherwise a downward-facing face pulls + // *up* where the sample is below mid-grey, leaving bed-contact vertices at differing heights. + if (settings.no_downward_z && double(p.z()) <= double(bounds.min.z()) + 1e-5) + moved.z() = double(p.z()); + + out.pos[i] = moved.cast(); + } + }); + + // Per-face, not averaged across shared positions: averaging can flip an excluded face's normal + // when its neighbours moved outward. + tbb::parallel_for(tbb::blocked_range(0, count / 3), [&](const tbb::blocked_range &r) { + for (size_t f = r.begin(); f < r.end(); ++f) { + const size_t t = f * 3; + const Vec3f n = (out.pos[t + 1] - out.pos[t]).cross(out.pos[t + 2] - out.pos[t]).normalized(); + out.nrm[t] = out.nrm[t + 1] = out.nrm[t + 2] = n; + } + }); + out.exclude_weight = geometry.exclude_weight; + return out; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeDisplace.hpp b/src/libslic3r/TextureBake/TextureBakeDisplace.hpp new file mode 100644 index 0000000000..eee6ca0626 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeDisplace.hpp @@ -0,0 +1,68 @@ +#pragma once + +// Displacement along surface normals. +// +// The mesh is non-indexed, so at a shared edge two triangles hold the same position with different +// face normals; displacing each copy along its own normal sends them to different points and opens a +// crack. So one smooth (area-weighted) normal per unique position drives both the sample lookup and +// the displacement direction, every copy moves by the same vector, and the result is watertight by +// construction. Displaced normals are then smooth at hard edges, but the geometry is still faceted, +// so printed edges stay sharp. + +#include +#include +#include + +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +// Height at a point, called once per unique welded position. `smooth_normal` is the vector the +// displacement will move along; `blend_normal` is that after smoothing, for projection blend weights. +using HeightSampleFn = std::function; + +struct DisplaceSettings +{ + // Displacement height in mm, applied to the sampled value. + float amplitude = 0.4f; + + // Sample around a mid-grey rest level rather than displacing outward only. + bool symmetric = false; + + // Faces flatter than these (degrees from horizontal) are held back, leaving bed-contact and top + // surfaces alone. 0 disables that side. + float bottom_angle_limit = 5.f; + float top_angle_limit = 0.f; + + // Never move a vertex below its original Z, so no new overhang. The sideways component is kept. + bool no_downward_z = false; + + // Distance in mm over which displacement ramps up from a mask boundary. 0 leaves a hard edge. + float boundary_falloff = 0.f; + + // Laplacian iterations on the blend normal only - the displacement direction must stay the exact + // smooth normal or copies of a position move differently and the mesh cracks. Inside a blend band + // the weight gradient is largest, so a few degrees of vertex-to-vertex jitter multiplies the + // difference between two unrelated height samples into visible seam noise. A no-op on an + // already-smooth surface. + int blend_normal_smoothing = 32; +}; + +// Model extents; only the minimum Z is read, for the bottom-plane clamp. +struct DisplaceBounds +{ + Vec3f min = Vec3f::Zero(); + Vec3f max = Vec3f::Zero(); +}; + +// Returns false to cancel. +using DisplaceProgressFn = std::function; + +TriSoup apply_displacement(const TriSoup &geometry, const HeightSampleFn &sample, + const DisplaceSettings &settings, const DisplaceBounds &bounds, + const DisplaceProgressFn &on_progress = {}); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeFlip.cpp b/src/libslic3r/TextureBake/TextureBakeFlip.cpp new file mode 100644 index 0000000000..f4d9997f71 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeFlip.cpp @@ -0,0 +1,212 @@ +#include "TextureBakeFlip.hpp" + +#include +#include +#include +#include + +#include +#include +#include + +namespace Slic3r { +namespace TextureBake { + +FlipResult flip_edges_to_height(const TriSoup &geometry, const std::vector &face_parent_id, + const HeightSampleFn &sample, const FlipSettings &settings, + const std::vector &locked) +{ + FlipResult result; + result.geometry = geometry; + result.face_parent_id = face_parent_id; + const size_t count = geometry.pos.size(); + const size_t tri_ct = count / 3; + if (count == 0 || !sample || settings.passes <= 0) + return result; + + // Weld, so a flip rewrites triangles in terms of shared vertices rather than positions. + QuantizedPointMap weld(WELD_GRID_GEOMETRY, std::min(count, size_t(1) << 22)); + std::vector vid(count); + std::vector pos; + std::vector weight; // exclude weight per unique vertex, the max over its copies + const bool has_weight = !geometry.exclude_weight.empty(); + for (size_t i = 0; i < count; ++i) { + vid[i] = weld.get_or_set(geometry.pos[i], int(pos.size())); + if (weld.inserted()) { + pos.push_back(geometry.pos[i]); + weight.push_back(has_weight ? geometry.exclude_weight[i] : 0.f); + } else if (has_weight) { + weight[size_t(vid[i])] = std::max(weight[size_t(vid[i])], geometry.exclude_weight[i]); + } + } + const size_t nv = pos.size(); + + // Triangles as vertex ids; a locked or excluded triangle never takes part. + std::vector> tri(tri_ct); + std::vector fixed(tri_ct, 0); + for (size_t t = 0; t < tri_ct; ++t) { + tri[t] = { vid[t * 3], vid[t * 3 + 1], vid[t * 3 + 2] }; + if (!locked.empty() && t < locked.size() && locked[t]) + fixed[t] = 1; + if (has_weight && geometry.exclude_weight[t * 3] > 0.99f) + fixed[t] = 1; + } + + // Height per unique vertex along its area-weighted normal, the direction displacement will use. + std::vector nrm(nv, Vec3f::Zero()); + std::vector face_n(tri_ct); + const auto rebuild_normals = [&]() { + std::fill(nrm.begin(), nrm.end(), Vec3f::Zero()); + for (size_t t = 0; t < tri_ct; ++t) { + const Vec3f fn = (pos[size_t(tri[t][1])] - pos[size_t(tri[t][0])]).cross(pos[size_t(tri[t][2])] - pos[size_t(tri[t][0])]); + face_n[t] = fn; + for (int k = 0; k < 3; ++k) + nrm[size_t(tri[t][size_t(k)])] += fn; + } + for (Vec3f &n : nrm) { + const float l = n.norm(); + n = (l > 0.f) ? Vec3f(n / l) : Vec3f(0.f, 0.f, 1.f); + } + }; + rebuild_normals(); + std::vector h(nv, 0.f); + tbb::parallel_for(tbb::blocked_range(0, nv), [&](const tbb::blocked_range &r) { + for (size_t v = r.begin(); v < r.end(); ++v) + h[v] = sample(pos[v], nrm[v], nrm[v]); + }); + float h_lo = std::numeric_limits::max(), h_hi = -h_lo; + for (const float x : h) { h_lo = std::min(h_lo, x); h_hi = std::max(h_hi, x); } + const float range = h_hi - h_lo; + if (!(range > 0.f)) + return result; // flat: every diagonal is as good as the other + const float min_gain = float(settings.min_gain_fraction) * range; + const float planar = float(settings.min_planar_cos); + + struct Candidate + { + uint32_t t1, t2; // the two triangles + uint8_t k1, k2; // corner index in each where the shared edge starts (t1: a->c, t2: c->a) + float gain; + }; + + for (int pass = 0; pass < settings.passes; ++pass) { + // Half-edges keyed by their undirected edge, sorted so the two halves of an interior edge land + // next to each other; a run of exactly two with opposite directions is a manifold interior + // edge. Sorting beats hashing here by an order of magnitude on a few million triangles. + struct Half { uint64_t key; uint32_t corner; }; + std::vector half; + half.reserve(count); + for (size_t t = 0; t < tri_ct; ++t) + for (int k = 0; k < 3; ++k) { + const int from = tri[t][size_t(k)], to = tri[t][size_t((k + 1) % 3)]; + if (from == to) continue; + const uint32_t lo = uint32_t(std::min(from, to)), hi = uint32_t(std::max(from, to)); + half.push_back({ (uint64_t(lo) << 32) | hi, uint32_t(t * 3 + size_t(k)) }); + } + tbb::parallel_sort(half.begin(), half.end(), [](const Half &x, const Half &y) { + return x.key != y.key ? x.key < y.key : x.corner < y.corner; + }); + std::vector> edges; // (corner in t1, corner in t2), t1 < t2 + edges.reserve(half.size() / 2); + for (size_t i = 0; i < half.size();) { + size_t j = i + 1; + while (j < half.size() && half[j].key == half[i].key) ++j; + if (j - i == 2) { + // Opposite directions: the lower vertex id is `from` in exactly one of the two. + const uint32_t c1 = half[i].corner, c2 = half[i + 1].corner; + const int f1 = tri[c1 / 3][size_t(c1 % 3)], f2 = tri[c2 / 3][size_t(c2 % 3)]; + if (f1 != f2) + edges.emplace_back(c1, c2); + } + i = j; + } + std::vector cands(edges.size()); + std::vector valid(edges.size(), 0); + tbb::parallel_for(tbb::blocked_range(0, edges.size()), [&](const tbb::blocked_range &r) { + for (size_t i = r.begin(); i < r.end(); ++i) { + const uint32_t c1 = uint32_t(edges[i].first), c2 = uint32_t(edges[i].second); + const uint32_t t1 = c1 / 3, t2 = c2 / 3; + const int k1 = int(c1 % 3), k2 = int(c2 % 3); + if (fixed[t1] || fixed[t2]) continue; + if (!face_parent_id.empty() && face_parent_id[t1] != face_parent_id[t2]) continue; + // a->c is the shared edge in t1, with b opposite; t2 runs c->a with d opposite. + const int a = tri[t1][size_t(k1)], c = tri[t1][size_t((k1 + 1) % 3)], b = tri[t1][size_t((k1 + 2) % 3)]; + const int d = tri[t2][size_t((k2 + 2) % 3)]; + if (b == d) continue; + // Level quads have nothing to gain; the test is on the corners, before any sampling. + const float hmin = std::min({ h[size_t(a)], h[size_t(b)], h[size_t(c)], h[size_t(d)] }); + const float hmax = std::max({ h[size_t(a)], h[size_t(b)], h[size_t(c)], h[size_t(d)] }); + if (hmax - hmin < min_gain) continue; + // Coplanar enough to have a real alternative, and convex so the alternative is valid: + // the new triangles (a, d, b) and (d, c, b) must both face the way the quad does, with + // a decent share of its area. + const Vec3f n1 = face_n[t1], n2 = face_n[t2]; + const float l1 = n1.norm(), l2 = n2.norm(); + if (l1 <= 0.f || l2 <= 0.f || n1.dot(n2) < planar * l1 * l2) continue; + const Vec3f quad_n = (n1 + n2).normalized(); + const Vec3f &pa = pos[size_t(a)], &pb = pos[size_t(b)], &pc = pos[size_t(c)], &pd = pos[size_t(d)]; + const Vec3f m1 = (pd - pa).cross(pb - pa), m2 = (pc - pd).cross(pb - pd); + const float area_old = l1 + l2, area_new = m1.dot(quad_n) + m2.dot(quad_n); + const float min_part = 0.05f * area_old; + if (m1.dot(quad_n) < min_part || m2.dot(quad_n) < min_part) continue; + if (std::abs(area_new - area_old) > 0.02f * area_old) continue; // not the same quad: folded + // The diagonals' midpoint errors. + const auto mid_err = [&](int u, int w) { + const Vec3f p = 0.5f * (pos[size_t(u)] + pos[size_t(w)]); + Vec3f n = nrm[size_t(u)] + nrm[size_t(w)]; + const float l = n.norm(); + n = (l > 0.f) ? Vec3f(n / l) : quad_n; + return std::abs(sample(p, n, n) - 0.5f * (h[size_t(u)] + h[size_t(w)])); + }; + const float gain = mid_err(a, c) - mid_err(b, d); + if (gain < min_gain) continue; + cands[i] = { t1, t2, uint8_t(k1), uint8_t(k2), gain }; + valid[i] = 1; + } + }); + std::vector chosen; + for (size_t i = 0; i < cands.size(); ++i) + if (valid[i]) chosen.push_back(cands[i]); + std::sort(chosen.begin(), chosen.end(), [](const Candidate &x, const Candidate &y) { + return x.gain != y.gain ? x.gain > y.gain : (x.t1 != y.t1 ? x.t1 < y.t1 : x.t2 < y.t2); + }); + // Best first, and a triangle changes at most once per pass. + std::vector touched(tri_ct, 0); + size_t applied = 0; + for (const Candidate &cd : chosen) { + if (touched[cd.t1] || touched[cd.t2]) continue; + const int a = tri[cd.t1][cd.k1], c = tri[cd.t1][size_t((cd.k1 + 1) % 3)], b = tri[cd.t1][size_t((cd.k1 + 2) % 3)]; + const int d = tri[cd.t2][size_t((cd.k2 + 2) % 3)]; + tri[cd.t1] = { a, d, b }; + tri[cd.t2] = { d, c, b }; + touched[cd.t1] = touched[cd.t2] = 1; + ++applied; + } + result.flipped += applied; + if (applied == 0) + break; + rebuild_normals(); // face normals feed the planarity test of the next pass + } + + if (result.flipped == 0) + return result; + + // Back to the soup: positions, weights and per-face normals from the (possibly rewritten) triangles. + for (size_t t = 0; t < tri_ct; ++t) { + for (int k = 0; k < 3; ++k) { + const size_t i = t * 3 + size_t(k); + const int v = tri[t][size_t(k)]; + result.geometry.pos[i] = pos[size_t(v)]; + if (has_weight) + result.geometry.exclude_weight[i] = weight[size_t(v)]; + } + Vec3f n = (result.geometry.pos[t * 3 + 1] - result.geometry.pos[t * 3]).cross(result.geometry.pos[t * 3 + 2] - result.geometry.pos[t * 3]); + const float len = n.norm(); + n = (len > 0.f) ? Vec3f(n / len) : Vec3f(0.f, 0.f, 1.f); + result.geometry.nrm[t * 3] = result.geometry.nrm[t * 3 + 1] = result.geometry.nrm[t * 3 + 2] = n; + } + return result; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeFlip.hpp b/src/libslic3r/TextureBake/TextureBakeFlip.hpp new file mode 100644 index 0000000000..02701bbced --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeFlip.hpp @@ -0,0 +1,57 @@ +#pragma once + +// Data-dependent edge flipping: choose each quad's diagonal to follow the height field, before any +// displacement happens. +// +// Refinement produces a regular grid, and a step in the height map that crosses that grid at an +// angle lands on alternating corners: one triangle of a quad gets a raised corner, the next does not, +// and the displaced wall comes out as a sawtooth the size of the grid. Finer triangles make the teeth +// smaller, never straight. The cause is the diagonal, not the density: with the diagonal running +// along the step both triangles of the quad sit cleanly on one side or the other, and the wall is a +// straight line between them. +// +// So, for every interior edge, compare the two diagonals of the quad it spans by how well each +// interpolates the field at its own midpoint - the sampled height there against the mean of its two +// endpoints - and keep the better one. A quad whose four corners are level is skipped outright, so +// flat regions cost nothing; a non-planar quad (a model crease) is never touched, nor is one whose +// triangles belong to different source faces or straddle the painted boundary. + +#include +#include + +#include "TextureBakeDisplace.hpp" +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +struct FlipSettings +{ + // Passes over all edges. Flips interact through shared triangles, so a pass applies non-conflicting + // ones and the next pass picks up the rest; two or three settle a grid. + int passes = 3; + + // A flip has to reduce the midpoint error by at least this fraction of the height range, so noise + // on a rough surface does not toggle diagonals for nothing. + double min_gain_fraction = 0.02; + + // The two triangles have to be this coplanar (cosine of their normals' angle) for the quad to have + // a meaningful alternative diagonal at all: across a real crease there is none. + double min_planar_cos = 0.985; // ~10 degrees +}; + +struct FlipResult +{ + TriSoup geometry; + std::vector face_parent_id; + size_t flipped = 0; +}; + +// `face_parent_id` may be empty; when given it is carried through unchanged (a flip never crosses a +// parent boundary). `locked` flags triangles that must not change (per triangle, may be empty). +FlipResult flip_edges_to_height(const TriSoup &geometry, const std::vector &face_parent_id, + const HeightSampleFn &sample, const FlipSettings &settings, + const std::vector &locked); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeIndex.cpp b/src/libslic3r/TextureBake/TextureBakeIndex.cpp new file mode 100644 index 0000000000..ac7234774b --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeIndex.cpp @@ -0,0 +1,25 @@ +#include "TextureBakeIndex.hpp" + +#include + +namespace Slic3r { +namespace TextureBake { + +WeldResult weld_vertices(const std::vector &positions, double quant) +{ + WeldResult out; + QuantizedPointMap map(quant, std::min(positions.size(), size_t(1) << 22)); + out.vertex_id.resize(positions.size()); + int next_id = 0; + for (size_t i = 0; i < positions.size(); ++i) { + const int id = map.get_or_set(positions[i], next_id); + if (map.inserted()) + ++next_id; + out.vertex_id[i] = id; + } + out.unique_count = next_id; + return out; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeIndex.hpp b/src/libslic3r/TextureBake/TextureBakeIndex.hpp new file mode 100644 index 0000000000..2b1dd72395 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeIndex.hpp @@ -0,0 +1,158 @@ +#pragma once + +// Vertex welding for the texture bake pipeline. The pipeline works on non-indexed triangle soup, so +// a shared point exists once per incident triangle with float noise between the copies; welding maps +// each quantised position to one integer id. +// +// The three grids below are deliberately not unified - changing one at a call site changes +// watertightness. 100 um matches the precision files are written with; 10 um keeps small fillet +// vertices distinct (they merge at 100 um, giving needle artifacts after displacement) while still +// absorbing float noise; 1 um is what collapse positioning needs. + +#include +#include +#include +#include + +#include "../Point.hpp" + +namespace Slic3r { +namespace TextureBake { + +static constexpr double WELD_GRID_EXPORT = 1e4; // 100 um +static constexpr double WELD_GRID_GEOMETRY = 1e5; // 10 um +static constexpr double WELD_GRID_DECIMATION = 1e6; // 1 um + +// Round half toward positive infinity. Quantised coordinates hit exact halves often enough that the +// tie rule matters. +inline int64_t grid_round(double v) { return int64_t(std::floor(v + 0.5)); } + +// Open-addressing table, linear probing: no allocation per lookup, exact integer key comparison. +// Values must be non-negative; -1 is the empty sentinel and what get() returns on a miss. +// +// Key and value live together in one 32-byte cell. They used to be four parallel arrays, which made a +// single probe touch four cache lines - and probing this table was 13% of a whole bake, because every +// stage welds the full soup through it. +class QuantizedPointMap +{ +public: + explicit QuantizedPointMap(double quant, size_t expected = 256) : m_quant(quant) + { + size_t cap = 16; + const size_t target = std::max(16, size_t(std::ceil(double(expected) / 0.6))); + while (cap < target) + cap *= 2; + alloc(cap); + } + + size_t size() const { return m_size; } + // Whether the last get_or_set() inserted rather than found. + bool inserted() const { return m_inserted; } + + int get(float x, float y, float z) + { + return m_cells[slot(grid_round(double(x) * m_quant), grid_round(double(y) * m_quant), + grid_round(double(z) * m_quant))].val; + } + int get(const Vec3f &p) { return get(p.x(), p.y(), p.z()); } + + // The value already stored for this position's grid cell; if there is none, store `value` and + // return it. inserted() then says which of the two happened. + int get_or_set(float x, float y, float z, int value) + { + return get_or_set_key(grid_round(double(x) * m_quant), grid_round(double(y) * m_quant), + grid_round(double(z) * m_quant), value); + } + int get_or_set(const Vec3f &p, int value) { return get_or_set(p.x(), p.y(), p.z(), value); } + + // The same table as a set of integer tuples (edge marking, midpoint cache). Quantisation is + // bypassed: routing ids through the float overloads loses precision above 2^24. + int get_key(int64_t a, int64_t b, int64_t c) { return m_cells[slot(a, b, c)].val; } + int get_or_set_key(int64_t a, int64_t b, int64_t c, int value) + { + const size_t i = slot(a, b, c); + Cell &cell = m_cells[i]; + if (cell.val != -1) { + m_inserted = false; + return cell.val; + } + cell.qx = a; cell.qy = b; cell.qz = c; + cell.val = value; + m_inserted = true; + if (++m_size > size_t(double(m_cap) * 0.7)) + grow(); + return value; + } + +private: + struct Cell + { + int64_t qx = 0, qy = 0, qz = 0; + int32_t val = -1; + }; + + void alloc(size_t cap) + { + m_cap = cap; + m_mask = cap - 1; + m_cells.assign(cap, Cell{}); + } + + size_t slot(int64_t qx, int64_t qy, int64_t qz) const + { + // Unsigned multiplies: the signed versions overflowed on nearly every key, which is undefined + // behaviour. The resulting bits are identical on every target OrcaSlicer builds for. + // + // A stronger 64-bit finalizer was tried and measured no faster - the probing that shows up in a + // profile is subdivide's parallel mark count, spread over every core, not long probe chains. + uint32_t h = (uint32_t(qx) * 0x9E3779B1u) ^ (uint32_t(qy) * 0x85EBCA77u) ^ (uint32_t(qz) * 0xC2B2AE3Du); + h ^= h >> 15; + size_t i = size_t(h) & m_mask; + // Equality is checked against the stored 64-bit keys, so truncating to 32 bits for the hash + // costs collisions at worst, never a wrong answer. + while (m_cells[i].val != -1) { + const Cell &c = m_cells[i]; + if (c.qx == qx && c.qy == qy && c.qz == qz) + return i; + i = (i + 1) & m_mask; + } + return i; + } + + void grow() + { + std::vector old = std::move(m_cells); + alloc(m_cap * 2); + for (const Cell &c : old) + if (c.val != -1) + m_cells[slot(c.qx, c.qy, c.qz)] = c; + } + + double m_quant; + size_t m_cap = 0, m_mask = 0, m_size = 0; + bool m_inserted = false; + std::vector m_cells; +}; + +// Three consecutive entries per triangle. The indexers turn this into shared vertices where a stage +// needs adjacency. +struct TriSoup +{ + std::vector pos; + std::vector nrm; // parallel to pos + std::vector exclude_weight; // parallel to pos; empty when nothing is excluded + + size_t triangle_count() const { return pos.size() / 3; } + bool empty() const { return pos.empty(); } +}; + +// Assign each vertex the sequential id of its quantised position, first occurrence winning. +struct WeldResult +{ + std::vector vertex_id; + int unique_count = 0; +}; +WeldResult weld_vertices(const std::vector &positions, double quant); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeMesh.cpp b/src/libslic3r/TextureBake/TextureBakeMesh.cpp new file mode 100644 index 0000000000..6f6d72218d --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeMesh.cpp @@ -0,0 +1,62 @@ +#include "TextureBakeMesh.hpp" + +#include + +namespace Slic3r { +namespace TextureBake { + +TriSoup to_soup(const indexed_triangle_set &its, const std::vector &face_excluded) +{ + TriSoup out; + const size_t n = its.indices.size(); + out.pos.resize(n * 3); + out.nrm.resize(n * 3); + const bool have_excl = face_excluded.size() == n; + if (have_excl) + out.exclude_weight.resize(n * 3); + + for (size_t t = 0; t < n; ++t) { + const stl_triangle_vertex_indices &tri = its.indices[t]; + const Vec3f a = its.vertices[size_t(tri[0])]; + const Vec3f b = its.vertices[size_t(tri[1])]; + const Vec3f c = its.vertices[size_t(tri[2])]; + Vec3f nrm = (b - a).cross(c - a); + const float len = nrm.norm(); + nrm = (len > 0.f) ? Vec3f(nrm / len) : Vec3f(0.f, 0.f, 1.f); + out.pos[t * 3] = a; + out.pos[t * 3 + 1] = b; + out.pos[t * 3 + 2] = c; + // Per-face on purpose: the accurate indexer derives smooth normals and splits at sharp edges + // itself, so averaged ones would pre-empt that. + out.nrm[t * 3] = out.nrm[t * 3 + 1] = out.nrm[t * 3 + 2] = nrm; + if (have_excl) { + const float w = face_excluded[t] ? 1.f : 0.f; + out.exclude_weight[t * 3] = out.exclude_weight[t * 3 + 1] = out.exclude_weight[t * 3 + 2] = w; + } + } + return out; +} + +indexed_triangle_set to_indexed_triangle_set(const TriSoup &soup) +{ + indexed_triangle_set out; + const size_t n = soup.pos.size(); + out.indices.reserve(n / 3); + QuantizedPointMap map(WELD_GRID_GEOMETRY, std::min(n, size_t(1) << 22)); + std::vector id(n); + for (size_t i = 0; i < n; ++i) { + id[i] = map.get_or_set(soup.pos[i], int(out.vertices.size())); + if (map.inserted()) + out.vertices.push_back(soup.pos[i]); + } + for (size_t t = 0; t + 2 < n; t += 3) { + // Welded-together corners carry no area. + if (id[t] == id[t + 1] || id[t + 1] == id[t + 2] || id[t] == id[t + 2]) + continue; + out.indices.emplace_back(id[t], id[t + 1], id[t + 2]); + } + return out; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeMesh.hpp b/src/libslic3r/TextureBake/TextureBakeMesh.hpp new file mode 100644 index 0000000000..b4e3ced5fe --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeMesh.hpp @@ -0,0 +1,19 @@ +#pragma once + +// Conversion between the pipeline's triangle soup and the indexed mesh used elsewhere. The pipeline +// stays on soup because each stage welds on its own grid, and those differences are load-bearing. + +#include "TextureBakeIndex.hpp" +#include "../TriangleMesh.hpp" + +namespace Slic3r { +namespace TextureBake { + +// `face_excluded`: one entry per input triangle, becoming the soup's per-corner exclusion weight. +TriSoup to_soup(const indexed_triangle_set &its, const std::vector &face_excluded = {}); + +// Welds at the geometry grid. +indexed_triangle_set to_indexed_triangle_set(const TriSoup &soup); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakePipeline.cpp b/src/libslic3r/TextureBake/TextureBakePipeline.cpp new file mode 100644 index 0000000000..2b678905b1 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakePipeline.cpp @@ -0,0 +1,375 @@ +#include "TextureBakePipeline.hpp" + +#include +#include + +#include "TextureBakeDebug.hpp" + +#include +#include +#include +#include + +#include + +namespace Slic3r { +namespace TextureBake { + +void clamp_below_bottom(TriSoup &geometry, float bottom_z) +{ + for (size_t t = 0; t + 2 < geometry.pos.size(); t += 3) { + bool dirty = false; + for (int k = 0; k < 3; ++k) + if (geometry.pos[t + size_t(k)].z() < bottom_z) { + geometry.pos[t + size_t(k)].z() = bottom_z; + dirty = true; + } + if (!dirty) + continue; + Vec3f n = (geometry.pos[t + 1] - geometry.pos[t]).cross(geometry.pos[t + 2] - geometry.pos[t]); + const float len = n.norm(); + n = (len > 0.f) ? Vec3f(n / len) : Vec3f(0.f, 0.f, 1.f); + geometry.nrm[t] = geometry.nrm[t + 1] = geometry.nrm[t + 2] = n; + } +} + +size_t snap_bottom_to_flat(TriSoup &geometry, float bottom_z, double tol) +{ + const size_t vert_count = geometry.pos.size(); + const size_t tri_count = vert_count / 3; + if (tri_count == 0 || tol <= 0.0) + return 0; + + // Weld at the finest grid: by this point copies of one position are bit-identical, because every + // earlier stage moved them by the same vector. + QuantizedPointMap weld(WELD_GRID_DECIMATION, std::min(vert_count, size_t(1) << 22)); + std::vector vid(vert_count); + int unique = 0; + for (size_t i = 0; i < vert_count; ++i) { + vid[i] = weld.get_or_set(geometry.pos[i], unique); + if (weld.inserted()) + ++unique; + } + // Incident corners per position, CSR style. + std::vector start(size_t(unique) + 1, 0); + for (size_t i = 0; i < vert_count; ++i) + ++start[size_t(vid[i]) + 1]; + for (size_t id = 0; id < size_t(unique); ++id) + start[id + 1] += start[id]; + std::vector inc(vert_count), cursor(size_t(unique), 0); + for (size_t i = 0; i < vert_count; ++i) + inc[start[size_t(vid[i])] + cursor[size_t(vid[i])]++] = uint32_t(i); + + const double fold_cos = std::cos(75.0 * M_PI / 180.0); + std::vector dirty_tri(tri_count, 0); + + for (size_t id = 0; id < size_t(unique); ++id) { + const float z = geometry.pos[inc[start[id]]].z(); + if (z == bottom_z || std::abs(double(z) - double(bottom_z)) > tol) + continue; + + // Simulate the move: every incident triangle must keep positive area and must not fold. + bool ok = true; + for (uint32_t k = start[id]; k < start[id + 1] && ok; ++k) { + const size_t t = size_t(inc[k]) / 3; + Vec3f p[3]; + for (int v = 0; v < 3; ++v) { + p[v] = geometry.pos[t * 3 + size_t(v)]; + if (vid[t * 3 + size_t(v)] == int(id)) + p[v].z() = bottom_z; + } + const Vec3d on = (geometry.pos[t * 3 + 1] - geometry.pos[t * 3]) + .cross(geometry.pos[t * 3 + 2] - geometry.pos[t * 3]).cast(); + const Vec3d nn = (p[1] - p[0]).cross(p[2] - p[0]).cast(); + const double o2 = on.squaredNorm(), n2 = nn.squaredNorm(); + if (n2 < 1e-20) { ok = false; break; } // would collapse to zero area + if (o2 < 1e-20) continue; // already degenerate, cannot judge a rotation + const double dot = on.dot(nn); + if (dot < 0.0 || dot * dot < fold_cos * fold_cos * o2 * n2) + ok = false; + } + if (!ok) + continue; + + for (uint32_t k = start[id]; k < start[id + 1]; ++k) { + geometry.pos[inc[k]].z() = bottom_z; + dirty_tri[size_t(inc[k]) / 3] = 1; + } + } + + size_t dirty = 0; + for (size_t t = 0; t < tri_count; ++t) { + if (!dirty_tri[t]) + continue; + ++dirty; + Vec3f n = (geometry.pos[t * 3 + 1] - geometry.pos[t * 3]) + .cross(geometry.pos[t * 3 + 2] - geometry.pos[t * 3]); + const float len = n.norm(); + n = (len > 0.f) ? Vec3f(n / len) : Vec3f(0.f, 0.f, 1.f); + geometry.nrm[t * 3] = geometry.nrm[t * 3 + 1] = geometry.nrm[t * 3 + 2] = n; + } + return dirty; +} + +PipelineResult run_pipeline(const TriSoup &input, const HeightSampleFn &sample, + const PipelineSettings &settings, const DisplaceBounds &bounds, + PipelineMode mode, const std::vector &face_excluded, + const PipelineProgressFn &on_progress, BakeStageRecorder *debug, + const ColorSampleFn &color_sample) +{ + PipelineResult result; + const auto report = [&](const char *stage, double f) { + return !on_progress || on_progress(stage, f); + }; + // Per-stage wall time. The stages differ in cost by orders of magnitude depending on the model, so + // without this it is guesswork which one to attack. + auto clock_now = [] { return std::chrono::steady_clock::now(); }; + auto t_stage = clock_now(); + // One call site for both the log line and the debug capture, so a stage cannot appear in one and + // be missing from the other. The capture happens after the elapsed time is read: welding the soup + // and scanning its edges costs more than some of the stages do, and must not land inside the + // measurement it is reporting. + const auto lap = [&](const char *stage, const TriSoup &geometry, const std::string &detail = {}) { + const double ms = std::chrono::duration(clock_now() - t_stage).count(); + BOOST_LOG_TRIVIAL(info) << "TextureBake " << stage << ": " << ms << " ms, " + << geometry.triangle_count() << " tris"; + if (debug != nullptr) + debug->capture(stage, geometry, ms, detail); + t_stage = clock_now(); + }; + + if (input.empty() || !sample) { + result.geometry = input; + return result; + } + if (debug != nullptr) + debug->capture("input", input, 0.0, "as handed to the pipeline"); + t_stage = clock_now(); // the capture above is not part of the first stage + + // 1. Refine to the target edge length. + SubdivideResult sub = subdivide( + input, settings.refine_length, face_excluded, /* fast */ false, settings.safety_cap, + [&](double f, size_t, double) { return report("subdivide", f); }, settings.paint_within); + result.safety_cap_hit = sub.safety_cap_hit; + lap("subdivide", sub.geometry); + if (!report("subdivide", 1.0)) { + result.canceled = true; + return result; + } + + // 2. Dissolve the slivers refinement inherited, then recover the edges that lengthened. + if (settings.regularize) { + RegularizeOptions ropts = settings.regularize_opts; + ropts.preserve_excluded = settings.preserve_untextured; + RegularizeResult reg = regularize_mesh(sub.geometry, sub.face_parent_id, + settings.refine_length, ropts); + result.collapse_count = reg.collapse_count; + lap("regularize", reg.geometry, std::to_string(reg.collapse_count) + " collapses"); + if (!report("regularize", 1.0)) { + result.canceled = true; + return result; + } + if (reg.collapse_count > 0) { + // Excluded faces are carried on the soup itself, so the flag is re-derived rather than + // indexed across the collapse. + std::vector excl; + if (!reg.geometry.exclude_weight.empty()) { + excl.assign(reg.geometry.triangle_count(), 0); + for (size_t t = 0; t < excl.size(); ++t) + excl[t] = reg.geometry.exclude_weight[t * 3] > 0.99f ? 1 : 0; + } + sub = subdivide(reg.geometry, settings.refine_length * settings.regularize_second_pass_mul, + excl, false, settings.safety_cap, + [&](double f, size_t, double) { return report("re-subdivide", f); }, + settings.paint_within); + result.safety_cap_hit = result.safety_cap_hit || sub.safety_cap_hit; + // The second pass renumbers faces, so the parent map has to be composed through it. + std::vector composed(sub.face_parent_id.size()); + for (size_t i = 0; i < composed.size(); ++i) { + const int mid = sub.face_parent_id[i]; + composed[i] = (mid >= 0 && size_t(mid) < reg.face_parent_id.size()) + ? reg.face_parent_id[size_t(mid)] : -1; + } + sub.face_parent_id = std::move(composed); + lap("re-subdivide", sub.geometry); + } else { + sub.geometry = std::move(reg.geometry); + sub.face_parent_id = std::move(reg.face_parent_id); + } + } + + // 2b. Paint finer than the input triangles. The caller includes a source triangle when any part of + // it is painted; now that the faces are small, ask once more per face and switch the unpainted + // ones off. They are pinned like the excluded region from here on: their own corners at weight 1, + // and the displacement's boundary sealing pins the stroke's rim on the painted side. + if (settings.painted) { + const size_t nf = sub.geometry.triangle_count(); + const bool have_w = !sub.geometry.exclude_weight.empty(); + std::vector unpainted(nf, 0); + tbb::parallel_for(tbb::blocked_range(0, nf), [&](const tbb::blocked_range &r) { + for (size_t t = r.begin(); t < r.end(); ++t) { + if (have_w && sub.geometry.exclude_weight[t * 3] > 0.99f) + continue; // excluded from the start, never asked + const Vec3f &a = sub.geometry.pos[t * 3], &b = sub.geometry.pos[t * 3 + 1], &c = sub.geometry.pos[t * 3 + 2]; + if (!settings.painted((a + b + c) / 3.f)) + unpainted[t] = 1; + } + }); + size_t switched = 0; + for (size_t t = 0; t < nf; ++t) + switched += unpainted[t]; + if (switched > 0) { + if (sub.geometry.exclude_weight.empty()) + sub.geometry.exclude_weight.assign(sub.geometry.pos.size(), 0.f); + for (size_t t = 0; t < nf; ++t) + if (unpainted[t]) + sub.geometry.exclude_weight[t * 3] = sub.geometry.exclude_weight[t * 3 + 1] = + sub.geometry.exclude_weight[t * 3 + 2] = 1.f; + } + lap("paint", sub.geometry, std::to_string(switched) + " faces switched off"); + if (!report("paint", 1.0)) { + result.canceled = true; + return result; + } + } + + // 3. Align the mesh to the height field's edges, then displace. + if (settings.relocate) { + std::vector locked; + if (settings.preserve_untextured && !sub.geometry.exclude_weight.empty()) { + locked.assign(sub.geometry.triangle_count(), 0); + for (size_t t = 0; t < locked.size(); ++t) + locked[t] = sub.geometry.exclude_weight[t * 3] > 0.99f ? 1 : 0; + } + RelocateResult rel = relocate_to_contours(sub.geometry, sample, settings.relocate_opts, locked); + BOOST_LOG_TRIVIAL(info) << "TextureBake relocate: moved=" << rel.moved + << " rejected=" << rel.rejected; + sub.geometry = std::move(rel.geometry); + lap("relocate", sub.geometry, + "moved " + std::to_string(rel.moved) + ", rejected " + std::to_string(rel.rejected)); + } + + // 3b. Diagonals along the height field's steps, so they displace into straight walls. + if (settings.flip_edges) { + std::vector locked; + if (settings.preserve_untextured && !sub.geometry.exclude_weight.empty()) { + locked.assign(sub.geometry.triangle_count(), 0); + for (size_t t = 0; t < locked.size(); ++t) + locked[t] = sub.geometry.exclude_weight[t * 3] > 0.99f ? 1 : 0; + } + FlipResult fl = flip_edges_to_height(sub.geometry, sub.face_parent_id, sample, settings.flip_opts, locked); + sub.geometry = std::move(fl.geometry); + sub.face_parent_id = std::move(fl.face_parent_id); + lap("align edges", sub.geometry, std::to_string(fl.flipped) + " flips"); + if (!report("align edges", 1.0)) { + result.canceled = true; + return result; + } + } + + TriSoup displaced = apply_displacement(sub.geometry, sample, settings.displace, bounds, + [&](double f) { return report("displace", f); }); + lap("displace", displaced); + if (!report("displace", 1.0)) { + result.canceled = true; + return result; + } + + // 4. Decimate - export only. A bake needs the face-parent map, which a collapse destroys. + std::vector parent = std::move(sub.face_parent_id); + const size_t displaced_before_decimate = displaced.triangle_count(); + if (mode == PipelineMode::Export) { + std::vector locked; + size_t preserved = 0; + { + if (settings.preserve_untextured && !displaced.exclude_weight.empty()) { + locked.assign(displaced.triangle_count(), 0); + // The corner average, as the displacement stage judges it: after the flip stage's + // per-vertex merge an included face touching the excluded region carries one corner + // at weight 1, and must stay free to collapse and to take colour. + for (size_t t = 0; t < locked.size(); ++t) + locked[t] = (displaced.exclude_weight[t * 3] + displaced.exclude_weight[t * 3 + 1] + + displaced.exclude_weight[t * 3 + 2]) / 3.f > 0.99f ? 1 : 0; + // That includes the faces the paint test switched off: the harvest would re-triangulate + // them into long slivers, which a later bake painted there would refine instead of the + // grid the graded refinement left. + preserved = size_t(std::count(locked.begin(), locked.end(), uint8_t(1))); + } + } + // The budget is what this bake may spend on what it refines. Geometry it only preserves - the + // unpainted surface, and on it the relief of an earlier bake - is counted on top of it: charged + // against the same budget, a second bake over a fresh area had to evict the first one's + // triangles to fit, so every bake after the first came out coarser than the one before. + const size_t target = settings.max_triangles + preserved; + const bool over_budget = displaced.triangle_count() > target; + // Flat faces are harvested whether or not the budget bites. Refinement is driven by the target + // edge length alone, so it leaves as fine a mesh over the flat parts of a texture as over its + // detail, and nothing else removes those: under its budget a bake kept every redundant triangle + // unless the budget was lowered until decimation had to run. Only collapses costing less than + // harvest_tol are taken, so this does not reach the relief. + const bool harvest_only = !over_budget && settings.harvest_flat && displaced.triangle_count() > 0; + if (over_budget || harvest_only) { + // Colour per face on the fine mesh, so colour boundaries become creases the collapse + // respects. Excluded (unpainted) faces take no colour. + std::vector face_color; + if (color_sample) { + const size_t nf = displaced.triangle_count(); + face_color.assign(nf, -1); + const bool have_w = !displaced.exclude_weight.empty(); + tbb::parallel_for(tbb::blocked_range(0, nf), [&](const tbb::blocked_range &r) { + for (size_t t = r.begin(); t < r.end(); ++t) { + if (have_w && (displaced.exclude_weight[t * 3] + displaced.exclude_weight[t * 3 + 1] + + displaced.exclude_weight[t * 3 + 2]) / 3.f > 0.99f) + continue; + const Vec3f &a = displaced.pos[t * 3], &b = displaced.pos[t * 3 + 1], &c = displaced.pos[t * 3 + 2]; + face_color[t] = color_sample((a + b + c) / 3.f, displaced.nrm[t * 3]); + } + }); + } + // Harvesting alone is asked for by handing it the count it already has: nothing is then + // over the target, so the loop only ever pops collapses under the tolerance. + const size_t before = displaced.triangle_count(); + DecimateResult dec = decimate(displaced, over_budget ? target : before, settings.harvest_flat, + settings.harvest_tol, locked, + [&](double f) { return report("decimate", f); }, face_color); + result.locked_over_budget = dec.locked_over_budget; + result.budget_limited = result.simplified = dec.target_cost_detail; + displaced = std::move(dec.geometry); + lap("decimate", displaced, over_budget ? "over budget, simplified" : "flat faces harvested"); + BOOST_LOG_TRIVIAL(info) << "TextureBake decimate: " << before << " -> " << displaced.triangle_count() + << (over_budget ? " (budget " : " (flat harvest, budget ") << target << ")"; + parent.clear(); // no longer meaningful + } + result.triangles_refined = displaced_before_decimate; + result.triangles_budget = target; + if (!report("decimate", 1.0)) { + result.canceled = true; + return result; + } + } + + // 5. Flatten the bed-contact surface. + { + const bool clamped = settings.clamp_below_plate || settings.displace.bottom_angle_limit > 0.f; + if (clamped) + clamp_below_bottom(displaced, bounds.min.z()); + size_t snapped = 0; + if (settings.bottom_snap_tol > 0.0) + snapped = snap_bottom_to_flat(displaced, bounds.min.z(), settings.bottom_snap_tol); + if (clamped || settings.bottom_snap_tol > 0.0) + lap("bottom clamp + snap", displaced, std::to_string(snapped) + " triangles snapped flat"); + } + + // 6. Close the T-junctions decimation left behind. Only meaningful when it ran. + if (mode == PipelineMode::Export && parent.empty()) { + displaced = resolve_t_junctions(displaced); + lap("repair", displaced); + } + + result.geometry = std::move(displaced); + result.face_parent_id = std::move(parent); + return result; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakePipeline.hpp b/src/libslic3r/TextureBake/TextureBakePipeline.hpp new file mode 100644 index 0000000000..e230cf0d49 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakePipeline.hpp @@ -0,0 +1,156 @@ +#pragma once + +// The bake pipeline: +// +// subdivide -> [regularize -> re-subdivide] -> [paint test] -> [relocate] -> [flip edges] +// -> displace -> [decimate] -> bottom clamp -> bottom snap -> [resolve T-junctions] +// +// Regularization sits between two subdivisions on purpose: it dissolves the slivers refinement +// inherited, which lengthens some edges past the target, and the second pass brings those back. +// Before any subdivision it would have nothing to work on, since the slivers come from refining a +// needle; after a single pass it would leave the mesh coarser than asked for. +// +// Decimation and repair are export-only - decimation drops the output-to-input face mapping a bake +// needs to carry per-face data forward. + +#include +#include +#include + +#include "TextureBakeDecimate.hpp" +#include "TextureBakeDisplace.hpp" +#include "TextureBakeIndex.hpp" +#include "TextureBakeRegularize.hpp" +#include "TextureBakeFlip.hpp" +#include "TextureBakeRelocate.hpp" +#include "TextureBakeRepair.hpp" +#include "TextureBakeSubdivide.hpp" + +namespace Slic3r { + +// Optional step-by-step capture; see TextureBakeDebug.hpp. A pointer, and forward declared, so the +// pipeline header stays free of the mesh types the recorder converts into. +class BakeStageRecorder; + +namespace TextureBake { + +enum class PipelineMode +{ + // Keeps the face-parent mapping; skips decimation and repair. + Bake, + // The full sequence, including decimation and repair. + Export, +}; + +struct PipelineSettings +{ + // Target edge length for the refinement, in mm. + double refine_length = 1.0; + + // Sliver removal between the two subdivision passes. + bool regularize = true; + RegularizeOptions regularize_opts; + // Slightly above the first pass, so it recovers the edges regularization lengthened instead of + // re-refining what it just merged. + double regularize_second_pass_mul = 1.1; + + // Slide vertices onto the height map's own edges before displacing, so a step lands on a mesh + // edge instead of being quantised to wherever the grid fell. + bool relocate = false; + RelocateSettings relocate_opts; + + // Choose each quad's diagonal to follow the height field before displacing, so a step that crosses + // the grid at an angle comes out as a straight wall instead of a sawtooth. See TextureBakeFlip.hpp. + bool flip_edges = true; + FlipSettings flip_opts; + + DisplaceSettings displace; + + // Optional. Asked once per refined face (its centroid, in the soup's coordinates) after the + // refinement stages and before displacement, for faces whose source triangle was included: + // false marks the face as unpainted (no displacement), so paint finer than the input triangles + // is honoured. Faces excluded from the start are never asked. Called from several threads at + // once, so it must be safe to call concurrently. + std::function painted; + + // Optional. Whether the paint comes within a radius of a point, which grades the refinement (see + // subdivide()): only the paint and its surroundings reach refine_length, and the unpainted surface + // further out stays in whole pieces of its own grid. That is what a later bake painted there + // refines, so it meets the same grid a first bake does. Called from several threads at once. + SubdivideWithinFn paint_within; + + // Export mode only. + // What this bake may spend on what it refines. Geometry it only preserves (see preserve_untextured), + // the unpainted surface and an earlier bake's relief on it, is counted on top of it, so that relief + // does not have to be evicted to fit this one. + size_t max_triangles = 750'000; + // Keep removing zero-cost flat faces past the target. Only applies when decimation runs, i.e. when + // the displaced mesh is over the budget - an under-budget mesh is never decimated. + bool harvest_flat = true; + double harvest_tol = DECIMATE_DEFAULT_HARVEST_TOL; + // Lock the untextured region against both regularization and decimation. + bool preserve_untextured = true; + + // Push anything that displaced below the plate back up to it. Downward movement is otherwise left + // alone, so relief on the underside is kept - only what would sink through the plate is stopped. + bool clamp_below_plate = false; + + // Snap vertices within this of the bottom plane onto it. 0 disables. + double bottom_snap_tol = 0.1; + + int safety_cap = SUBDIVIDE_SAFETY_CAP; +}; + +// Stage name and a fraction within it. Returning false cancels the run. +using PipelineProgressFn = std::function; +// Colour class of a point of the surface (a palette index, -1 for none), for the decimation's +// colour-boundary creases. Only consulted when the mesh is over budget. +using ColorSampleFn = std::function; + +struct PipelineResult +{ + TriSoup geometry; + // Output face -> input face. Empty in Export mode, where decimation invalidates it. + std::vector face_parent_id; + bool safety_cap_hit = false; + bool locked_over_budget = false; + size_t collapse_count = 0; + bool canceled = false; + // What the refinement produced, before decimation, and the count it had to fit into (the budget + // plus the preserved geometry). budget_limited says the refined mesh did not fit without collapsing + // more than flat faces: the result carries less of the texture than the resolution asked for, + // which is what a caller warns about. + size_t triangles_refined = 0; + size_t triangles_budget = 0; + bool budget_limited = false; + // The budget coarsened the mesh, so its triangles are no longer the fine, even ones the refinement + // laid down - they can be as large as the features on them, which a caller that post-processes per + // triangle (the colour despeckle) has to know. Harvesting flat faces does not count: what it + // removes carried nothing. Not the same question as "did a collapse run", which is why + // face_parent_id being empty is no longer used to answer it. + bool simplified = false; +}; + +// `debug`, when given and enabled, receives the mesh after every stage that ran - which is the only +// way to tell which stage a bad result came from, since each one rewrites the whole mesh. +PipelineResult run_pipeline(const TriSoup &input, const HeightSampleFn &sample, + const PipelineSettings &settings, const DisplaceBounds &bounds, + PipelineMode mode, const std::vector &face_excluded = {}, + const PipelineProgressFn &on_progress = {}, + BakeStageRecorder *debug = nullptr, const ColorSampleFn &color_sample = {}); + +// Snap anything that ended below the model's original bottom back up to it. +void clamp_below_bottom(TriSoup &geometry, float bottom_z); + +// Flatten the bed-contact surface by snapping positions within `tol` of the bottom plane onto it. +// +// Gated, not unconditional: an unconditional band snap also flattens the undersides of texture relief +// near the base, folding them coplanar into the bottom face. Folded faces overlap the plate, so edges +// there pick up four incident faces - non-manifold edges and phantom shells on re-import. All copies +// of a position move together, and the move is rejected if any incident triangle would go degenerate +// or rotate more than about 75 degrees. A real bed-contact sliver rotates by a fraction of a degree +// and still snaps. Returns how many triangles moved. +size_t snap_bottom_to_flat(TriSoup &geometry, float bottom_z, double tol = 0.1); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeRegularize.cpp b/src/libslic3r/TextureBake/TextureBakeRegularize.cpp new file mode 100644 index 0000000000..3028d8bee9 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeRegularize.cpp @@ -0,0 +1,393 @@ +#include "TextureBakeRegularize.hpp" + +#include +#include +#include + +#include +#include + +namespace Slic3r { +namespace TextureBake { + +namespace { + +// Vertex-to-triangle lists as intrusive doubly linked lists of corner slots over flat arrays. Slot s +// is corner (triangle * 3 + k), owned by corners[s]. Deleted and moved corners are unlinked, so a +// collapse costs no allocation. +struct SlotLists +{ + std::vector head, next, prev; + + void init(size_t vertex_count, size_t slot_count) + { + head.assign(vertex_count, -1); + next.assign(slot_count, -1); + prev.assign(slot_count, -1); + } + void link(int s, const std::vector &corners) + { + const int v = corners[size_t(s)]; + const int h = head[size_t(v)]; + prev[size_t(s)] = -1; + next[size_t(s)] = h; + if (h != -1) + prev[size_t(h)] = s; + head[size_t(v)] = s; + } + void unlink(int s, const std::vector &corners) + { + const int p = prev[size_t(s)], n = next[size_t(s)]; + if (p != -1) next[size_t(p)] = n; + else head[size_t(corners[size_t(s)])] = n; + if (n != -1) prev[size_t(n)] = p; + } +}; + +} // namespace + +RegularizeResult regularize_mesh(const TriSoup &geometry, const std::vector &face_parent_id, + double max_edge_length, const RegularizeOptions &opts) +{ + RegularizeResult result; + const size_t tri_count = geometry.triangle_count(); + if (tri_count == 0 || max_edge_length <= 0.0) { + result.geometry = geometry; + result.face_parent_id = face_parent_id; + return result; + } + + const double base_max_len_sq = (max_edge_length * opts.slack) * (max_edge_length * opts.slack); + const double aggr_max_len_sq = + (max_edge_length * opts.aggressive_slack) * (max_edge_length * opts.aggressive_slack); + const double extreme_aspect2 = opts.extreme_sliver_aspect * opts.extreme_sliver_aspect; + const double aspect_thr2 = opts.aspect_threshold * opts.aspect_threshold; + + // Double precision: a collapse writes a midpoint back and later collapses read it, so rounding + // would accumulate. + QuantizedPointMap pos_map(WELD_GRID_GEOMETRY, std::min(tri_count * 3, size_t(1) << 22)); + std::vector vert; + std::vector corners(tri_count * 3); + vert.reserve(tri_count); + for (size_t i = 0; i < tri_count * 3; ++i) { + const Vec3f &p = geometry.pos[i]; + const int id = pos_map.get_or_set(p, int(vert.size())); + if (pos_map.inserted()) + vert.push_back(p.cast()); + corners[i] = id; + } + const size_t vert_count = vert.size(); + + std::vector tri_nrm(tri_count, Vec3d::Zero()); + std::vector tri_deleted(tri_count, 0); + result.face_parent_id = face_parent_id; + if (result.face_parent_id.size() != tri_count) + result.face_parent_id.assign(tri_count, 0); + + const auto sq_dist = [&](int a, int b) { return (vert[size_t(a)] - vert[size_t(b)]).squaredNorm(); }; + + const auto recompute_face_normal = [&](size_t t) { + const Vec3d &a = vert[size_t(corners[t * 3])]; + const Vec3d n = (vert[size_t(corners[t * 3 + 1])] - a).cross(vert[size_t(corners[t * 3 + 2])] - a); + const double len = n.norm(); + tri_nrm[t] = (len > 0.0) ? Vec3d(n / len) : Vec3d::Zero(); + }; + for (size_t t = 0; t < tri_count; ++t) + recompute_face_normal(t); + + // Never updated - the normal gate measures against these, so drift cannot compound across rounds. + const std::vector orig_nrm = tri_nrm; + + // Squared thinness, the longest edge over the shortest altitude: + // thinness = lmax / hmin = lmax^2 / (2 * area), so thinness^2 = lmax^4 / |AB x AC|^2 + // + // Not lmax/lmin, which misses what matters here: three near-collinear points can have all edges + // similar, so an edge ratio reports about 2 and the gate skips a triangle with near-zero area + // whose corners sample three unrelated texels. An equilateral scores about 1.15. + const auto tri_aspect_sq = [&](size_t t) -> double { + const Vec3d &a = vert[size_t(corners[t * 3])]; + const Vec3d ab = vert[size_t(corners[t * 3 + 1])] - a; + const Vec3d ac = vert[size_t(corners[t * 3 + 2])] - a; + const Vec3d bc = vert[size_t(corners[t * 3 + 2])] - vert[size_t(corners[t * 3 + 1])]; + const double lmax2 = std::max({ ab.squaredNorm(), ac.squaredNorm(), bc.squaredNorm() }); + const double cross2 = ab.cross(ac).squaredNorm(); + return cross2 > 0.0 ? lmax2 * lmax2 / cross2 : std::numeric_limits::infinity(); + }; + + SlotLists slots; + slots.init(vert_count, tri_count * 3); + for (size_t s = 0; s < tri_count * 3; ++s) + slots.link(int(s), corners); + + // O(1) membership without clearing a set per collapse. + std::vector vert_stamp(vert_count, 0), tri_stamp(tri_count, 0); + uint32_t stamp_gen = 0; + + // Both endpoints of a hard edge are barred from being collapse endpoints, preserving such + // corners exactly while leaving flat-face interiors free. + // + // Skipped when either triangle is an extreme sliver: a sliver's normal is dominated by where its + // far apex sits, so noise pivots it tens of degrees with no feature behind it, and freezing on + // that would lock the very chains this pass exists to dissolve. Genuine features are bordered by + // well-shaped triangles and are unaffected. + std::vector frozen_vert(vert_count, 0); + { + std::vector tri_thin2(tri_count); + for (size_t t = 0; t < tri_count; ++t) + tri_thin2[t] = tri_aspect_sq(t); + QuantizedPointMap edge_seen(1.0, std::min(tri_count * 3, size_t(1) << 22)); + for (size_t t = 0; t < tri_count; ++t) + for (int e = 0; e < 3; ++e) { + const int u = corners[t * 3 + size_t(e)]; + const int v = corners[t * 3 + size_t((e + 1) % 3)]; + const int lo = std::min(u, v), hi = std::max(u, v); + const int other = edge_seen.get_or_set_key(lo, hi, 0, int(t)); + if (edge_seen.inserted()) + continue; + if (tri_thin2[t] > extreme_aspect2 || tri_thin2[size_t(other)] > extreme_aspect2) + continue; + if (tri_nrm[t].dot(tri_nrm[size_t(other)]) < opts.sharp_edge_cos) { + frozen_vert[size_t(u)] = 1; + frozen_vert[size_t(v)] = 1; + } + } + } + + // Exclusion freeze. The weight is constant across a face's corners, so the first one answers. + if (opts.preserve_excluded && !geometry.exclude_weight.empty()) + for (size_t t = 0; t < tri_count; ++t) + if (geometry.exclude_weight[t * 3] > 0.99f) + for (int k = 0; k < 3; ++k) + frozen_vert[size_t(corners[t * 3 + size_t(k)])] = 1; + + std::vector wing_scratch, affected_scratch; + + const auto third_vertex = [&](size_t t, int u, int v) { + const int a = corners[t * 3], b = corners[t * 3 + 1], c = corners[t * 3 + 2]; + if (a != u && a != v) return a; + if (b != u && b != v) return b; + return c; + }; + const auto triangles_sharing_edge = [&](int u, int v) -> std::vector & { + wing_scratch.clear(); + for (int s = slots.head[size_t(u)]; s != -1; s = slots.next[size_t(s)]) { + const size_t t = size_t(s) / 3; + if (tri_deleted[t]) + continue; + if (corners[t * 3] == v || corners[t * 3 + 1] == v || corners[t * 3 + 2] == v) + wing_scratch.push_back(int(t)); + } + return wing_scratch; + }; + + RegularizeRejectStats &stats = result.reject_stats; + + const auto try_collapse = [&](int u, int v) -> bool { + if (u == v) + return false; + if (frozen_vert[size_t(u)] || frozen_vert[size_t(v)]) { ++stats.frozen; return false; } + + // Two wings means a manifold interior edge. + std::vector &wings = triangles_sharing_edge(u, v); + if (wings.size() != 2) { ++stats.wing_count; return false; } + const size_t w0 = size_t(wings[0]), w1 = size_t(wings[1]); + const int apex1 = third_vertex(w0, u, v), apex2 = third_vertex(w1, u, v); + if (apex1 == apex2) { ++stats.folded_apex; return false; } + + // The edge cap loosens if *either* wing is extreme, since the re-subdivision recovers an + // over-long edge. The normal cap needs *both*, which is what protects fillets. + const double w1a = tri_aspect_sq(w0), w2a = tri_aspect_sq(w1); + const bool either_extreme = w1a > extreme_aspect2 || w2a > extreme_aspect2; + const bool both_extreme = w1a > extreme_aspect2 && w2a > extreme_aspect2; + const double eff_max_len_sq = either_extreme ? aggr_max_len_sq : base_max_len_sq; + const double eff_normal_cos = + both_extreme ? opts.aggressive_normal_delta_cos : opts.max_normal_delta_cos; + + // A vertex sharing a triangle with both endpoints, other than the wing apexes, would go + // non-manifold. Stamp one side's neighbours, scan the other against them. + ++stamp_gen; + for (int s = slots.head[size_t(v)]; s != -1; s = slots.next[size_t(s)]) { + const size_t t = size_t(s) / 3; + if (tri_deleted[t]) + continue; + for (int k = 0; k < 3; ++k) + if (const int x = corners[t * 3 + size_t(k)]; x != v) + vert_stamp[size_t(x)] = stamp_gen; + } + for (int s = slots.head[size_t(u)]; s != -1; s = slots.next[size_t(s)]) { + const size_t t = size_t(s) / 3; + if (tri_deleted[t]) + continue; + for (int k = 0; k < 3; ++k) { + const int x = corners[t * 3 + size_t(k)]; + if (x != u && x != v && x != apex1 && x != apex2 && vert_stamp[size_t(x)] == stamp_gen) { + ++stats.link_condition; + return false; + } + } + } + + const Vec3d m = (vert[size_t(u)] + vert[size_t(v)]) * 0.5; + + // Everything using either endpoint; the wings are being deleted. + ++stamp_gen; + affected_scratch.clear(); + for (const int endpoint : { u, v }) + for (int s = slots.head[size_t(endpoint)]; s != -1; s = slots.next[size_t(s)]) { + const size_t t = size_t(s) / 3; + if (tri_deleted[t] || t == w0 || t == w1) + continue; + if (tri_stamp[t] != stamp_gen) { + tri_stamp[t] = stamp_gen; + affected_scratch.push_back(int(t)); + } + } + + // Validate every affected triangle before touching anything. + for (const int ti : affected_scratch) { + const size_t t = size_t(ti); + Vec3d p[3]; + for (int k = 0; k < 3; ++k) { + const int x = corners[t * 3 + size_t(k)]; + p[k] = (x == u || x == v) ? m : vert[size_t(x)]; + } + const double ab2 = (p[1] - p[0]).squaredNorm(); + const double bc2 = (p[2] - p[1]).squaredNorm(); + const double ca2 = (p[0] - p[2]).squaredNorm(); + if (ab2 > eff_max_len_sq || bc2 > eff_max_len_sq || ca2 > eff_max_len_sq) { + ++stats.edge_cap; + return false; + } + const Vec3d n = (p[1] - p[0]).cross(p[2] - p[0]); + const double nlen = n.norm(); + if (nlen <= 0.0) { ++stats.degenerate; return false; } + if ((n / nlen).dot(orig_nrm[t]) < eff_normal_cos) { ++stats.normal_change; return false; } + } + + // Apply: move u to the merged position and redirect every reference to v. + vert[size_t(u)] = m; + for (const size_t w : { w0, w1 }) { + tri_deleted[w] = 1; + for (int k = 0; k < 3; ++k) + slots.unlink(int(w * 3) + k, corners); + } + // A non-wing triangle contains v exactly once, so moving its slots suffices. + for (int s = slots.head[size_t(v)]; s != -1;) { + const int ns = slots.next[size_t(s)]; + slots.unlink(s, corners); + corners[size_t(s)] = u; + slots.link(s, corners); + recompute_face_normal(size_t(s) / 3); + s = ns; + } + for (int s = slots.head[size_t(u)]; s != -1; s = slots.next[size_t(s)]) { + const size_t t = size_t(s) / 3; + if (!tri_deleted[t]) + recompute_face_normal(t); + } + return true; + }; + + // Per-triangle thinness for a round's candidate scan; -1 marks "not a candidate". Scored in + // parallel, since the scan only reads the mesh, then gathered serially in index order. + std::vector round_aspect(tri_count); + for (int round = 0; round < opts.maxrounds; ++round) { + // Rebuilt each round so earlier collapses inform the priorities. + tbb::parallel_for(tbb::blocked_range(0, tri_count), [&](const tbb::blocked_range &r) { + for (size_t t = r.begin(); t < r.end(); ++t) { + round_aspect[t] = -1.0; + if (tri_deleted[t]) + continue; + const int a = corners[t * 3], b = corners[t * 3 + 1], c = corners[t * 3 + 2]; + if (std::min({ sq_dist(a, b), sq_dist(b, c), sq_dist(c, a) }) <= 0.0) + continue; + const double aspect2 = tri_aspect_sq(t); + if (aspect2 >= aspect_thr2) + round_aspect[t] = aspect2; + } + }); + // Worst first; ties keep ascending triangle order so the pass is deterministic. Sorting the + // (thinness, triangle) pairs themselves gives exactly the order the index sort with its + // indirect comparator did, without that comparator's extra lookup on every comparison. + std::vector> cand; + for (size_t t = 0; t < tri_count; ++t) + if (round_aspect[t] >= 0.0) + cand.emplace_back(round_aspect[t], int(t)); + std::sort(cand.begin(), cand.end(), [](const std::pair &x, const std::pair &y) { + return x.first != y.first ? x.first > y.first : x.second < y.second; + }); + + size_t round_collapses = 0; + for (const std::pair &entry : cand) { + const size_t t = size_t(entry.second); + if (tri_deleted[t]) + continue; + const int a = corners[t * 3], b = corners[t * 3 + 1], c = corners[t * 3 + 2]; + // All three edges, shortest first: a sliver straddling a seam has its shortest edge + // crossing it, which the normal gate refuses, while a long edge along one surface + // collapses safely. Trying only the shortest would leave those stuck. + struct Cand { double len2; int u, v; }; + Cand e[3] = { { sq_dist(a, b), a, b }, { sq_dist(b, c), b, c }, { sq_dist(c, a), c, a } }; + std::stable_sort(std::begin(e), std::end(e), + [](const Cand &x, const Cand &y) { return x.len2 < y.len2; }); + if (try_collapse(e[0].u, e[0].v) || try_collapse(e[1].u, e[1].v) || + try_collapse(e[2].u, e[2].v)) + ++round_collapses; + } + result.collapse_count += round_collapses; + if (round_collapses == 0) + break; + } + + // Drop deleted triangles and rebuild the soup. + const bool have_weights = !geometry.exclude_weight.empty(); + const size_t survivors = tri_count - size_t(std::count(tri_deleted.begin(), tri_deleted.end(), uint8_t(1))); + std::vector out_parent; + TriSoup &out = result.geometry; + out_parent.reserve(survivors); + out.pos.reserve(survivors * 3); + if (have_weights) + out.exclude_weight.reserve(survivors * 3); + for (size_t t = 0; t < tri_count; ++t) { + if (tri_deleted[t]) + continue; + for (int k = 0; k < 3; ++k) + out.pos.push_back(vert[size_t(corners[t * 3 + size_t(k)])].cast()); + if (have_weights) { + // Constant across a face's corners. + const float w = geometry.exclude_weight[t * 3]; + out.exclude_weight.insert(out.exclude_weight.end(), { w, w, w }); + } + out_parent.push_back(result.face_parent_id[t]); + } + result.face_parent_id = std::move(out_parent); + + // Rebuilt from the compacted geometry - the collapses moved vertices. + out.nrm.assign(out.pos.size(), Vec3f::Zero()); + { + QuantizedPointMap weld(WELD_GRID_GEOMETRY, out.pos.size()); + std::vector vid(out.pos.size()); + int next = 0; + for (size_t i = 0; i < out.pos.size(); ++i) { + vid[i] = weld.get_or_set(out.pos[i], next); + if (weld.inserted()) + ++next; + } + std::vector vn(size_t(next), Vec3d::Zero()); + for (size_t t = 0; t * 3 < out.pos.size(); ++t) { + const Vec3d a = out.pos[t * 3].cast(); + const Vec3d n = (out.pos[t * 3 + 1].cast() - a).cross(out.pos[t * 3 + 2].cast() - a); + for (int k = 0; k < 3; ++k) + vn[size_t(vid[t * 3 + size_t(k)])] += n; + } + for (size_t i = 0; i < out.pos.size(); ++i) { + const Vec3d &n = vn[size_t(vid[i])]; + const double l = n.norm(); + out.nrm[i] = (l > 0.0) ? Vec3d(n / l).cast() : Vec3f(0.f, 0.f, 1.f); + } + } + return result; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeRegularize.hpp b/src/libslic3r/TextureBake/TextureBakeRegularize.hpp new file mode 100644 index 0000000000..350666783a --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeRegularize.hpp @@ -0,0 +1,73 @@ +#pragma once + +// Sliver removal by short-edge collapse. +// +// Subdivision turns tessellation needles into chains of slivers that are within the edge-length +// budget but still poor triangles. A sliver's three vertices land on three unrelated texels, so the +// relief picks up noise that is an artifact of the tessellation rather than of the image. +// +// A candidate's edge is collapsed to its midpoint only if it passes three gates: no affected +// triangle may exceed the target edge times a slack factor; every affected triangle must keep its +// face normal within a bound of its *original* direction (which is what stops curved surfaces being +// flattened); and the link condition must hold, or the result would be non-manifold. Boundary and +// non-manifold edges are skipped outright. Rounds repeat until one achieves nothing. + +#include +#include + +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +struct RegularizeOptions +{ + // Candidate threshold. Set to catch real slivers - chains measure in the hundreds - without + // sweeping up moderate fillet triangles, which sit between 2 and 5. + double aspect_threshold = 5.0; + + // The base tier is loose on purpose: non-sliver boundary collapses must keep succeeding, since + // those give a chain the room to dissolve. A tight base leaves chains worse than before. The + // aggressive tier applies when at least one wing is an extreme sliver. + double slack = 3.0; + double aggressive_slack = 8.0; + + // Thinness above which a wing counts as extreme: longest edge over shortest altitude. + double extreme_sliver_aspect = 8.0; + + // Measured against each triangle's normal from before any collapse ran, so rounds of small + // allowed drift cannot compound into corner damage. Asymmetric two-tier: the loose bound needs + // *both* wings extreme, which matches a needle chain on a curved face but not a sliver beside a + // fillet, so fillets keep the tight bound. + double max_normal_delta_cos = 0.965925826289; // cos(15 degrees) + double aggressive_normal_delta_cos = 0.906307787037; // cos(25 degrees) + + // Vertices on edges sharper than this are frozen, so hard features keep every original vertex. + double sharp_edge_cos = 0.866025403784; // cos(30 degrees) + + int maxrounds = 8; + + // Freeze excluded faces entirely, so untextured geometry is never modified. + bool preserve_excluded = false; +}; + +// Which gate blocked a collapse - the only practical way to tell why a region failed to merge. +struct RegularizeRejectStats +{ + size_t frozen = 0, wing_count = 0, link_condition = 0, edge_cap = 0, normal_change = 0, + degenerate = 0, folded_apex = 0; +}; + +struct RegularizeResult +{ + TriSoup geometry; + std::vector face_parent_id; + size_t collapse_count = 0; + RegularizeRejectStats reject_stats; +}; + +RegularizeResult regularize_mesh(const TriSoup &geometry, const std::vector &face_parent_id, + double max_edge_length, const RegularizeOptions &opts = {}); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeRelocate.cpp b/src/libslic3r/TextureBake/TextureBakeRelocate.cpp new file mode 100644 index 0000000000..5ea33b353b --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeRelocate.cpp @@ -0,0 +1,205 @@ +#include "TextureBakeRelocate.hpp" + +#include +#include +#include + +#include +#include + +namespace Slic3r { +namespace TextureBake { + +namespace { + +// Any two unit vectors orthogonal to n. Which two does not matter - the gradient is expressed in this +// basis and converted straight back, so the result is basis independent. +void tangent_basis(const Vec3f &n, Vec3f &t1, Vec3f &t2) +{ + const Vec3f a = (std::abs(n.x()) < 0.9f) ? Vec3f(1.f, 0.f, 0.f) : Vec3f(0.f, 1.f, 0.f); + t1 = n.cross(a).normalized(); + t2 = n.cross(t1).normalized(); +} + +} // namespace + +RelocateResult relocate_to_contours(const TriSoup &geometry, const HeightSampleFn &sample, + const RelocateSettings &settings, const std::vector &locked) +{ + RelocateResult result; + result.geometry = geometry; + const size_t count = geometry.pos.size(); + const size_t tri_ct = count / 3; + if (count == 0 || !sample || settings.iterations <= 0) + return result; + + // Weld, so every copy of a position moves together and the mesh cannot come apart. + QuantizedPointMap weld(WELD_GRID_GEOMETRY, std::min(count, size_t(1) << 22)); + std::vector vid(count); + std::vector pos; + for (size_t i = 0; i < count; ++i) { + vid[i] = weld.get_or_set(geometry.pos[i], int(pos.size())); + if (weld.inserted()) + pos.push_back(geometry.pos[i]); + } + const size_t nv = pos.size(); + + // Incident corners per position, CSR style, plus the mean incident edge length that sets the scale + // for both the finite difference and the move limit. + std::vector start(nv + 1, 0); + for (size_t i = 0; i < count; ++i) + ++start[size_t(vid[i]) + 1]; + for (size_t v = 0; v < nv; ++v) + start[v + 1] += start[v]; + std::vector inc(count), cursor(nv, 0); + for (size_t i = 0; i < count; ++i) + inc[start[size_t(vid[i])] + cursor[size_t(vid[i])]++] = uint32_t(i); + + std::vector frozen(nv, 0); + if (!locked.empty()) + for (size_t t = 0; t < tri_ct && t < locked.size(); ++t) + if (locked[t]) + for (int k = 0; k < 3; ++k) + frozen[size_t(vid[t * 3 + size_t(k)])] = 1; + + std::vector edge_len(nv, 0.f), normal_len(nv, 0.f); + std::vector nrm(nv, Vec3f::Zero()); + const auto rebuild_frames = [&]() { + std::fill(nrm.begin(), nrm.end(), Vec3f::Zero()); + std::fill(edge_len.begin(), edge_len.end(), 0.f); + std::vector deg(nv, 0); + for (size_t t = 0; t < tri_ct; ++t) { + const int a = vid[t * 3], b = vid[t * 3 + 1], c = vid[t * 3 + 2]; + const Vec3f fn = (pos[size_t(b)] - pos[size_t(a)]).cross(pos[size_t(c)] - pos[size_t(a)]); + for (int k = 0; k < 3; ++k) { + const int u = vid[t * 3 + size_t(k)], w = vid[t * 3 + size_t((k + 1) % 3)]; + nrm[size_t(u)] += fn; + edge_len[size_t(u)] += (pos[size_t(w)] - pos[size_t(u)]).norm(); + ++deg[size_t(u)]; + } + } + for (size_t v = 0; v < nv; ++v) { + const float l = nrm[v].norm(); + nrm[v] = (l > 0.f) ? Vec3f(nrm[v] / l) : Vec3f(0.f, 0.f, 1.f); + edge_len[v] = deg[v] > 0 ? edge_len[v] / float(deg[v]) : 0.f; + } + }; + rebuild_frames(); + + // The level to snap onto, taken from the height actually present on this patch rather than assumed. + // A texture that never reaches full black or white would otherwise be measured against a range it + // does not occupy. + double h_lo = std::numeric_limits::max(), h_hi = -h_lo; + { + std::vector h0(nv, 0.f); + tbb::parallel_for(tbb::blocked_range(0, nv), [&](const tbb::blocked_range &r) { + for (size_t v = r.begin(); v < r.end(); ++v) + h0[v] = sample(pos[v], nrm[v], nrm[v]); + }); + for (const float h : h0) { + h_lo = std::min(h_lo, double(h)); + h_hi = std::max(h_hi, double(h)); + } + } + const double h_range = h_hi - h_lo; + if (!(h_range > 0.0)) + return result; // a flat height field has no contour to snap to + const double target = h_lo + h_range * settings.contour_level; + // A gradient is worth acting on when the height changes by this much across one edge length. + const double min_grad = h_range * settings.min_gradient_fraction; + + std::vector ever_moved(nv, 0); + + for (int iter = 0; iter < settings.iterations; ++iter) { + std::vector proposal(nv); + std::vector want(nv, 0); + + tbb::parallel_for(tbb::blocked_range(0, nv), [&](const tbb::blocked_range &r) { + for (size_t v = r.begin(); v < r.end(); ++v) { + if (frozen[v] || edge_len[v] <= 0.f) + continue; + const Vec3f n = nrm[v]; + Vec3f t1, t2; + tangent_basis(n, t1, t2); + const float eps = edge_len[v] * float(settings.gradient_step_fraction); + if (eps <= 0.f) + continue; + + // Central differences in the tangent plane. Sampling the field itself, not the mesh, + // so the gradient is the image's, at whatever resolution the mesh happens to have. + const double h = double(sample(pos[v], n, n)); + const double gx = (double(sample(pos[v] + t1 * eps, n, n)) - + double(sample(pos[v] - t1 * eps, n, n))) / (2.0 * double(eps)); + const double gy = (double(sample(pos[v] + t2 * eps, n, n)) - + double(sample(pos[v] - t2 * eps, n, n))) / (2.0 * double(eps)); + const double g2 = gx * gx + gy * gy; + if (g2 <= 0.0) + continue; + // Scale-free test: how much the height changes across one edge, versus the patch range. + if (std::sqrt(g2) * double(edge_len[v]) < min_grad) + continue; + + // Newton step onto the level set h = target, expressed back in 3D. + const double s = -(h - target) / g2; + Vec3f d = t1 * float(s * gx) + t2 * float(s * gy); + const float cap = edge_len[v] * float(settings.max_move_fraction); + const float len = d.norm(); + if (len <= 0.f) + continue; + if (len > cap) + d *= cap / len; + proposal[v] = pos[v] + d; + want[v] = 1; + } + }); + + // Apply one at a time: a move is only valid against the neighbourhood as it stands, and two + // adjacent vertices moving together can invert a triangle neither would have on its own. + size_t applied = 0; + for (size_t v = 0; v < nv; ++v) { + if (!want[v]) + continue; + const Vec3f old = pos[v]; + pos[v] = proposal[v]; + bool ok = true; + for (uint32_t k = start[v]; k < start[v + 1] && ok; ++k) { + const size_t t = size_t(inc[k]) / 3; + const Vec3f &a = pos[size_t(vid[t * 3])]; + const Vec3f n2 = (pos[size_t(vid[t * 3 + 1])] - a).cross(pos[size_t(vid[t * 3 + 2])] - a); + // Compared against the frame this vertex carried before the move: a triangle that + // flips or collapses means the move crossed a neighbour. + if (n2.squaredNorm() <= 0.f || n2.normalized().dot(nrm[v]) < 0.f) + ok = false; + } + if (ok) { + ++applied; + ever_moved[v] = 1; + } else { + pos[v] = old; + ++result.rejected; + } + } + if (applied == 0) + break; + rebuild_frames(); + } + + for (size_t v = 0; v < nv; ++v) + if (ever_moved[v]) + ++result.moved; + + // Write the relocated positions back to every copy, and rebuild the per-face normals. + for (size_t i = 0; i < count; ++i) + result.geometry.pos[i] = pos[size_t(vid[i])]; + for (size_t t = 0; t < tri_ct; ++t) { + Vec3f n = (result.geometry.pos[t * 3 + 1] - result.geometry.pos[t * 3]) + .cross(result.geometry.pos[t * 3 + 2] - result.geometry.pos[t * 3]); + const float len = n.norm(); + n = (len > 0.f) ? Vec3f(n / len) : Vec3f(0.f, 0.f, 1.f); + result.geometry.nrm[t * 3] = result.geometry.nrm[t * 3 + 1] = result.geometry.nrm[t * 3 + 2] = n; + } + return result; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeRelocate.hpp b/src/libslic3r/TextureBake/TextureBakeRelocate.hpp new file mode 100644 index 0000000000..cd674d03ae --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeRelocate.hpp @@ -0,0 +1,72 @@ +#pragma once + +// Tangential relocation: slide vertices along the surface so triangle edges land on the height map's +// own edges, before any displacement happens. +// +// Displacement moves vertices along the normal only, so a step in the height map - the wall of a +// mortar groove, the rim of an embossed shape - is reproduced wherever the triangle grid happens to +// fall, as a staircase quantised to triangle boundaries. Refining further only makes the steps +// smaller; it never straightens them, because the edge in the image still does not coincide with any +// edge in the mesh. +// +// This pass fixes the cause rather than the symptom. For a vertex sitting near a step it takes a +// Newton step onto the contour: with h the sampled height and g its tangential gradient, the move +// +// d = -(h - target) * g / |g|^2 +// +// lands on the level set h = target to first order. The ring of vertices nearest each step therefore +// snaps onto it, the triangle edges between them follow the step, and the displaced result has a +// straight wall instead of a sawtooth. +// +// Vertices in flat regions have no gradient to speak of and are left alone, so the pass costs nothing +// where there is nothing to align. + +#include +#include +#include + +#include "TextureBakeDisplace.hpp" +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +struct RelocateSettings +{ + // Passes. Each is a Newton step, so a couple converge for vertices that start reasonably close; + // more mainly helps ones that begin further away. + int iterations = 3; + + // How far a vertex may move in one pass, as a fraction of the mean length of its incident edges. + // Below a half it cannot pass a neighbour, which is what keeps the triangulation valid without + // needing a full topological check. + double max_move_fraction = 0.35; + + // A vertex is only pulled when the height varies enough across its own footprint to mean + // something - as a fraction of the height range over the whole patch. Below this the gradient is + // noise, and chasing it would scramble flat regions. + double min_gradient_fraction = 0.05; + + // The level to snap onto, as a position in the sampled height range: 0.5 is midway between the + // lowest and highest point of the relief, which is where the wall of a step is steepest. + double contour_level = 0.5; + + // Sampling offset for the finite-difference gradient, as a fraction of the local edge length. + double gradient_step_fraction = 0.25; +}; + +struct RelocateResult +{ + TriSoup geometry; + size_t moved = 0; // positions that were relocated at least once + size_t rejected = 0; // moves refused because a triangle would have inverted +}; + +// `locked`, when non-empty, has one entry per input triangle; a vertex touching a locked triangle is +// never moved, so an excluded region keeps its exact vertex positions. +RelocateResult relocate_to_contours(const TriSoup &geometry, const HeightSampleFn &sample, + const RelocateSettings &settings = {}, + const std::vector &locked = {}); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeRepair.cpp b/src/libslic3r/TextureBake/TextureBakeRepair.cpp new file mode 100644 index 0000000000..438e0ea25d --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeRepair.cpp @@ -0,0 +1,215 @@ +#include "TextureBakeRepair.hpp" + +#include +#include +#include +#include +#include + +namespace Slic3r { +namespace TextureBake { + +namespace { + +inline uint64_t edge_key(int a, int b) +{ + const uint32_t lo = uint32_t(std::min(a, b)), hi = uint32_t(std::max(a, b)); + return (uint64_t(lo) << 32) | uint64_t(hi); +} + +// On the export grid a squared cross product is either 0 (collinear) or at least about 1e-16, the +// smallest real triangle being one grid unit per leg, so this separates the two cleanly. +constexpr double DEGENERATE_AREA_SQ = 1e-18; + +} // namespace + +EdgeDefects count_edge_defects(const TriSoup &geometry, double quant) +{ + EdgeDefects out; + const size_t n = geometry.pos.size(); + out.triangles = n / 3; + QuantizedPointMap vmap(quant, std::min(n, size_t(1) << 22)); + std::vector id(n); + int next = 0; + for (size_t i = 0; i < n; ++i) { + id[i] = vmap.get_or_set(geometry.pos[i], next); + if (vmap.inserted()) + ++next; + } + std::unordered_map counts; + for (size_t t = 0; t + 2 < n; t += 3) { + const int a = id[t], b = id[t + 1], c = id[t + 2]; + if (a == b || b == c || a == c) + continue; + const int tri[3] = { a, b, c }; + for (int e = 0; e < 3; ++e) + ++counts[edge_key(tri[e], tri[(e + 1) % 3])]; + } + for (const auto &[key, c] : counts) { + (void) key; + if (c == 1) ++out.open; + else if (c > 2) ++out.non_manifold; + } + return out; +} + +size_t count_area_slivers(const TriSoup &geometry) +{ + size_t n = 0; + for (size_t t = 0; t + 2 < geometry.pos.size(); t += 3) { + const Vec3d u = (geometry.pos[t + 1] - geometry.pos[t]).cast(); + const Vec3d v = (geometry.pos[t + 2] - geometry.pos[t]).cast(); + // The threshold a slicer applies: area below 1e-12 mm^2. + if (u.cross(v).squaredNorm() < 1e-24) + ++n; + } + return n; +} + +TriSoup resolve_t_junctions(const TriSoup &geometry, const RepairOptions &opts) +{ + const size_t n_tri = geometry.triangle_count(); + const double on_tol2 = opts.on_seg_tol * opts.on_seg_tol; + const double Q = opts.weld_quant; + + // Snapped, not just welded: keeping unrounded coordinates lets a thin triangle pass the + // degeneracy test here and then collapse to collinear once the file is written, punching the very + // hole this pass prevents. Snapping makes the check see what will be written. + QuantizedPointMap vmap(Q, std::min(n_tri * 3, size_t(1) << 22)); + std::vector vert; + std::vector vid(n_tri * 3); + for (size_t i = 0; i < n_tri * 3; ++i) { + const Vec3f &p = geometry.pos[i]; + const int id = vmap.get_or_set(p, int(vert.size())); + if (vmap.inserted()) + vert.emplace_back(double(grid_round(double(p.x()) * Q)) / Q, + double(grid_round(double(p.y()) * Q)) / Q, + double(grid_round(double(p.z()) * Q)) / Q); + vid[i] = id; + } + + // Dropped: faces whose corners welded together, and needles - distinct but collinear on this + // grid. A needle reads as watertight yet is deleted downstream, and dropping it leaves exactly + // the on-edge-vertex topology the pass below closes. + std::vector> faces; + faces.reserve(n_tri); + for (size_t t = 0; t < n_tri; ++t) { + const int a = vid[t * 3], b = vid[t * 3 + 1], c = vid[t * 3 + 2]; + if (a == b || b == c || a == c) + continue; + const Vec3d u = vert[size_t(b)] - vert[size_t(a)]; + const Vec3d w = vert[size_t(c)] - vert[size_t(a)]; + if (u.cross(w).squaredNorm() < DEGENERATE_AREA_SQ) + continue; + faces.push_back({ a, b, c }); + } + + for (int iter = 0; iter < opts.max_iters; ++iter) { + std::unordered_map e_count; + for (const auto &f : faces) + for (int e = 0; e < 3; ++e) + ++e_count[edge_key(f[size_t(e)], f[size_t((e + 1) % 3)])]; + + std::unordered_set bverts; + for (const auto &[key, c] : e_count) { + if (c != 1) + continue; + bverts.insert(int(uint32_t(key >> 32))); + bverts.insert(int(uint32_t(key & 0xFFFFFFFFu))); + } + if (bverts.empty()) + break; + const std::vector bv(bverts.begin(), bverts.end()); + + struct Split { int a, b; std::vector mids; }; + std::unordered_map splits; + for (size_t fi = 0; fi < faces.size(); ++fi) { + const auto &f = faces[fi]; + for (int e = 0; e < 3; ++e) { + const int a = f[size_t(e)], b = f[size_t((e + 1) % 3)]; + if (e_count[edge_key(a, b)] != 1) + continue; // only a boundary edge carries an unresolved T-junction + const Vec3d A = vert[size_t(a)]; + const Vec3d ev = vert[size_t(b)] - A; + const double elen2 = ev.squaredNorm(); + if (elen2 < 1e-20) + continue; + std::vector> found; + for (const int c : bv) { + if (c == a || c == b) + continue; + const Vec3d cv = vert[size_t(c)] - A; + const double tp = cv.dot(ev) / elen2; + if (tp <= 1e-4 || tp >= 1.0 - 1e-4) + continue; // strictly between the ends + if ((cv - ev * tp).squaredNorm() < on_tol2) + found.emplace_back(tp, c); + } + if (!found.empty()) { + std::sort(found.begin(), found.end(), + [](const auto &x, const auto &y) { return x.first < y.first; }); + Split sp{ a, b, {} }; + for (const auto &m : found) + sp.mids.push_back(m.second); + splits.emplace(fi, std::move(sp)); + break; // one site per face per pass; iteration handles cascades + } + } + } + if (splits.empty()) + break; + + std::vector> next; + next.reserve(faces.size() + splits.size() * 2); + for (size_t fi = 0; fi < faces.size(); ++fi) { + const auto it = splits.find(fi); + if (it == splits.end()) { + next.push_back(faces[fi]); + continue; + } + const auto &f = faces[fi]; + const auto &sp = it->second; + const int apex = (f[0] != sp.a && f[0] != sp.b) ? f[0] + : (f[1] != sp.a && f[1] != sp.b) ? f[1] + : f[2]; + // Walk the base the way the face already traverses it, so the winding survives. + bool dir_ab = false; + for (int e = 0; e < 3; ++e) + if (f[size_t(e)] == sp.a && f[size_t((e + 1) % 3)] == sp.b) { + dir_ab = true; + break; + } + std::vector seq; + if (dir_ab) { + seq.push_back(sp.a); + seq.insert(seq.end(), sp.mids.begin(), sp.mids.end()); + seq.push_back(sp.b); + } else { + seq.push_back(sp.b); + seq.insert(seq.end(), sp.mids.rbegin(), sp.mids.rend()); + seq.push_back(sp.a); + } + for (size_t s = 0; s + 1 < seq.size(); ++s) + next.push_back({ seq[s], seq[s + 1], apex }); + } + faces.swap(next); + } + + TriSoup out; + out.pos.reserve(faces.size() * 3); + out.nrm.reserve(faces.size() * 3); + for (const auto &f : faces) { + const Vec3f a = vert[size_t(f[0])].cast(); + const Vec3f b = vert[size_t(f[1])].cast(); + const Vec3f c = vert[size_t(f[2])].cast(); + Vec3f nrm = (b - a).cross(c - a); + const float len = nrm.norm(); + nrm = (len > 0.f) ? Vec3f(nrm / len) : Vec3f(0.f, 0.f, 1.f); + out.pos.insert(out.pos.end(), { a, b, c }); + out.nrm.insert(out.nrm.end(), { nrm, nrm, nrm }); + } + return out; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeRepair.hpp b/src/libslic3r/TextureBake/TextureBakeRepair.hpp new file mode 100644 index 0000000000..35e9f50b06 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeRepair.hpp @@ -0,0 +1,48 @@ +#pragma once + +// T-junction resolution and edge-defect accounting. +// +// Decimation can collapse a long edge whose interior still carries neighbouring triangles' vertices. +// Those then sit *on* an edge rather than at an end: watertight vertex-for-vertex, but the edge has +// one incident face on one side, which a slicer reads as an open boundary. This splits the offending +// face into a fan so every on-edge vertex becomes a real corner. + +#include +#include + +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +struct EdgeDefects +{ + size_t open = 0, non_manifold = 0, triangles = 0; +}; + +// Welds at the export grid first: counting on the un-snapped mesh reports defects the file does not +// have and misses ones it does. +EdgeDefects count_edge_defects(const TriSoup &geometry, double quant = WELD_GRID_EXPORT); + +// Triangles a slicer would drop as degenerate. Each one, removed, punches a hole - so a non-zero +// count means watertight only on paper. +size_t count_area_slivers(const TriSoup &geometry); + +struct RepairOptions +{ + // Coordinates are snapped onto this grid, matching the precision files are written with. + double weld_quant = WELD_GRID_EXPORT; + + // How far off an edge a vertex may sit and still count as on it. Well above the harvest + // tolerance, since harvesting leaves a region flat only to within that, making a collapsed edge a + // chord the on-edge vertices deviate from by about as much. Still far below the weld grid. + double on_seg_tol = 0.02; + + // Splitting one face can expose another behind it, so the pass cascades. + int max_iters = 16; +}; + +TriSoup resolve_t_junctions(const TriSoup &geometry, const RepairOptions &opts = {}); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeSubdivide.cpp b/src/libslic3r/TextureBake/TextureBakeSubdivide.cpp new file mode 100644 index 0000000000..6b882b1fc8 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeSubdivide.cpp @@ -0,0 +1,484 @@ +#include "TextureBakeSubdivide.hpp" + +#include +#include +#include + +#include +#include +#include + +namespace Slic3r { +namespace TextureBake { + +namespace { + +double edge_len_sq(const VertStore &v, int a, int b) +{ + return (v.pos[size_t(a)] - v.pos[size_t(b)]).squaredNorm(); +} + +// Both indexers accumulate raw, area-weighted cross products and normalise once at the end. +void normalize_store_normals(VertStore &verts) +{ + for (Vec3d &n : verts.nrm) { + const double len = n.norm(); + n = (len > 0.0) ? Vec3d(n / len) : Vec3d(0.0, 0.0, 1.0); + } +} + +// Keyed by the raw parent-vertex pair rather than by position: two sharp-edge copies of one point +// need their own midpoints, since their normals differ even though the position does not. +int get_midpoint(VertStore &verts, QuantizedPointMap &cache, int a, int b, + QuantizedPointMap *pos_canon_map) +{ + const int lo = std::min(a, b), hi = std::max(a, b); + if (const int cached = cache.get_key(lo, hi, 0); cached != -1) + return cached; + + const Vec3d m = (verts.pos[size_t(a)] + verts.pos[size_t(b)]) * 0.5; + Vec3d n = verts.nrm[size_t(a)] + verts.nrm[size_t(b)]; + const double nl = n.norm(); + n = (nl > 0.0) ? Vec3d(n / nl) : verts.nrm[size_t(a)]; + + const int idx = verts.push(m, n); + if (!verts.wgt.empty()) + verts.wgt.push_back((verts.wgt[size_t(a)] + verts.wgt[size_t(b)]) * 0.5); + if (!verts.canon.empty() && pos_canon_map != nullptr) + verts.canon.push_back(pos_canon_map->get_or_set(float(m.x()), float(m.y()), float(m.z()), idx)); + + cache.get_or_set_key(lo, hi, 0, idx); + return idx; +} + +struct PassResult +{ + std::vector indices; + std::vector face_excluded; + std::vector face_parent_id; + bool changed = false; + bool capped = false; +}; + +// Three steps, so that no T-junction can appear: +// 1. Mark every too-long edge globally, so both triangles on a shared edge decide alike. +// 1.5 Predict the exact resulting count from the marks (0->1, 1->2, 2->3, 3->4) and abort the +// *whole* pass if it exceeds the cap - a partial pass leaves split parents beside unsplit +// neighbours, the very crack step 1 prevents. +// 2. Rebuild, allocating once at the now-known size. +PassResult subdivide_pass(VertStore &verts, const std::vector &indices, double max_edge_length, + int safety_cap, const std::vector &face_excluded, + QuantizedPointMap *pos_canon_map, const std::vector &face_parent_id, + const SubdivideWithinFn &within) +{ + PassResult out; + const double max_sq = max_edge_length * max_edge_length; + const size_t tri_count = indices.size() / 3; + const bool have_canon = !verts.canon.empty(); + + // Sized from the pass rather than grown from 64 k: a fine pass marks on the order of one edge per + // triangle, and growing to that by doubling rehashes the whole table a dozen times. + const size_t expect = std::max(size_t(1) << 16, tri_count); + QuantizedPointMap mid_cache(1.0, expect); + QuantizedPointMap split_edges(1.0, expect); + + // With canonical ids the key is the canonical *position* id, so split copies either side of a + // sharp edge see one another's decision; without them the vertex index serves. + const auto key_of = [&](int v) -> int64_t { return have_canon ? verts.canon[size_t(v)] : v; }; + const auto mark_edge = [&](int a, int b) { + const int64_t u = key_of(a), v = key_of(b); + if (u < v) split_edges.get_or_set_key(u, v, 0, 1); + else split_edges.get_or_set_key(v, u, 0, 1); + }; + const auto is_marked = [&](int a, int b) { + const int64_t u = key_of(a), v = key_of(b); + return (u < v ? split_edges.get_key(u, v, 0) : split_edges.get_key(v, u, 0)) != -1; + }; + + // Graded, an edge splits while it is longer than max_edge_length + SUBDIVIDE_GRADE * (d - len/2), + // d its midpoint's distance from the region; less half the length bounds the edge's own distance + // from below, so the test errs toward splitting. Solved for d, that is the region coming within the + // radius below. It reads the positions alone, so two triangles sharing the edge agree. + const auto too_long = [&](int a, int b) { + const double len_sq = edge_len_sq(verts, a, b); + if (len_sq <= max_sq) + return false; + if (!within) + return true; + const double len = std::sqrt(len_sq); + return within((verts.pos[size_t(a)] + verts.pos[size_t(b)]) * 0.5, + 0.5 * len + (len - max_edge_length) / SUBDIVIDE_GRADE); + }; + + // Step 1. An excluded triangle marks none of its own edges while left alone, so its interior never + // refines; its boundary edges are still marked by an included neighbour, and ungraded it follows + // that split. Graded, one the refinement reaches marks its own too-long edges too, and so on + // outward. An earlier bake's relief meets the paint along edges already at the target length, so + // it is never reached and stays as it was. + std::vector want(tri_count, 0); + tbb::parallel_for(tbb::blocked_range(0, tri_count), [&](const tbb::blocked_range &range) { + for (size_t t = range.begin(); t < range.end(); ++t) { + const int a = indices[t * 3], b = indices[t * 3 + 1], c = indices[t * 3 + 2]; + want[t] = uint8_t(too_long(a, b)) | uint8_t(too_long(b, c) << 1) | uint8_t(too_long(c, a) << 2); + } + }); + const auto mark_wanted = [&](size_t t) { + const int a = indices[t * 3], b = indices[t * 3 + 1], c = indices[t * 3 + 2]; + if (want[t] & 1) mark_edge(a, b); + if (want[t] & 2) mark_edge(b, c); + if (want[t] & 4) mark_edge(c, a); + }; + std::vector unreached; + for (size_t t = 0; t < tri_count; ++t) + if (face_excluded.empty() || !face_excluded[t]) + mark_wanted(t); + else if (within && want[t] != 0) + unreached.push_back(t); + // Marks only accumulate, so the order the reached triangles are taken in does not matter. + for (size_t n = 0; n != unreached.size();) { + n = unreached.size(); + unreached.erase(std::remove_if(unreached.begin(), unreached.end(), [&](size_t t) { + const int a = indices[t * 3], b = indices[t * 3 + 1], c = indices[t * 3 + 2]; + const bool reached = is_marked(a, b) || is_marked(b, c) || is_marked(c, a); + if (reached) + mark_wanted(t); + return reached; + }), unreached.end()); + } + if (split_edges.size() == 0) { + out.indices = indices; + out.face_excluded = face_excluded; + out.face_parent_id = face_parent_id; + return out; // changed stays false: nothing left to refine + } + + // Step 1.5. Read-only against the finished mark set, so it runs in parallel - and it keeps each + // triangle's three marks (bit 0 = ab, 1 = bc, 2 = ca), so the serial rebuild below reads a byte + // instead of probing the hash map three more times per triangle. + std::vector tri_marks(tri_count); + const size_t predicted = tbb::parallel_reduce( + tbb::blocked_range(0, tri_count), size_t(0), + [&](const tbb::blocked_range &range, size_t acc) { + for (size_t t = range.begin(); t < range.end(); ++t) { + const int a = indices[t * 3], b = indices[t * 3 + 1], c = indices[t * 3 + 2]; + const uint8_t m = uint8_t(is_marked(a, b)) | uint8_t(is_marked(b, c) << 1) | + uint8_t(is_marked(c, a) << 2); + tri_marks[t] = m; + const int n = (m & 1) + ((m >> 1) & 1) + ((m >> 2) & 1); + acc += (n == 0) ? 1 : size_t(n + 1); + } + return acc; + }, + std::plus()); + if (predicted > size_t(safety_cap)) { + out.indices = indices; + out.face_excluded = face_excluded; + out.face_parent_id = face_parent_id; + out.capped = true; + return out; // coarser than asked for, but watertight + } + + // Step 2. + out.indices.resize(predicted * 3); + if (!face_excluded.empty()) + out.face_excluded.resize(predicted); + if (!face_parent_id.empty()) + out.face_parent_id.resize(predicted); + size_t wi = 0, fi = 0; + const auto emit_face_data = [&](uint8_t excl, int pid, int times) { + for (int k = 0; k < times; ++k) { + if (!out.face_excluded.empty()) out.face_excluded[fi] = excl; + if (!out.face_parent_id.empty()) out.face_parent_id[fi] = pid; + ++fi; + } + }; + const auto emit = [&](int x, int y, int z) { + out.indices[wi++] = x; out.indices[wi++] = y; out.indices[wi++] = z; + }; + + for (size_t t = 0; t < tri_count; ++t) { + const int a = indices[t * 3], b = indices[t * 3 + 1], c = indices[t * 3 + 2]; + const uint8_t excl = face_excluded.empty() ? uint8_t(0) : face_excluded[t]; + const int pid = face_parent_id.empty() ? 0 : face_parent_id[t]; + const bool s_ab = (tri_marks[t] & 1) != 0, s_bc = (tri_marks[t] & 2) != 0, s_ca = (tri_marks[t] & 4) != 0; + const int n = int(s_ab) + int(s_bc) + int(s_ca); + + if (n == 0) { + emit(a, b, c); + emit_face_data(excl, pid, 1); + } else if (n == 3) { + // a + // / \ + // mCA-mAB + // / \ / \ + // c--mBC--b + const int m_ab = get_midpoint(verts, mid_cache, a, b, pos_canon_map); + const int m_bc = get_midpoint(verts, mid_cache, b, c, pos_canon_map); + const int m_ca = get_midpoint(verts, mid_cache, c, a, pos_canon_map); + emit(a, m_ab, m_ca); + emit(m_ab, b, m_bc); + emit(m_ca, m_bc, c); + emit(m_ab, m_bc, m_ca); + emit_face_data(excl, pid, 4); + } else if (n == 1) { + if (s_ab) { + const int m = get_midpoint(verts, mid_cache, a, b, pos_canon_map); + emit(a, m, c); + emit(m, b, c); + } else if (s_bc) { + const int m = get_midpoint(verts, mid_cache, b, c, pos_canon_map); + emit(a, b, m); + emit(a, m, c); + } else { + const int m = get_midpoint(verts, mid_cache, c, a, pos_canon_map); + emit(a, b, m); + emit(m, b, c); + } + emit_face_data(excl, pid, 2); + } else { + // A corner triangle on the untouched-edge vertex, then the remaining quadrilateral split + // along the midpoint-to-midpoint diagonal, which keeps the winding consistent. + // + // A sliver parent propagates: that inner diagonal inherits half the short edge and hands + // the sliver to two children per pass. No better diagonal exists - one avoiding the + // midpoints must pass through one of them, giving a zero-area triangle. Regularization + // removes such slivers before the mesh reaches here. + if (!s_ab) { // fan from c + const int m_bc = get_midpoint(verts, mid_cache, b, c, pos_canon_map); + const int m_ca = get_midpoint(verts, mid_cache, c, a, pos_canon_map); + emit(a, b, m_bc); + emit(a, m_bc, m_ca); + emit(c, m_ca, m_bc); + } else if (!s_bc) { // fan from a + const int m_ab = get_midpoint(verts, mid_cache, a, b, pos_canon_map); + const int m_ca = get_midpoint(verts, mid_cache, c, a, pos_canon_map); + emit(a, m_ab, m_ca); + emit(m_ab, b, c); + emit(m_ab, c, m_ca); + } else { // fan from b + const int m_ab = get_midpoint(verts, mid_cache, a, b, pos_canon_map); + const int m_bc = get_midpoint(verts, mid_cache, b, c, pos_canon_map); + emit(b, m_bc, m_ab); + emit(a, m_ab, m_bc); + emit(a, m_bc, c); + } + emit_face_data(excl, pid, 3); + } + } + + out.changed = true; + return out; +} + +} // namespace + +IndexedMesh to_indexed_fast(const TriSoup &geometry) +{ + // Preview path: a plain position merge - no clustering, no sharp-edge splitting, no canonical ids. + IndexedMesh out; + const size_t n = geometry.pos.size(); + QuantizedPointMap vert_map(WELD_GRID_GEOMETRY, std::min(n, size_t(1) << 22)); + out.indices.resize(n); + const bool has_w = !geometry.exclude_weight.empty(); + + for (size_t i = 0; i < n; ++i) { + const Vec3f &p = geometry.pos[i]; + const Vec3f nf = geometry.nrm.empty() ? Vec3f(0.f, 0.f, 1.f) : geometry.nrm[i]; + const int idx = vert_map.get_or_set(p, int(out.verts.count())); + if (vert_map.inserted()) { + out.verts.push(p.cast(), nf.cast()); + if (has_w) + out.verts.wgt.push_back(double(geometry.exclude_weight[i])); + } else { + out.verts.nrm[size_t(idx)] += nf.cast(); + // Merge exclusion by maximum: any excluded face marks the shared vertex. + if (has_w && double(geometry.exclude_weight[i]) > out.verts.wgt[size_t(idx)]) + out.verts.wgt[size_t(idx)] = double(geometry.exclude_weight[i]); + } + out.indices[i] = idx; + } + normalize_store_normals(out.verts); + return out; +} + +IndexedMesh to_indexed(const TriSoup &geometry) +{ + // Export path. Two vertices at one position merge only when their face normals agree to within + // SUBDIVIDE_SHARP_ANGLE_DEG, which keeps a cylinder from faceting while stopping a cube's edge + // normal from leaking into the flat face interiors as subdivision carries it inward. + IndexedMesh out; + out.has_canon = true; + const size_t n = geometry.pos.size(); + const bool has_w = !geometry.exclude_weight.empty(); + const double sharp_cos = std::cos(SUBDIVIDE_SHARP_ANGLE_DEG * M_PI / 180.0); + + // Per-face normals: unit for the angle test, raw for the area-weighted accumulation. + std::vector face_unit(n), face_raw(n); + tbb::parallel_for(tbb::blocked_range(0, n / 3), [&](const tbb::blocked_range &range) { + for (size_t f = range.begin(); f < range.end(); ++f) { + const size_t t = f * 3; + const Vec3d a = geometry.pos[t].cast(); + const Vec3d r = (geometry.pos[t + 1].cast() - a).cross( + geometry.pos[t + 2].cast() - a); + const double len = r.norm(); + const Vec3d u = (len > 0.0) ? Vec3d(r / len) : Vec3d(0.0, 0.0, 1.0); + for (int v = 0; v < 3; ++v) { + face_unit[t + size_t(v)] = u; + face_raw[t + size_t(v)] = r; + } + } + }); + + out.indices.resize(n); + out.pos_canon_map = QuantizedPointMap(WELD_GRID_GEOMETRY, std::min(n, size_t(1) << 22)); + struct Cluster { int idx; Vec3d fn_unit; }; + std::unordered_map> clusters_by_canon; + + for (size_t i = 0; i < n; ++i) { + const Vec3f &p = geometry.pos[i]; + // The first vertex at a position becomes its canonical id; later split copies share it. + const int canon_id = out.pos_canon_map.get_or_set(p, int(out.verts.count())); + const bool fresh_position = out.pos_canon_map.inserted(); + + const auto add_vertex = [&](int canon) { + const int idx = out.verts.push(p.cast(), face_raw[i]); + if (has_w) + out.verts.wgt.push_back(double(geometry.exclude_weight[i])); + out.verts.canon.push_back(canon); + return idx; + }; + + if (fresh_position) { + const int idx = add_vertex(canon_id); + clusters_by_canon[canon_id].push_back({ idx, face_unit[i] }); + out.indices[i] = idx; + continue; + } + + std::vector &clusters = clusters_by_canon[canon_id]; + bool matched = false; + for (Cluster &cl : clusters) { + if (cl.fn_unit.dot(face_unit[i]) < sharp_cos) + continue; + out.verts.nrm[size_t(cl.idx)] += face_raw[i]; + if (has_w && double(geometry.exclude_weight[i]) > out.verts.wgt[size_t(cl.idx)]) + out.verts.wgt[size_t(cl.idx)] = double(geometry.exclude_weight[i]); + // Track the running average, so gradual curvature stays in one cluster instead of + // fragmenting when a distant face exceeds the threshold against the seed's fixed normal. + cl.fn_unit += face_unit[i]; + if (const double rl = cl.fn_unit.norm(); rl > 0.0) + cl.fn_unit /= rl; + out.indices[i] = cl.idx; + matched = true; + break; + } + if (!matched) { + // A sharp-edge split: a new vertex at the same position, sharing its canonical id. + const int idx = add_vertex(canon_id); + clusters.push_back({ idx, face_unit[i] }); + out.indices[i] = idx; + } + } + + normalize_store_normals(out.verts); + return out; +} + +TriSoup to_non_indexed(const VertStore &verts, const std::vector &indices, + const std::vector &face_excluded) +{ + TriSoup out; + const size_t tri_count = indices.size() / 3; + out.pos.resize(tri_count * 3); + out.nrm.resize(tri_count * 3); + const bool want_weights = !face_excluded.empty() || !verts.wgt.empty(); + if (want_weights) + out.exclude_weight.resize(tri_count * 3); + + // Each triangle writes only its own three slots, so this is a plain parallel gather. + tbb::parallel_for(tbb::blocked_range(0, tri_count), [&](const tbb::blocked_range &r) { + for (size_t t = r.begin(); t < r.end(); ++t) { + // The per-face flag, not the interpolated weight: merging by maximum can push an *included* + // face's corners to 1 when it borders two excluded neighbours, wrongly excluding it. + const bool have_face_flag = !face_excluded.empty(); + const float face_w = have_face_flag ? (face_excluded[t] ? 1.f : 0.f) : 0.f; + for (int v = 0; v < 3; ++v) { + const size_t vidx = size_t(indices[t * 3 + size_t(v)]); + out.pos[t * 3 + size_t(v)] = verts.pos[vidx].cast(); + out.nrm[t * 3 + size_t(v)] = verts.nrm[vidx].cast(); + if (want_weights) + out.exclude_weight[t * 3 + size_t(v)] = + have_face_flag ? face_w : float(verts.wgt[vidx]); + } + } + }); + return out; +} + +SubdivideResult subdivide(const TriSoup &geometry, double max_edge_length, + const std::vector &face_excluded, bool fast, int safety_cap, + const SubdivideProgressFn &on_progress, const SubdivideWithinFn &within) +{ + SubdivideResult result; + if (geometry.empty() || max_edge_length <= 0.0) { + result.geometry = geometry; + return result; + } + + IndexedMesh indexed = fast ? to_indexed_fast(geometry) : to_indexed(geometry); + QuantizedPointMap *canon_map = indexed.has_canon ? &indexed.pos_canon_map : nullptr; + + const size_t initial_tris = indexed.indices.size() / 3; + std::vector current_indices = std::move(indexed.indices); // nothing reads it again + std::vector current_excluded = face_excluded; + std::vector current_parent(initial_tris); + for (size_t i = 0; i < initial_tris; ++i) + current_parent[i] = int(i); + + for (int iter = 0; iter < SUBDIVIDE_MAX_ITERATIONS; ++iter) { + if (current_indices.size() / 3 >= size_t(safety_cap)) { + result.safety_cap_hit = true; + break; + } + + PassResult pass = subdivide_pass(indexed.verts, current_indices, max_edge_length, safety_cap, + current_excluded, canon_map, current_parent, within); + current_indices = std::move(pass.indices); + if (!pass.face_excluded.empty()) + current_excluded = std::move(pass.face_excluded); + if (!pass.face_parent_id.empty()) + current_parent = std::move(pass.face_parent_id); + if (pass.capped || current_indices.size() / 3 >= size_t(safety_cap)) + result.safety_cap_hit = true; + + if (on_progress) { + // Reported after the pass, so the value falls each iteration instead of lagging a step. + // A max is order-independent, so the scan reduces in parallel to the same value. + const double max_edge_sq = tbb::parallel_reduce( + tbb::blocked_range(0, current_indices.size() / 3), 0.0, + [&](const tbb::blocked_range &r, double acc) { + for (size_t f = r.begin(); f < r.end(); ++f) { + const int a = current_indices[f * 3], b = current_indices[f * 3 + 1], + c = current_indices[f * 3 + 2]; + acc = std::max({ acc, edge_len_sq(indexed.verts, a, b), edge_len_sq(indexed.verts, b, c), + edge_len_sq(indexed.verts, c, a) }); + } + return acc; + }, + [](double x, double y) { return std::max(x, y); }); + if (!on_progress(std::min(0.95, double(iter + 1) / SUBDIVIDE_MAX_ITERATIONS), + current_indices.size() / 3, std::sqrt(max_edge_sq))) + break; // whole passes only, so what we have is still crack-free + } + + if (!pass.changed || result.safety_cap_hit) + break; + } + + result.geometry = to_non_indexed(indexed.verts, current_indices, current_excluded); + result.face_parent_id = std::move(current_parent); + return result; +} + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureBake/TextureBakeSubdivide.hpp b/src/libslic3r/TextureBake/TextureBakeSubdivide.hpp new file mode 100644 index 0000000000..743c74eb49 --- /dev/null +++ b/src/libslic3r/TextureBake/TextureBakeSubdivide.hpp @@ -0,0 +1,96 @@ +#pragma once + +// Adaptive subdivision to a target edge length, by global marked-edge (red-green) refinement rather +// than longest-edge bisection. Marking is global, so two triangles sharing an edge always agree and +// the result is crack-free by construction. A triangle is rebuilt from its marked-edge count: 0 +// keeps, 1 bisects, 2 fans into three, 3 does the regular 1->4 split. +// +// The 1->4 case is what keeps the tessellation regular - its children are similar to the parent. An +// irregular one shows up after displacement as adjacent triangles tilting alternately, i.e. noise. + +#include +#include + +#include "TextureBakeIndex.hpp" + +namespace Slic3r { +namespace TextureBake { + +// Memory guard for the stages downstream. At roughly 145 bytes per triangle this is about 2.9 GB. +static constexpr int SUBDIVIDE_SAFETY_CAP = 16'000'000; + +// Vertices at one position stay separate when their faces disagree by more than this: a cube keeps +// hard edges, a cylinder keeps averaged ones. +static constexpr double SUBDIVIDE_SHARP_ANGLE_DEG = 30.0; + +// A depth bound, not a work bound: the loop stops as soon as a pass changes nothing. +static constexpr int SUBDIVIDE_MAX_ITERATIONS = 12; + +// Graded refinement: millimetres of edge length allowed per millimetre of distance from the region. +static constexpr double SUBDIVIDE_GRADE = 1.0; + +// Built by the indexers, appended to by the passes. Double precision so repeated midpointing does +// not drift. +struct VertStore +{ + std::vector pos; + std::vector nrm; + std::vector wgt; // exclusion weights; empty when the caller supplied none + std::vector canon; // canonical position ids; empty in fast mode + + size_t count() const { return pos.size(); } + int push(const Vec3d &p, const Vec3d &n) + { + const int idx = int(pos.size()); + pos.push_back(p); + nrm.push_back(n); + return idx; + } +}; + +struct IndexedMesh +{ + VertStore verts; + std::vector indices; // 3 per triangle + QuantizedPointMap pos_canon_map{ WELD_GRID_GEOMETRY, 256 }; + bool has_canon = false; +}; + +// Fraction, triangle count, longest remaining edge. Returning false cancels; what comes back is +// still watertight, because passes apply whole or not at all. +using SubdivideProgressFn = std::function; +// Whether the region being refined comes within `radius` mm of `point`. Called from several threads +// at once. +using SubdivideWithinFn = std::function; + +struct SubdivideResult +{ + TriSoup geometry; + // Output triangle -> input triangle it descends from, so per-face data survives with no remap. + std::vector face_parent_id; + bool safety_cap_hit = false; +}; + +// `face_excluded`: one entry per input triangle; non-zero means its interior is not refined unless the +// graded refinement reaches it (see `within`). Its edges still split when an included neighbour marks +// them, so no T-junction appears at the boundary. +// `fast` selects the cheap position-only indexer for previews. +// `within`, when given, grades the refinement: an edge splits only while it is longer than +// max_edge_length plus SUBDIVIDE_GRADE times its distance from the region. Away from the region the +// triangles are then left as whole pieces of the input's own 1->4 grid rather than refined throughout. +// An excluded triangle the refinement reaches - one of its edges splits - splits the same graded way, +// instead of fanning from its far corner to follow the edge it shares with an included one. +SubdivideResult subdivide(const TriSoup &geometry, double max_edge_length, + const std::vector &face_excluded = {}, bool fast = false, + int safety_cap = SUBDIVIDE_SAFETY_CAP, + const SubdivideProgressFn &on_progress = {}, + const SubdivideWithinFn &within = {}); + +// Displacement needs the same welding and sharp-edge clustering. +IndexedMesh to_indexed(const TriSoup &geometry); +IndexedMesh to_indexed_fast(const TriSoup &geometry); +TriSoup to_non_indexed(const VertStore &verts, const std::vector &indices, + const std::vector &face_excluded); + +} // namespace TextureBake +} // namespace Slic3r diff --git a/src/libslic3r/TextureDisplacement.cpp b/src/libslic3r/TextureDisplacement.cpp new file mode 100644 index 0000000000..862c6c9044 --- /dev/null +++ b/src/libslic3r/TextureDisplacement.cpp @@ -0,0 +1,5044 @@ +#include "TextureDisplacement.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "AABBTreeIndirect.hpp" +#include "MeshBoolean.hpp" +#include "Model.hpp" +#include "PNGReadWrite.hpp" +#include "TriangleSelector.hpp" +#include "TextureBake/TextureBakeDebug.hpp" +#include "TextureBake/TextureBakeMesh.hpp" +#include "TextureBake/TextureBakePipeline.hpp" + +namespace Slic3r { + +bool DecodedHeightTexture::texel_tap(const Vec2f &uv, bool tile_enabled, TextureTileMethod tile_method, + TexelTap &tap) const +{ + if (empty()) + return false; + + auto repeat01 = [](float x) { + x = std::fmod(x, 1.f); + return x < 0.f ? x + 1.f : x; + }; + // Standard mirrored-repeat: reflect back and forth every other unit, so tile edges always + // line up with themselves instead of jumping from one edge of the image to the other. + auto mirrored_repeat01 = [](float x) { + x = std::fmod(std::abs(x), 2.f); + return x > 1.f ? 2.f - x : x; + }; + + if (!tile_enabled && (uv.x() < 0.f || uv.x() >= 1.f || uv.y() < 0.f || uv.y() >= 1.f)) + // Outside the single, non-repeating placement entirely: no texture there, not "smeared + // edge pixel" - clamping the *coordinate* to [0, 1] would otherwise keep returning the + // border row/column's height forever in every direction, stretching it out to infinity. + return false; + + float u, v; + if (!tile_enabled) { + u = uv.x(); + v = uv.y(); + } else if (tile_method == TextureTileMethod::MirroredRepeat) { + u = mirrored_repeat01(uv.x()); + v = mirrored_repeat01(uv.y()); + } else { + u = repeat01(uv.x()); + v = repeat01(uv.y()); + } + + const float fx = u * float(width); + const float fy = v * float(height); + const int x0 = std::clamp(int(std::floor(fx)), 0, width - 1); + const int y0 = std::clamp(int(std::floor(fy)), 0, height - 1); + // Neighbour for bilinear filtering: wrap for tiling methods, clamp at the edge otherwise (a + // repeating neighbour would incorrectly blend against the opposite edge of the image). + tap.x0 = x0; + tap.y0 = y0; + tap.x1 = tile_enabled ? (x0 + 1) % width : std::min(x0 + 1, width - 1); + tap.y1 = tile_enabled ? (y0 + 1) % height : std::min(y0 + 1, height - 1); + tap.tx = fx - std::floor(fx); + tap.ty = fy - std::floor(fy); + return true; +} + +float DecodedHeightTexture::sample(const Vec2f &uv, bool tile_enabled, TextureTileMethod tile_method) const +{ + TexelTap tap; + if (!texel_tap(uv, tile_enabled, tile_method, tap)) + return 0.f; + const int x0 = tap.x0, y0 = tap.y0, x1 = tap.x1, y1 = tap.y1; + const float tx = tap.tx, ty = tap.ty; + + auto at = [this](int x, int y) { return float(pixels[size_t(y) * size_t(width) + size_t(x)]) / 255.f; }; + const float top = at(x0, y0) * (1.f - tx) + at(x1, y0) * tx; + const float bottom = at(x0, y1) * (1.f - tx) + at(x1, y1) * tx; + return top * (1.f - ty) + bottom * ty; +} + +Vec3f DecodedHeightTexture::sample_color(const Vec2f &uv, bool tile_enabled, TextureTileMethod tile_method) const +{ + TexelTap tap; + if (!has_color() || !texel_tap(uv, tile_enabled, tile_method, tap)) + return Vec3f::Zero(); + + auto at = [this](int x, int y) { + const size_t i = (size_t(y) * size_t(width) + size_t(x)) * 3; + return Vec3f(float(rgb[i]) / 255.f, float(rgb[i + 1]) / 255.f, float(rgb[i + 2]) / 255.f); + }; + const Vec3f top = at(tap.x0, tap.y0) * (1.f - tap.tx) + at(tap.x1, tap.y0) * tap.tx; + const Vec3f bottom = at(tap.x0, tap.y1) * (1.f - tap.tx) + at(tap.x1, tap.y1) * tap.tx; + return top * (1.f - tap.ty) + bottom * tap.ty; +} + +namespace { +// Decoding a PNG (zlib inflate + defilter) is real work, and image_data never changes in place +// once assigned to a layer (a new texture always gets a brand new image_data), so the decoded +// result can be cached for the lifetime of that specific image_data allocation. This matters +// because the GUI's live preview calls decode_height_texture() again on every rebuild (every +// paint stroke / parameter tweak), which would otherwise re-decode the same unchanged bytes over +// and over. Keyed by a weak_ptr (not just the raw pointer) so a freed image_data's address being +// reused by an unrelated later allocation can never alias a stale cache entry: a weak_ptr to a +// destroyed object always fails to lock, forcing a correct re-decode instead of a false hit. +struct DecodedTextureCache +{ + std::mutex mutex; + std::unordered_map>, DecodedHeightTexture>> entries; +}; +DecodedTextureCache g_decoded_texture_cache; + +// The smoothed copy is cached too, one per image: the thumbnail, the shaded-preview height texture, the +// colour texture, the projector texture, the UV editor's background and the preview job all ask for +// the same (image, smoothing) pair in the same frame while the Smoothing slider moves, and each of them +// blurring its own copy is what froze the UI. Keyed like the raw cache; a different smoothing value +// simply replaces the entry. +struct SmoothedTextureCache +{ + struct Entry + { + std::weak_ptr> source; + float smoothing = 0.f; + DecodedHeightTexture texture; + }; + std::mutex mutex; + std::unordered_map entries; +}; +SmoothedTextureCache g_smoothed_texture_cache; +} // namespace + +namespace { +// A few passes of a separable box blur approximate a Gaussian, cheaply. `radius` is in whole texels; +// 0 is a no-op. Wraps at the edges so a tiling height map stays seamless after smoothing. Operates on +// the grayscale byte buffer in place. +// +// Each pass is a sliding window - one add and one subtract per texel - so the cost is the image size, +// not the image size times the radius. The Smoothing slider drives this on every frame it moves, for +// every consumer of the layer, and the radius goes up to 48 texels: the per-window loop this replaces +// stalled the UI for seconds on a large map. Rows (and column blocks) run in parallel. The rounding is +// the old code's exactly, so a blur gives the same bytes as before. +void smooth_height_pixels_box(std::vector &pixels, int width, int height, int radius) +{ + if (radius <= 0 || width <= 0 || height <= 0 || pixels.size() != size_t(width) * size_t(height)) + return; + + const int window = 2 * radius + 1; + const float inv = 1.f / float(window); + const auto wrap = [](int i, int n) { return (i % n + n) % n; }; + std::vector tmp(pixels.size()); + + for (int pass = 0; pass < 2; ++pass) { // two passes -> smoother than a single box + // Horizontal: a running sum per row. + tbb::parallel_for(tbb::blocked_range(0, height), [&](const tbb::blocked_range &r) { + for (int y = r.begin(); y < r.end(); ++y) { + const uint8_t *src = pixels.data() + size_t(y) * size_t(width); + uint8_t *dst = tmp.data() + size_t(y) * size_t(width); + uint32_t sum = 0; + for (int k = -radius; k <= radius; ++k) + sum += src[wrap(k, width)]; + for (int x = 0; x < width; ++x) { + dst[x] = uint8_t(std::lround(float(sum) * inv)); + sum += src[wrap(x + radius + 1, width)]; + sum -= src[wrap(x - radius, width)]; + } + } + }); + // Vertical: one running sum per column, advanced row by row so the reads stay row-major. + tbb::parallel_for(tbb::blocked_range(0, width, 256), [&](const tbb::blocked_range &r) { + std::vector sum(size_t(r.size()), 0); + for (int k = -radius; k <= radius; ++k) { + const uint8_t *row = tmp.data() + size_t(wrap(k, height)) * size_t(width); + for (int x = r.begin(); x < r.end(); ++x) + sum[size_t(x - r.begin())] += row[x]; + } + for (int y = 0; y < height; ++y) { + uint8_t *dst = pixels.data() + size_t(y) * size_t(width); + const uint8_t *add = tmp.data() + size_t(wrap(y + radius + 1, height)) * size_t(width); + const uint8_t *sub = tmp.data() + size_t(wrap(y - radius, height)) * size_t(width); + for (int x = r.begin(); x < r.end(); ++x) { + uint32_t &sx = sum[size_t(x - r.begin())]; + dst[x] = uint8_t(std::lround(float(sx) * inv)); + sx += add[x]; + sx -= sub[x]; + } + } + }); + } +} + +// The same blur with a *continuous* radius, which is what the Smoothing slider drives. +// +// A box blur can only work in whole texels, so mapping the slider straight onto a rounded radius +// made it move in visible jumps - and its very first step off zero was a full one-texel blur rather +// than a hint of one, which is what made the control feel like it switched on rather than ramped up. +// Blur at the next whole texel up and cross-fade the raw image back in by the fraction left over: +// below one texel that fade *is* the sub-texel kernel, and above it it turns each integer step into +// a continuous ramp. +void smooth_height_pixels(std::vector &pixels, int width, int height, float radius) +{ + if (radius <= 0.f || width <= 0 || height <= 0 || pixels.size() != size_t(width) * size_t(height)) + return; + + const int whole = std::max(1, int(std::ceil(radius))); + const float mix = std::clamp(radius / float(whole), 0.f, 1.f); + const std::vector raw = (mix < 0.999f) ? pixels : std::vector{}; + smooth_height_pixels_box(pixels, width, height, whole); + if (!raw.empty()) + for (size_t i = 0; i < pixels.size(); ++i) + pixels[i] = uint8_t(std::lround(float(raw[i]) + (float(pixels[i]) - float(raw[i])) * mix)); +} +} // namespace + +DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer) +{ + DecodedHeightTexture result; + if (layer.empty()) + return result; + + // The raw (unsmoothed) decode is what gets cached, keyed by the image_data allocation - decoding + // a PNG is the expensive part and never changes for a given image. Smoothing is applied afterwards + // to a throwaway copy, so moving the smoothing slider never invalidates the decode cache. + const void *key = layer.image_data.get(); + bool have_raw = false; + { + std::lock_guard lock(g_decoded_texture_cache.mutex); + auto it = g_decoded_texture_cache.entries.find(key); + if (it != g_decoded_texture_cache.entries.end() && it->second.first.lock() == layer.image_data) { + result = it->second.second; + have_raw = true; + } + } + + if (!have_raw) { + const png::ReadBuf rbuf{ layer.image_data->data(), layer.image_data->size() }; + if (!png::is_png(rbuf)) + // PNG only. The GUI converts any other imported format (jpg, bmp, ...) on import, so this + // code needs no dependency on wxWidgets/libjpeg to read arbitrary user images. + return result; + + png::ImageGreyscale img; + if (png::decode_png(rbuf, img) && img.cols > 0 && img.rows > 0) { + // The shipped library, and anything imported before colour was kept. + result.width = int(img.cols); + result.height = int(img.rows); + result.pixels = std::move(img.buf); + } else { + // A colour source: keep the colour, and take the height from its luminance. The + // coefficients are wxImage::ConvertToGreyscale()'s, which is what the importer used to + // apply on the way in - so a texture that used to be flattened to grey at import time + // displaces identically now that its colour is preserved. + // The loop below steps bytes_per_pixel per texel, which only holds at 8 bits per channel: + // decode_colored_png() does not narrow a 16-bit image, so that would read as noise. + png::ImageColorscale col; + if (!png::decode_colored_png(rbuf, col) || col.cols == 0 || col.rows == 0 || + col.bytes_per_pixel < 3 || col.buf.size() != col.cols * col.rows * size_t(col.bytes_per_pixel)) + return result; + + const int w = int(col.cols); + const int h = int(col.rows); + const size_t bpp = size_t(col.bytes_per_pixel); + result.width = w; + result.height = h; + result.pixels.resize(size_t(w) * size_t(h)); + result.rgb.resize(size_t(w) * size_t(h) * 3); + // decode_colored_png() hands its buffer back bottom-up - it is shared with the CLI's + // plate-thumbnail loader, which expects that - while this type, and decode_png()'s + // grayscale path above, are top-to-bottom. Reverse the rows on the way in so a colour + // height map displaces the same way up as a grayscale one. + for (int y = 0; y < h; ++y) + for (int x = 0; x < w; ++x) { + const uint8_t *src = col.buf.data() + (size_t(h - 1 - y) * size_t(w) + size_t(x)) * bpp; + const size_t dst = size_t(y) * size_t(w) + size_t(x); + const uint8_t r = src[0], g = src[1], b = src[2]; + result.rgb[dst * 3] = r; + result.rgb[dst * 3 + 1] = g; + result.rgb[dst * 3 + 2] = b; + result.pixels[dst] = uint8_t(std::lround(0.299 * r + 0.587 * g + 0.114 * b)); + } + } + + std::lock_guard lock(g_decoded_texture_cache.mutex); + // Opportunistically drop entries for image_data that no longer exists anywhere, so the + // cache doesn't grow without bound across many add/remove-texture cycles in a long session. + auto &entries = g_decoded_texture_cache.entries; + for (auto it = entries.begin(); it != entries.end();) + it = it->second.first.expired() ? entries.erase(it) : std::next(it); + entries[key] = { std::weak_ptr>(layer.image_data), result }; + } + + // Smoothing radius scales with the texture so the same slider value blurs the same *fraction* of + // the image whatever resolution it came in at, and stays continuous in the slider - see + // smooth_height_pixels(). The cap is a cost limit, not part of the mapping: the blur is + // O(width * height * radius) per pass, so a large map with the slider at the top would otherwise + // stall every preview rebuild. + if (layer.smoothing > 0.f) { + { + std::lock_guard lock(g_smoothed_texture_cache.mutex); + auto it = g_smoothed_texture_cache.entries.find(key); + if (it != g_smoothed_texture_cache.entries.end() && it->second.smoothing == layer.smoothing && + it->second.source.lock() == layer.image_data) + return it->second.texture; + } + const float span = 0.05f * float(std::min(result.width, result.height)); + const float radius = std::clamp(layer.smoothing, 0.f, 1.f) * std::min(span, 48.f); + smooth_height_pixels(result.pixels, result.width, result.height, radius); + // Colour gets the same blur, per channel. It is the same knob for the same reason: detail in + // the image finer than the mesh can carry is noise either way, and low-passing it here is the + // cheapest place to remove it - one blur of the texture, rather than a fight per triangle. + if (result.has_color()) { + const size_t n = size_t(result.width) * size_t(result.height); + std::vector channel(n); + for (int c = 0; c < 3; ++c) { + for (size_t i = 0; i < n; ++i) + channel[i] = result.rgb[i * 3 + size_t(c)]; + smooth_height_pixels(channel, result.width, result.height, radius); + for (size_t i = 0; i < n; ++i) + result.rgb[i * 3 + size_t(c)] = channel[i]; + } + } + std::lock_guard lock(g_smoothed_texture_cache.mutex); + auto &entries = g_smoothed_texture_cache.entries; + for (auto it = entries.begin(); it != entries.end();) + it = it->second.source.expired() ? entries.erase(it) : std::next(it); + entries[key] = { std::weak_ptr>(layer.image_data), layer.smoothing, result }; + } + return result; +} + +namespace { +struct TextureDetailCache +{ + std::mutex mutex; + std::unordered_map>, TextureDetail>> entries; +}; +TextureDetailCache g_texture_detail_cache; +} // namespace + +TextureDetail analyze_texture_detail(const TextureDisplacementLayer &layer) +{ + TextureDetail out; + if (layer.empty()) + return out; + const void *key = layer.image_data.get(); + { + std::lock_guard lock(g_texture_detail_cache.mutex); + auto it = g_texture_detail_cache.entries.find(key); + if (it != g_texture_detail_cache.entries.end() && it->second.first.lock() == layer.image_data) + return it->second.second; + } + // On the image as imported: the Smoothing slider must not move the recommendation around. + TextureDisplacementLayer raw = layer; + raw.smoothing = 0.f; + const DecodedHeightTexture tex = decode_height_texture(raw); + const int w = tex.width, h = tex.height; + if (w >= 3 && h >= 3) { + double sum = 0.0; + size_t sharp = 0, n = 0; + for (int y = 1; y < h - 1; ++y) { + const uint8_t *row = tex.pixels.data() + size_t(y) * size_t(w); + for (int x = 1; x < w - 1; ++x) { + const float dx = 0.5f * (float(row[x + 1]) - float(row[x - 1])); + const float dy = 0.5f * (float(row[x + w]) - float(row[x - w])); + const float mag = std::sqrt(dx * dx + dy * dy); + sum += mag; + sharp += mag > 30.f; + ++n; + } + } + out.mean_gradient = float(sum / double(n)); + out.sharp_fraction = float(sharp) / float(n); + if (out.sharp_fraction > 0.15f || out.mean_gradient > 50.f) out.pixels_per_edge = 1.f; + else if (out.sharp_fraction > 0.05f || out.mean_gradient > 20.f) out.pixels_per_edge = 1.5f; + else if (out.mean_gradient > 8.f) out.pixels_per_edge = 2.5f; + else out.pixels_per_edge = 4.f; + + // Colour spread: a coarse histogram (8 levels per channel, 64 levels for a grey image) and + // the share of the eight fullest bins. Tiles, logos and camouflage put nearly everything in a + // handful of bins even with some texture noise; a photograph spreads across hundreds. + std::vector bins(size_t(8 * 8 * 8), 0); + const size_t npx = size_t(w) * size_t(h); + if (tex.has_color()) + for (size_t i = 0; i < npx; ++i) + ++bins[size_t(tex.rgb[i * 3] >> 5) * 64 + size_t(tex.rgb[i * 3 + 1] >> 5) * 8 + size_t(tex.rgb[i * 3 + 2] >> 5)]; + else + for (size_t i = 0; i < npx; ++i) + ++bins[size_t(tex.pixels[i] >> 2) * 8]; // 64 grey levels, spread over distinct bins + std::partial_sort(bins.begin(), bins.begin() + 8, bins.end(), std::greater()); + uint64_t top = 0; + for (int i = 0; i < 8; ++i) + top += bins[size_t(i)]; + out.flat_share = float(double(top) / double(npx)); + out.flat_colors = out.flat_share >= 0.85f; + } + std::lock_guard lock(g_texture_detail_cache.mutex); + auto &entries = g_texture_detail_cache.entries; + for (auto it = entries.begin(); it != entries.end();) + it = it->second.first.expired() ? entries.erase(it) : std::next(it); + entries[key] = { std::weak_ptr>(layer.image_data), out }; + return out; +} + +V2Resolution recommend_v2_resolution(const indexed_triangle_set &mesh, + const std::vector &layers, + const Transform3d &volume_to_world) +{ + // The defaults on model load: edge = diagonal / 250 in [0.05, 5] mm, budget 750 k. A texture-driven + // variant (resolution from the texture's own detail) was measured to give better walls on step + // textures at 2-10x the bake time and up to 2 M output triangles, and was not worth that; these + // defaults stayed. The texel size and sharpness are still reported for the panel. + constexpr double EDGE_MIN = 0.05, EDGE_MAX = 5.0, DIAG_DIVISOR = 250.0; + constexpr int BUDGET_K = 750; + + V2Resolution out; + if (mesh.vertices.empty()) + return out; + for (const TextureDisplacementLayer &layer : layers) { + if (layer.empty() || layer.tiling_scale <= 0.f) + continue; + const DecodedHeightTexture &tex = decode_height_texture(layer); + if (tex.width <= 0) + continue; + const float texel = layer.tiling_scale / float(tex.width); + if (out.texel_mm <= 0.f || texel < out.texel_mm) { + out.texel_mm = texel; + out.pixels_per_edge = analyze_texture_detail(layer).pixels_per_edge; + } + } + Vec3d bmin = Vec3d::Constant(std::numeric_limits::max()), bmax = -bmin; + for (const Vec3f &v : mesh.vertices) { + const Vec3d w = volume_to_world * v.cast(); + bmin = bmin.cwiseMin(w); + bmax = bmax.cwiseMax(w); + } + const double diag = (bmax - bmin).norm(); + double edge = std::clamp(diag / DIAG_DIVISOR, EDGE_MIN, EDGE_MAX); + edge = std::max(EDGE_MIN, std::ceil(edge * 100.0) / 100.0); + out.edge_mm = float(edge); + out.budget_k = BUDGET_K; + out.budget_bound = false; + return out; +} + +Vec2f project_planar(const Vec3f &position, const Vec3f &normal) +{ + // Planar-project onto the two axes orthogonal to the dominant component of `normal`. Called + // with each vertex's *own* normal (TextureProjectionMethod::Triplanar), this is a standard + // tri-planar/cube projection; a patch spanning several differently-oriented faces gets each + // face projected along its own best-fit axis instead of all faces sharing one axis picked + // from a single averaged normal (which looks correct on one face but visibly distorts on any + // other face in the same patch - exactly the bug an earlier version of this feature had). + const Vec3f n = normal.cwiseAbs(); + if (n.x() >= n.y() && n.x() >= n.z()) + return Vec2f(position.y(), position.z()); + if (n.y() >= n.x() && n.y() >= n.z()) + return Vec2f(position.x(), position.z()); + return Vec2f(position.x(), position.y()); +} + +namespace { +// Wrapped around patch_axis, centered at patch_center. u is the arc length (mm) around the axis at +// this point's own radius, v is the signed distance along the axis - a reasonable approximation +// for roughly cylindrical selections, not an exact fit for arbitrary geometry. +Vec2f project_cylindrical(const Vec3f &position, const Vec3f &patch_center, const Vec3f &patch_axis) +{ + Vec3f up = patch_axis; + up = (up.norm() > 1e-8f) ? Vec3f(up.normalized()) : Vec3f::UnitZ(); + const Vec3f arbitrary = (std::abs(up.dot(Vec3f::UnitZ())) < 0.9f) ? Vec3f::UnitZ() : Vec3f::UnitX(); + const Vec3f right = Vec3f(up.cross(arbitrary).normalized()); + const Vec3f fwd = Vec3f(right.cross(up).normalized()); + + const Vec3f rel = position - patch_center; + const float along_axis = rel.dot(up); + const float x = rel.dot(right); + const float y = rel.dot(fwd); + const float radius = std::sqrt(x * x + y * y); + const float angle = std::atan2(y, x); + + return Vec2f(angle * radius, along_axis); +} + +// Longitude/latitude around patch_center. u/v are scaled by this point's own distance from the +// center so the result is in roughly the same mm-ish units tiling_scale expects, rather than bare +// radians - again an approximation, not an exact geodesic parametrization. +Vec2f project_spherical(const Vec3f &position, const Vec3f &patch_center) +{ + const Vec3f rel = position - patch_center; + const float radius = rel.norm(); + if (radius < 1e-8f) + return Vec2f::Zero(); + + const Vec3f dir = rel / radius; + const float longitude = std::atan2(dir.y(), dir.x()); + const float latitude = std::asin(std::clamp(dir.z(), -1.f, 1.f)); + return Vec2f(longitude, latitude) * radius; +} + +// CGAL's LSCM parameterizer expects a clean mesh with no isolated (unreferenced) vertices - but +// `patch` here (from TriangleSelector::get_facets_strict()) carries the *entire* mesh's vertex +// array, only its `indices` filtered to the painted triangles. Build a compacted copy referencing +// only the vertices `patch.indices` actually uses, plus a map back to the original vertex index so +// the resulting per-vertex UVs can be looked up by the caller's own (uncompacted) indexing. +indexed_triangle_set compact_patch_with_map(const indexed_triangle_set &patch, std::vector &original_to_compact) +{ + original_to_compact.assign(patch.vertices.size(), -1); + indexed_triangle_set compact; + compact.vertices.reserve(patch.vertices.size()); + compact.indices.reserve(patch.indices.size()); + for (const stl_triangle_vertex_indices &tri : patch.indices) { + stl_triangle_vertex_indices new_tri; + for (int i = 0; i < 3; ++i) { + const int vi = tri[i]; + if (original_to_compact[vi] < 0) { + original_to_compact[vi] = int(compact.vertices.size()); + compact.vertices.push_back(patch.vertices[vi]); + } + new_tri[i] = original_to_compact[vi]; + } + compact.indices.push_back(new_tri); + } + return compact; +} + +} // namespace + +namespace { + +// Union-find over triangles, used to grow charts. +struct UnionFind +{ + std::vector parent; + explicit UnionFind(size_t n) : parent(n) { std::iota(parent.begin(), parent.end(), 0); } + int find(int x) + { + while (parent[size_t(x)] != x) { + parent[size_t(x)] = parent[size_t(parent[size_t(x)])]; // path halving + x = parent[size_t(x)]; + } + return x; + } + void unite(int a, int b) + { + a = find(a); + b = find(b); + if (a != b) + parent[size_t(b)] = a; + } +}; + +uint64_t undirected_edge_key(int a, int b) +{ + if (a > b) + std::swap(a, b); + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); +} + +Vec3f face_normal(const indexed_triangle_set &mesh, const stl_triangle_vertex_indices &tri) +{ + const Vec3f n = (mesh.vertices[tri[1]] - mesh.vertices[tri[0]]).cross(mesh.vertices[tri[2]] - mesh.vertices[tri[0]]); + const float len = n.norm(); + return (len > 1e-12f) ? Vec3f(n / len) : Vec3f::UnitZ(); +} + +// Whether a chart can be laid flat as one island: a topological disk (V - E + F = 1 with a single boundary loop, +// which LSCM requires) whose faces all point within ~100 degrees of their average - past that even a disk folds +// over itself when flattened. Degenerate faces carry no direction and are left out of the normal test. +bool chart_is_flattenable(const indexed_triangle_set &mesh, const std::vector &normals, const std::vector &faces) +{ + constexpr float MIN_NORMAL_COS = -0.17f; // cos(100 deg) + + std::unordered_map edge_use; + std::unordered_map local_vertex; + edge_use.reserve(faces.size() * 2); + local_vertex.reserve(faces.size()); + Vec3f normal_sum = Vec3f::Zero(); + for (const int f : faces) { + const stl_triangle_vertex_indices &tri = mesh.indices[size_t(f)]; + for (int i = 0; i < 3; ++i) { + ++edge_use[undirected_edge_key(tri[i], tri[(i + 1) % 3])]; + local_vertex.emplace(tri[i], int(local_vertex.size())); + } + normal_sum += normals[size_t(f)]; + } + if (int(local_vertex.size()) - int(edge_use.size()) + int(faces.size()) != 1) + return false; + + UnionFind loops(local_vertex.size()); + int boundary_seed = -1; + for (const auto &[key, uses] : edge_use) { + if (uses > 2) + return false; // non-manifold + if (uses == 1) { + const int a = local_vertex[int(key >> 32)], b = local_vertex[int(uint32_t(key))]; + loops.unite(a, b); + boundary_seed = a; + } + } + if (boundary_seed < 0) + return false; // closed + const int loop = loops.find(boundary_seed); + for (const auto &[key, uses] : edge_use) + if (uses == 1 && loops.find(local_vertex[int(key >> 32)]) != loop) + return false; // a second boundary loop: a ring, or a disk with a hole + + const float len = normal_sum.norm(); + if (len < 1e-6f) + return false; + const Vec3f mean = normal_sum / len; + for (const int f : faces) { + const stl_triangle_vertex_indices &tri = mesh.indices[size_t(f)]; + const bool degenerate = (mesh.vertices[tri[1]] - mesh.vertices[tri[0]]).cross(mesh.vertices[tri[2]] - mesh.vertices[tri[0]]) + .squaredNorm() < 1e-20f; + if (!degenerate && normals[size_t(f)].dot(mean) < MIN_NORMAL_COS) + return false; + } + return true; +} + +// Which side of a cut each face of an unflattenable chart goes to (true / false, parallel to `faces`). The cut +// separates the faces' normals along their widest spread, so a tube splits lengthwise into two half-tubes and a +// closed sphere into two hemispheres. Where the normals barely vary (a flat ring) it splits the face centroids +// along their longest axis instead. +std::vector split_chart_sides(const indexed_triangle_set &mesh, const std::vector &normals, const std::vector &faces) +{ + const auto principal_axis = [](const std::vector &samples, Vec3f &mean, Vec3f &axis) { + mean = Vec3f::Zero(); + for (const Vec3f &s : samples) + mean += s; + mean /= float(samples.size()); + Eigen::Matrix3f covariance = Eigen::Matrix3f::Zero(); + for (const Vec3f &s : samples) { + const Vec3f d = s - mean; + covariance += d * d.transpose(); + } + const Eigen::SelfAdjointEigenSolver solver(covariance); + axis = solver.eigenvectors().col(2); // eigenvalues come sorted ascending + return solver.eigenvalues()(2) / float(samples.size()); + }; + + std::vector samples(faces.size()); + for (size_t i = 0; i < faces.size(); ++i) + samples[i] = normals[size_t(faces[i])]; + Vec3f mean, axis; + if (principal_axis(samples, mean, axis) < 1e-3f) { + for (size_t i = 0; i < faces.size(); ++i) { + const stl_triangle_vertex_indices &tri = mesh.indices[size_t(faces[i])]; + samples[i] = (mesh.vertices[tri[0]] + mesh.vertices[tri[1]] + mesh.vertices[tri[2]]) / 3.f; + } + principal_axis(samples, mean, axis); + } + std::vector side(faces.size()); + for (size_t i = 0; i < faces.size(); ++i) + side[i] = (samples[i] - mean).dot(axis) > 0.f; + return side; +} + +// Groups triangles into charts. First two triangles sharing an edge join the same chart only if the angle between +// their normals is below `seam_angle_deg` (and the edge is not a marked seam): everything sharper is a seam. The +// test uses each face's own normal - averaging in its neighbours, as this once did, cuts low-poly flat faces apart, +// because the two triangles of one cube face average in different neighbouring faces. +// +// Then every chart that cannot be laid flat as one island (see chart_is_flattenable()) is cut in two and each +// connected piece checked again: a cylinder's smooth side is one chart by angle but a ring, which no flattening +// can open without a cut, and a sphere is closed. +std::vector segment_into_charts(const indexed_triangle_set &mesh, const std::vector &normals, + float seam_angle_deg, const std::unordered_set &seam_keys, + int &chart_count) +{ + constexpr int MAX_SPLIT_DEPTH = 8; + const int n_faces = int(mesh.indices.size()); + const float cos_threshold = std::cos(std::clamp(seam_angle_deg, 0.f, 180.f) * float(M_PI) / 180.f); + + // Each shared edge, with the (up to two) faces on it. + std::unordered_map> edge_faces; + edge_faces.reserve(size_t(n_faces) * 3); + for (int f = 0; f < n_faces; ++f) { + const stl_triangle_vertex_indices &tri = mesh.indices[size_t(f)]; + for (int i = 0; i < 3; ++i) { + const uint64_t key = undirected_edge_key(tri[i], tri[(i + 1) % 3]); + const auto [it, inserted] = edge_faces.emplace(key, std::make_pair(f, -1)); + if (!inserted) + it->second.second = f; + } + } + + // Faces joined across each edge that does not cut. A face has three edges, so at most three such neighbours. + std::vector> adjacent(static_cast(n_faces), { -1, -1, -1 }); + const auto link = [&adjacent](int f, int nb) { + for (int &slot : adjacent[size_t(f)]) + if (slot < 0) { + slot = nb; + return; + } + }; + for (const auto &[key, fp] : edge_faces) { + if (fp.second < 0 || fp.first == fp.second) + continue; // a boundary edge of the patch, nothing on the far side to join + // A manually/auto marked seam always cuts, whatever the dihedral angle - that is exactly + // what lets "mark seam" / "cut island" split a chart that is otherwise flat enough to merge. + if (!seam_keys.empty() && seam_keys.count(key)) + continue; + if (normals[size_t(fp.first)].dot(normals[size_t(fp.second)]) >= cos_threshold) { + link(fp.first, fp.second); + link(fp.second, fp.first); + } + } + + // Connected pieces of `faces` over `adjacent`, staying within each face's current `group`. + std::vector group(static_cast(n_faces), 0), visited(static_cast(n_faces), -1); + int visit_pass = 0; + const auto connected_pieces = [&](const std::vector &faces, std::vector> &out) { + const int pass = visit_pass++; + std::vector stack; + for (const int seed : faces) { + if (visited[size_t(seed)] == pass) + continue; + visited[size_t(seed)] = pass; + std::vector piece{ seed }; + stack.assign(1, seed); + while (!stack.empty()) { + const int f = stack.back(); + stack.pop_back(); + for (const int nb : adjacent[size_t(f)]) + if (nb >= 0 && visited[size_t(nb)] != pass && group[size_t(nb)] == group[size_t(f)]) { + visited[size_t(nb)] = pass; + piece.push_back(nb); + stack.push_back(nb); + } + } + out.push_back(std::move(piece)); + } + }; + + std::vector all_faces(static_cast(n_faces)); + std::iota(all_faces.begin(), all_faces.end(), 0); + std::vector> pieces; + connected_pieces(all_faces, pieces); + std::vector, int>> pending; // a piece, and how many cuts produced it + for (std::vector &piece : pieces) + pending.emplace_back(std::move(piece), 0); + + std::vector> charts; + int next_group = 1; + while (!pending.empty()) { + std::vector faces = std::move(pending.back().first); + const int depth = pending.back().second; + pending.pop_back(); + if (faces.size() < 2 || depth >= MAX_SPLIT_DEPTH || chart_is_flattenable(mesh, normals, faces)) { + charts.push_back(std::move(faces)); + continue; + } + const std::vector side = split_chart_sides(mesh, normals, faces); + std::vector halves[2]; + for (size_t i = 0; i < faces.size(); ++i) + halves[side[i] ? 1 : 0].push_back(faces[i]); + if (halves[0].empty() || halves[1].empty()) { + charts.push_back(std::move(faces)); + continue; + } + for (std::vector &half : halves) { + for (const int f : half) + group[size_t(f)] = next_group; + ++next_group; + pieces.clear(); + connected_pieces(half, pieces); + for (std::vector &piece : pieces) + pending.emplace_back(std::move(piece), depth + 1); + } + } + + // Chart ids in first-encountered-triangle order, which TextureIsland indexing documents. + std::vector> first_face(charts.size()); + for (size_t c = 0; c < charts.size(); ++c) + first_face[c] = { *std::min_element(charts[c].begin(), charts[c].end()), c }; + std::sort(first_face.begin(), first_face.end()); + + std::vector chart_of(static_cast(n_faces), -1); + for (size_t id = 0; id < first_face.size(); ++id) + for (const int f : charts[first_face[id].second]) + chart_of[size_t(f)] = int(id); + chart_count = int(charts.size()); + return chart_of; +} + +// Projects a chart onto an orthonormal basis of its own average normal. This is *isometric* for a +// flat chart - lengths and angles come out exactly right - which is why a flat chart never needs a +// solve at all, and why this also serves as the fallback for a chart LSCM cannot handle. +std::vector project_to_tangent_plane(const indexed_triangle_set &chart, const Vec3f &normal) +{ + const Vec3f seed = (std::abs(normal.z()) < 0.9f) ? Vec3f::UnitZ() : Vec3f::UnitX(); + const Vec3f u = Vec3f(seed.cross(normal).normalized()); + const Vec3f v = Vec3f(normal.cross(u).normalized()); + + std::vector uvs(chart.vertices.size()); + for (size_t i = 0; i < chart.vertices.size(); ++i) + uvs[i] = Vec2f(chart.vertices[i].dot(u), chart.vertices[i].dot(v)); + return uvs; +} + +float area_3d(const indexed_triangle_set &mesh) +{ + float area = 0.f; + for (const stl_triangle_vertex_indices &t : mesh.indices) + area += 0.5f * (mesh.vertices[t[1]] - mesh.vertices[t[0]]).cross(mesh.vertices[t[2]] - mesh.vertices[t[0]]).norm(); + return area; +} + +float area_2d(const std::vector &uvs, const std::vector &indices) +{ + float area = 0.f; + for (const stl_triangle_vertex_indices &t : indices) { + const Vec2f e0 = uvs[size_t(t[1])] - uvs[size_t(t[0])]; + const Vec2f e1 = uvs[size_t(t[2])] - uvs[size_t(t[0])]; + area += 0.5f * std::abs(e0.x() * e1.y() - e0.y() * e1.x()); + } + return area; +} + +// FNV-1a over the patch's geometry plus the seam angle. The unwrap depends on nothing else about a +// layer - not depth, tiling, rotation, offset or even which texture is on it - so keying the cache +// on just this is what lets every one of those sliders be dragged without paying for a re-solve. +uint64_t unwrap_cache_key(const indexed_triangle_set &patch, float seam_angle_deg, float padding_mm, + const std::vector> &seam_edges) +{ + uint64_t h = 1469598103934665603ull; + const auto mix = [&h](const void *data, size_t bytes) { + const unsigned char *p = static_cast(data); + for (size_t i = 0; i < bytes; ++i) { + h ^= p[i]; + h *= 1099511628211ull; + } + }; + mix(patch.vertices.data(), patch.vertices.size() * sizeof(Vec3f)); + mix(patch.indices.data(), patch.indices.size() * sizeof(stl_triangle_vertex_indices)); + mix(&seam_angle_deg, sizeof(seam_angle_deg)); + mix(&padding_mm, sizeof(padding_mm)); + mix(seam_edges.data(), seam_edges.size() * sizeof(std::pair)); + return h; +} + +struct UnwrapCache +{ + std::mutex mutex; + std::unordered_map entries; +}; +UnwrapCache g_unwrap_cache; +const size_t UNWRAP_CACHE_MAX_ENTRIES = 8; + +} // namespace + +PatchUnwrap compute_patch_unwrap(const indexed_triangle_set &patch, float seam_angle_deg, float padding_mm, + const std::vector> &seam_edges) +{ + PatchUnwrap result; + if (patch.indices.empty()) + return result; + + const uint64_t key = unwrap_cache_key(patch, seam_angle_deg, padding_mm, seam_edges); + { + std::lock_guard lock(g_unwrap_cache.mutex); + if (auto it = g_unwrap_cache.entries.find(key); it != g_unwrap_cache.entries.end()) + return it->second; + } + + // CGAL wants a mesh with no unreferenced vertices; `patch` carries the whole mesh's vertex array + // (see get_facets_strict()), so compact it and keep the map back to the caller's numbering. + std::vector patch_to_compact; + const indexed_triangle_set compact = compact_patch_with_map(patch, patch_to_compact); + std::vector compact_to_patch(compact.vertices.size(), -1); + for (size_t vi = 0; vi < patch_to_compact.size(); ++vi) + if (patch_to_compact[vi] >= 0) + compact_to_patch[size_t(patch_to_compact[vi])] = int(vi); + + std::vector normals(compact.indices.size()); + for (size_t f = 0; f < compact.indices.size(); ++f) + normals[f] = face_normal(compact, compact.indices[f]); + + // Seam edges arrive in patch (== mesh) vertex space; translate to the compact numbering the + // segmentation runs in. An edge whose endpoints didn't both survive compaction is simply ignored. + std::unordered_set seam_keys; + seam_keys.reserve(seam_edges.size() * 2); + for (const auto &[a, b] : seam_edges) { + if (a < 0 || b < 0 || size_t(a) >= patch_to_compact.size() || size_t(b) >= patch_to_compact.size()) + continue; + const int ca = patch_to_compact[size_t(a)]; + const int cb = patch_to_compact[size_t(b)]; + if (ca >= 0 && cb >= 0) + seam_keys.insert(undirected_edge_key(ca, cb)); + } + + // Once the user has marked seams by hand, those seams define the islands: the automatic + // sharp-angle cutting must not keep splitting faces the user left un-seamed, or islands the user + // meant to be one piece never merge (the "seam angle overrides it" the user hit). So when any + // manual seam exists, the angle threshold is dropped to 180 degrees - nothing is cut except the + // marked seams. With no manual seams, the seam angle behaves exactly as before. + const float effective_seam_angle = seam_keys.empty() ? seam_angle_deg : 180.f; + int chart_count = 0; + const std::vector chart_of = segment_into_charts(compact, normals, effective_seam_angle, seam_keys, chart_count); + + struct FlatChart + { + std::vector uvs; + std::vector to_patch; // chart vertex -> patch vertex + std::vector indices; // chart-local + // Parallel to `indices`: the patch triangle each one came from. compact_patch_with_map() keeps + // the patch's triangle count *and* order, so a compact face index is already a patch face index. + std::vector faces; + Vec2f min = Vec2f::Zero(); + Vec2f size = Vec2f::Zero(); + }; + // static_cast, not size_t(...): the latter is a most-vexing-parse and declares a function. + std::vector charts(static_cast(chart_count)); + + for (int c = 0; c < chart_count; ++c) { + FlatChart &chart = charts[size_t(c)]; + + // Build the chart's own sub-mesh. Each chart gets its *own* compact->local vertex map, which + // is exactly what duplicates a seam vertex: it appears once in each chart that touches it, + // free to hold a different UV in each. + indexed_triangle_set chart_mesh; + std::vector compact_to_local(compact.vertices.size(), -1); + Vec3f normal_sum = Vec3f::Zero(); + for (size_t f = 0; f < compact.indices.size(); ++f) { + if (chart_of[f] != c) + continue; + const stl_triangle_vertex_indices &tri = compact.indices[f]; + // Area-weighted, so a chart's average normal isn't dragged around by slivers. + normal_sum += (compact.vertices[tri[1]] - compact.vertices[tri[0]]).cross(compact.vertices[tri[2]] - compact.vertices[tri[0]]); + + stl_triangle_vertex_indices local_tri; + for (int i = 0; i < 3; ++i) { + const int cv = tri[i]; + if (compact_to_local[size_t(cv)] < 0) { + compact_to_local[size_t(cv)] = int(chart_mesh.vertices.size()); + chart_mesh.vertices.push_back(compact.vertices[size_t(cv)]); + chart.to_patch.push_back(compact_to_patch[size_t(cv)]); + } + local_tri[i] = compact_to_local[size_t(cv)]; + } + chart_mesh.indices.push_back(local_tri); + chart.faces.push_back(int(f)); + } + if (chart_mesh.indices.empty()) + continue; + + const Vec3f chart_normal = (normal_sum.norm() > 1e-12f) ? Vec3f(normal_sum.normalized()) : Vec3f::UnitZ(); + + // Is the chart flat? Charts are grown by a *pairwise* angle threshold, so a chart can still + // curve gradually across many triangles - being merged is not the same as being planar. But + // when it is planar (a cube face, and after seam-cutting that is the common case), the + // tangent-plane projection is already the exact answer, and skipping the solve is the single + // biggest speed-up here. + bool planar = true; + for (size_t f = 0; f < compact.indices.size() && planar; ++f) + if (chart_of[f] == c) + planar = normals[f].dot(chart_normal) >= 0.9998f; // ~1 degree + + // Measured before chart_mesh.indices is moved out from under it, below - area_3d() iterates + // those indices, so taking it afterwards silently measures an empty mesh and returns 0. + const float mesh_area_3d = area_3d(chart_mesh); + + std::optional> uvs; + if (!planar) + uvs = MeshBoolean::cgal::parameterize_lscm(chart_mesh); + // Flat chart, or one LSCM refused (not a topological disk - closed, or holed). + chart.uvs = uvs ? std::move(*uvs) : project_to_tangent_plane(chart_mesh, chart_normal); + chart.indices = std::move(chart_mesh.indices); + + // LSCM's output is only defined up to a similarity, so charts come back at arbitrary and + // mutually inconsistent scales. Rescale each to its true surface area, so `Tile size (mm)` + // means the same thing on every chart and the texture doesn't change density across a seam. + const float uv_area = area_2d(chart.uvs, chart.indices); + if (uv_area > 1e-12f && mesh_area_3d > 1e-12f) { + const float scale = std::sqrt(mesh_area_3d / uv_area); + for (Vec2f &uv : chart.uvs) + uv *= scale; + } + + Vec2f lo(std::numeric_limits::max(), std::numeric_limits::max()); + Vec2f hi(std::numeric_limits::lowest(), std::numeric_limits::lowest()); + for (const Vec2f &uv : chart.uvs) { + lo = lo.cwiseMin(uv); + hi = hi.cwiseMax(uv); + } + chart.min = lo; + chart.size = hi - lo; + } + + // Shelf-pack the charts side by side so they don't overlap. Overlap would be harmless for a + // repeating texture but wrong for a non-tiled (decal) one, and it makes the UV editor unreadable. + float total_area = 0.f; + float widest = 0.f; + for (const FlatChart &chart : charts) { + total_area = total_area + chart.size.x() * chart.size.y(); + widest = std::max(widest, chart.size.x()); + } + const float shelf_width = std::max(widest, std::sqrt(std::max(total_area, 0.f)) * 1.4f); + // Negative padding means auto: a small fraction of the packed size, which is scale-independent + // and so does something sensible for a 5 mm patch and a 500 mm one alike. + const float margin = (padding_mm >= 0.f) ? padding_mm : std::max(shelf_width * 0.02f, 1e-4f); + + std::vector order(charts.size()); + std::iota(order.begin(), order.end(), 0); + std::sort(order.begin(), order.end(), // tallest first: the usual way to keep shelves tight + [&charts](int a, int b) { return charts[size_t(a)].size.y() > charts[size_t(b)].size.y(); }); + + float cursor_x = 0.f, cursor_y = 0.f, row_height = 0.f; + for (const int c : order) { + FlatChart &chart = charts[size_t(c)]; + if (chart.uvs.empty()) + continue; + if (cursor_x > 0.f && cursor_x + chart.size.x() > shelf_width) { + cursor_x = 0.f; + cursor_y += row_height + margin; + row_height = 0.f; + } + const Vec2f translation = Vec2f(cursor_x, cursor_y) - chart.min; + for (Vec2f &uv : chart.uvs) + uv += translation; + + cursor_x += chart.size.x() + margin; + row_height = std::max(row_height, chart.size.y()); + } + + // Concatenate the packed charts into the flat, duplicated-vertex form PatchUnwrap describes. + result.chart_centroid.assign(size_t(chart_count), Vec2f::Zero()); + for (int c = 0; c < chart_count; ++c) { + FlatChart &chart = charts[size_t(c)]; + const int base = int(result.uvs.size()); + result.uvs.insert(result.uvs.end(), chart.uvs.begin(), chart.uvs.end()); + result.source_vertex.insert(result.source_vertex.end(), chart.to_patch.begin(), chart.to_patch.end()); + result.vertex_chart.insert(result.vertex_chart.end(), chart.uvs.size(), c); + for (const stl_triangle_vertex_indices &tri : chart.indices) + result.indices.emplace_back(tri[0] + base, tri[1] + base, tri[2] + base); + result.source_face.insert(result.source_face.end(), chart.faces.begin(), chart.faces.end()); + + if (!chart.uvs.empty()) { + Vec2f sum = Vec2f::Zero(); + for (const Vec2f &uv : chart.uvs) + sum += uv; + result.chart_centroid[size_t(c)] = sum / float(chart.uvs.size()); + } + } + result.chart_count = chart_count; + + // Island outlines: an edge used by exactly one triangle. Charts have disjoint vertex sets (seam + // vertices are duplicated), so an edge along a seam shows up once in each chart and is correctly + // reported as a boundary of both. + { + std::unordered_map edge_use; + edge_use.reserve(result.indices.size() * 3); + for (const stl_triangle_vertex_indices &tri : result.indices) + for (int i = 0; i < 3; ++i) + ++edge_use[undirected_edge_key(tri[i], tri[(i + 1) % 3])]; + for (const stl_triangle_vertex_indices &tri : result.indices) + for (int i = 0; i < 3; ++i) { + const int a = tri[i], b = tri[(i + 1) % 3]; + if (edge_use[undirected_edge_key(a, b)] == 1) + result.boundary_edges.emplace_back(a, b); + } + } + + { + std::lock_guard lock(g_unwrap_cache.mutex); + // A patch changes on every paint stroke, so this would grow without bound over a session. + // Nothing here is worth an LRU: the working set is "the patch I am editing right now". + if (g_unwrap_cache.entries.size() >= UNWRAP_CACHE_MAX_ENTRIES) + g_unwrap_cache.entries.clear(); + g_unwrap_cache.entries.emplace(key, result); + } + return result; +} + +Eigen::Matrix island_transform_matrix(int chart, const PatchUnwrap &unwrap, const std::vector &islands) +{ + Eigen::Matrix m; + m << 1.f, 0.f, 0.f, + 0.f, 1.f, 0.f; + if (chart < 0 || size_t(chart) >= islands.size() || size_t(chart) >= unwrap.chart_centroid.size()) + return m; // no hand placement for this island: leave it where the packing put it + + const TextureIsland &island = islands[size_t(chart)]; + const Vec2f centre = unwrap.chart_centroid[size_t(chart)]; + + const float rad = island.rotation_deg * float(M_PI) / 180.f; + const float s = island.scale; + const float cs = std::cos(rad) * s; + const float sn = std::sin(rad) * s; + + // uv -> centre + R*S*(uv - centre) + offset, with the linear part and the constant part split + // out so this can be handed to a shader as-is. + Eigen::Matrix2f linear; + linear << cs, -sn, + sn, cs; + const Vec2f translation = centre + island.offset - linear * centre; + + m.block<2, 2>(0, 0) = linear; + m.col(2) = translation; + return m; +} + +Vec2f apply_island_transform(const Vec2f &uv, int chart, const PatchUnwrap &unwrap, const std::vector &islands) +{ + const Eigen::Matrix m = island_transform_matrix(chart, unwrap, islands); + return m.block<2, 2>(0, 0) * uv + m.col(2); +} + +namespace { +// One chart's copy of a shared mesh edge: the uv-vertex indices of its two endpoints, ordered so that +// .first is always the lower-numbered base vertex (so two charts' copies line up by base vertex). +struct ChartEdge { int chart = -1; int uv_lo = -1; int uv_hi = -1; }; + +// base edge (lo,hi mesh vertex) -> every chart that has it on its boundary. A mesh edge shared by two +// charts is a seam between them and appears once in each chart's boundary (charts have disjoint uv +// vertices), so its entry lists both charts. +std::map, std::vector> build_shared_edges(const PatchUnwrap &u) +{ + std::map, std::vector> edges; + for (const auto &[ua, ub] : u.boundary_edges) { + if (ua < 0 || ub < 0 || size_t(ua) >= u.source_vertex.size() || size_t(ub) >= u.source_vertex.size()) + continue; + const int ba = u.source_vertex[size_t(ua)], bb = u.source_vertex[size_t(ub)]; + if (ba < 0 || bb < 0 || ba == bb) + continue; + const int chart = (size_t(ua) < u.vertex_chart.size()) ? u.vertex_chart[size_t(ua)] : -1; + if (chart < 0) + continue; + const std::pair key{ std::min(ba, bb), std::max(ba, bb) }; + // Order the uv endpoints to match the base-vertex order in the key. + ChartEdge e{ chart, ua, ub }; + if (u.source_vertex[size_t(ua)] != key.first) + std::swap(e.uv_lo, e.uv_hi); + edges[key].push_back(e); + } + return edges; +} + +// Solve the placement that maps child's raw uv edge (rc0->rc1) onto the parent's placed edge +// (pp0->pp1): a rigid rotation about the child chart's centroid plus an offset, scale kept at 1 so the +// texel density is unchanged. cen is the child chart's centroid. +TextureIsland solve_edge_alignment(const Vec2f &rc0, const Vec2f &rc1, const Vec2f &pp0, const Vec2f &pp1, const Vec2f &cen) +{ + const Vec2f dP = pp1 - pp0, dC = rc1 - rc0; + const float rho = std::atan2(dP.y(), dP.x()) - std::atan2(dC.y(), dC.x()); + const float cs = std::cos(rho), sn = std::sin(rho); + const auto rot = [&](const Vec2f &v) { return Vec2f(v.x() * cs - v.y() * sn, v.x() * sn + v.y() * cs); }; + + TextureIsland island; + island.scale = 1.f; + island.rotation_deg = rho * 180.f / float(M_PI); + island.offset = pp0 - (rot(rc0 - cen) + cen); // island_transform_matrix places rc0 exactly here + return island; +} +} // namespace + +bool join_chart_placement(const PatchUnwrap &unwrap, const std::vector &islands, int child, int parent, + TextureIsland &out_child) +{ + if (child < 0 || parent < 0 || child == parent || size_t(child) >= unwrap.chart_centroid.size()) + return false; + const auto edges = build_shared_edges(unwrap); + for (const auto &[base_edge, list] : edges) { + const ChartEdge *pe = nullptr; + const ChartEdge *ce = nullptr; + for (const ChartEdge &e : list) { + if (e.chart == parent) pe = &e; + if (e.chart == child) ce = &e; + } + if (pe == nullptr || ce == nullptr) + continue; + // Parent's *placed* edge; child's *raw* edge, matched endpoint-to-endpoint by base vertex. + const Vec2f pp0 = apply_island_transform(unwrap.uvs[size_t(pe->uv_lo)], parent, unwrap, islands); + const Vec2f pp1 = apply_island_transform(unwrap.uvs[size_t(pe->uv_hi)], parent, unwrap, islands); + out_child = solve_edge_alignment(unwrap.uvs[size_t(ce->uv_lo)], unwrap.uvs[size_t(ce->uv_hi)], pp0, pp1, + unwrap.chart_centroid[size_t(child)]); + return true; + } + return false; +} + +namespace { +using Tri2 = std::array; + +// Whether two triangles overlap by more than `eps` (separating axis test). Triangles that merely share an edge or +// a corner, as neighbours in a net do, do not. +bool triangles_overlap(const Tri2 &a, const Tri2 &b, float eps) +{ + for (const Tri2 *t : { &a, &b }) + for (int i = 0; i < 3; ++i) { + const Vec2f edge = (*t)[(i + 1) % 3] - (*t)[i]; + const float len = edge.norm(); + if (len < 1e-12f) + continue; + const Vec2f axis(-edge.y() / len, edge.x() / len); + float a_min = std::numeric_limits::max(), a_max = std::numeric_limits::lowest(); + float b_min = a_min, b_max = a_max; + for (int k = 0; k < 3; ++k) { + const float pa = axis.dot(a[k]), pb = axis.dot(b[k]); + a_min = std::min(a_min, pa); + a_max = std::max(a_max, pa); + b_min = std::min(b_min, pb); + b_max = std::max(b_max, pb); + } + if (a_max <= b_min + eps || b_max <= a_min + eps) + return false; + } + return true; +} + +// The triangles already placed in one net, bucketed in a uniform grid so a candidate chart is only tested against +// its neighbourhood. Triangles spanning many cells go into a list that is tested against everything instead. +struct NetGrid +{ + static constexpr int BIG_SPAN = 16; + float cell; + float eps; + std::unordered_map> cells; + std::vector big; + + static uint64_t key(int x, int y) { return (uint64_t(uint32_t(x)) << 32) | uint32_t(y); } + bool range(const Tri2 &t, int &x0, int &y0, int &x1, int &y1) const + { + const Vec2f lo = t[0].cwiseMin(t[1]).cwiseMin(t[2]), hi = t[0].cwiseMax(t[1]).cwiseMax(t[2]); + x0 = int(std::floor(lo.x() / cell)); + y0 = int(std::floor(lo.y() / cell)); + x1 = int(std::floor(hi.x() / cell)); + y1 = int(std::floor(hi.y() / cell)); + return x1 - x0 <= BIG_SPAN && y1 - y0 <= BIG_SPAN; + } + bool overlaps(const Tri2 &t) const + { + for (const Tri2 &b : big) + if (triangles_overlap(t, b, eps)) + return true; + int x0, y0, x1, y1; + if (!range(t, x0, y0, x1, y1)) { + for (const auto &[k, tris] : cells) + for (const Tri2 &b : tris) + if (triangles_overlap(t, b, eps)) + return true; + return false; + } + for (int x = x0; x <= x1; ++x) + for (int y = y0; y <= y1; ++y) + if (const auto it = cells.find(key(x, y)); it != cells.end()) + for (const Tri2 &b : it->second) + if (triangles_overlap(t, b, eps)) + return true; + return false; + } + void insert(const Tri2 &t) + { + int x0, y0, x1, y1; + if (!range(t, x0, y0, x1, y1)) { + big.push_back(t); + return; + } + for (int x = x0; x <= x1; ++x) + for (int y = y0; y <= y1; ++y) + cells[key(x, y)].push_back(t); + } +}; +} // namespace + +std::vector compute_connected_net(const PatchUnwrap &unwrap) +{ + const int n = std::max(unwrap.chart_count, 0); + std::vector islands(static_cast(n)); + if (n <= 1) + return islands; + + // Chart adjacency, with one representative shared edge per adjacent pair. + const auto edges = build_shared_edges(unwrap); + struct PairEdge { ChartEdge a, b; }; + std::map, PairEdge> pair_edge; + std::vector> adj(static_cast(n)); + for (const auto &[base_edge, list] : edges) { + for (size_t i = 0; i < list.size(); ++i) + for (size_t j = i + 1; j < list.size(); ++j) { + const int c1 = list[i].chart, c2 = list[j].chart; + if (c1 == c2 || c1 < 0 || c2 < 0 || c1 >= n || c2 >= n) + continue; + const std::pair pk{ std::min(c1, c2), std::max(c1, c2) }; + if (pair_edge.count(pk)) + continue; // keep the first shared edge as the fold line for this pair + pair_edge[pk] = (c1 < c2) ? PairEdge{ list[i], list[j] } : PairEdge{ list[j], list[i] }; + adj[size_t(pk.first)].push_back(pk.second); + adj[size_t(pk.second)].push_back(pk.first); + } + } + + // Per chart: its vertices, its triangles and its flattened area. + std::vector> chart_verts(static_cast(n)), chart_tris(static_cast(n)); + std::vector chart_area(static_cast(n), 0.f); + for (size_t i = 0; i < unwrap.uvs.size(); ++i) + if (const int c = unwrap.vertex_chart[i]; c >= 0 && c < n) + chart_verts[size_t(c)].push_back(int(i)); + float extent_sum = 0.f, extent = 0.f; + for (size_t t = 0; t < unwrap.indices.size(); ++t) { + const stl_triangle_vertex_indices &tri = unwrap.indices[t]; + const int c = unwrap.vertex_chart[size_t(tri[0])]; + if (c < 0 || c >= n) + continue; + chart_tris[size_t(c)].push_back(int(t)); + const Vec2f &p0 = unwrap.uvs[size_t(tri[0])], &p1 = unwrap.uvs[size_t(tri[1])], &p2 = unwrap.uvs[size_t(tri[2])]; + const Vec2f e0 = p1 - p0, e1 = p2 - p0; + chart_area[size_t(c)] += 0.5f * std::abs(e0.x() * e1.y() - e0.y() * e1.x()); + const Vec2f size = p0.cwiseMax(p1).cwiseMax(p2) - p0.cwiseMin(p1).cwiseMin(p2); + extent_sum += std::max(size.x(), size.y()); + extent = std::max({ extent, p0.cwiseAbs().maxCoeff(), p1.cwiseAbs().maxCoeff(), p2.cwiseAbs().maxCoeff() }); + } + const float cell = std::max(extent_sum / float(std::max(unwrap.indices.size(), 1)), 1e-6f); + // Touching neighbours may overlap by rounding: a fraction of a typical triangle, but at least what float + // rounding of a placement at this distance from the origin can produce. + const float eps = std::max(0.02f * cell, 4e-6f * extent); + + const auto placed = [&](const Eigen::Matrix &m, int t) { + const stl_triangle_vertex_indices &tri = unwrap.indices[size_t(t)]; + Tri2 out; + for (int k = 0; k < 3; ++k) + out[size_t(k)] = m.block<2, 2>(0, 0) * unwrap.uvs[size_t(tri[k])] + m.col(2); + return out; + }; + + // Grow a net from the largest chart not yet in one, unfolding each neighbour onto the chart it was reached from + // (bigger neighbours first, so slivers don't claim the good spots) unless its triangles would overlap the net. + // A chart that doesn't fit stays out and roots a net of its own later, so nothing is left in a random spot. + std::vector by_area(static_cast(n)); + std::iota(by_area.begin(), by_area.end(), 0); + std::stable_sort(by_area.begin(), by_area.end(), [&chart_area](int a, int b) { return chart_area[size_t(a)] > chart_area[size_t(b)]; }); + + std::vector net_of(static_cast(n), -1); + int net_count = 0; + for (const int root : by_area) { + if (net_of[size_t(root)] >= 0 || chart_tris[size_t(root)].empty()) + continue; + const int net = net_count++; + NetGrid grid{ cell, eps, {}, {} }; + net_of[size_t(root)] = net; + { + const Eigen::Matrix m = island_transform_matrix(root, unwrap, islands); + for (const int t : chart_tris[size_t(root)]) + grid.insert(placed(m, t)); + } + std::queue q; + q.push(root); + while (!q.empty()) { + const int p = q.front(); + q.pop(); + std::vector neighbours = adj[size_t(p)]; + std::stable_sort(neighbours.begin(), neighbours.end(), + [&chart_area](int a, int b) { return chart_area[size_t(a)] > chart_area[size_t(b)]; }); + for (const int c : neighbours) { + if (net_of[size_t(c)] >= 0 || chart_tris[size_t(c)].empty()) + continue; + const auto it = pair_edge.find({ std::min(p, c), std::max(p, c) }); + if (it == pair_edge.end()) + continue; + const ChartEdge &pe = (p < c) ? it->second.a : it->second.b; + const ChartEdge &ce = (p < c) ? it->second.b : it->second.a; + const Vec2f pp0 = apply_island_transform(unwrap.uvs[size_t(pe.uv_lo)], p, unwrap, islands); + const Vec2f pp1 = apply_island_transform(unwrap.uvs[size_t(pe.uv_hi)], p, unwrap, islands); + islands[size_t(c)] = solve_edge_alignment(unwrap.uvs[size_t(ce.uv_lo)], unwrap.uvs[size_t(ce.uv_hi)], pp0, + pp1, unwrap.chart_centroid[size_t(c)]); + + const Eigen::Matrix m = island_transform_matrix(c, unwrap, islands); + std::vector tris; + tris.reserve(chart_tris[size_t(c)].size()); + bool fits = true; + for (const int t : chart_tris[size_t(c)]) { + tris.push_back(placed(m, t)); + if (grid.overlaps(tris.back())) { + fits = false; + break; + } + } + if (!fits) { + islands[size_t(c)] = TextureIsland{}; + continue; + } + for (const Tri2 &t : tris) + grid.insert(t); + net_of[size_t(c)] = net; + q.push(c); + } + } + } + + // Shelf-pack the nets side by side, tallest first, the way compute_patch_unwrap() packs charts. + std::vector lo(static_cast(net_count), Vec2f::Constant(std::numeric_limits::max())); + std::vector hi(static_cast(net_count), Vec2f::Constant(std::numeric_limits::lowest())); + for (int c = 0; c < n; ++c) { + const int net = net_of[size_t(c)]; + if (net < 0) + continue; + const Eigen::Matrix m = island_transform_matrix(c, unwrap, islands); + for (const int v : chart_verts[size_t(c)]) { + const Vec2f p = m.block<2, 2>(0, 0) * unwrap.uvs[size_t(v)] + m.col(2); + lo[size_t(net)] = lo[size_t(net)].cwiseMin(p); + hi[size_t(net)] = hi[size_t(net)].cwiseMax(p); + } + } + float total_area = 0.f, widest = 0.f; + for (int k = 0; k < net_count; ++k) { + const Vec2f size = hi[size_t(k)] - lo[size_t(k)]; + total_area += size.x() * size.y(); + widest = std::max(widest, size.x()); + } + const float shelf_width = std::max(widest, std::sqrt(std::max(total_area, 0.f)) * 1.4f); + const float margin = std::max(shelf_width * 0.02f, 1e-4f); + std::vector order(static_cast(net_count)); + std::iota(order.begin(), order.end(), 0); + std::stable_sort(order.begin(), order.end(), [&](int a, int b) { + return hi[size_t(a)].y() - lo[size_t(a)].y() > hi[size_t(b)].y() - lo[size_t(b)].y(); + }); + std::vector shift(static_cast(net_count), Vec2f::Zero()); + float cursor_x = 0.f, cursor_y = 0.f, row_height = 0.f; + for (const int k : order) { + const Vec2f size = hi[size_t(k)] - lo[size_t(k)]; + if (cursor_x > 0.f && cursor_x + size.x() > shelf_width) { + cursor_x = 0.f; + cursor_y += row_height + margin; + row_height = 0.f; + } + shift[size_t(k)] = Vec2f(cursor_x, cursor_y) - lo[size_t(k)]; + cursor_x += size.x() + margin; + row_height = std::max(row_height, size.y()); + } + for (int c = 0; c < n; ++c) + if (net_of[size_t(c)] >= 0) + islands[size_t(c)].offset += shift[size_t(net_of[size_t(c)])]; + return islands; +} + +void average_island_scales(std::vector &islands) +{ + if (islands.empty()) + return; + float sum = 0.f; + for (const TextureIsland &island : islands) + sum += island.scale; + const float mean = sum / float(islands.size()); + for (TextureIsland &island : islands) + island.scale = mean; +} + +std::vector apply_lscm_uv_overrides(PatchUnwrap &unwrap, const std::vector> &overrides) +{ + std::vector edited(unwrap.uvs.size(), false); + if (overrides.empty()) + return edited; + // Mesh-vertex keys first, so an edit on one copy of the same vertex takes precedence over them. + std::map by_mesh_vertex; + for (const auto &[key, uv] : overrides) + if (key >= 0) + by_mesh_vertex[key] = uv; + if (!by_mesh_vertex.empty()) + for (size_t i = 0; i < unwrap.uvs.size(); ++i) + if (const auto it = by_mesh_vertex.find(unwrap.source_vertex[i]); it != by_mesh_vertex.end()) { + unwrap.uvs[i] = it->second; + edited[i] = true; + } + for (const auto &[key, uv] : overrides) + if (const int i = -key - 1; key < 0 && size_t(i) < unwrap.uvs.size()) { + unwrap.uvs[size_t(i)] = uv; + edited[size_t(i)] = true; + } + return edited; +} + +std::vector compute_lscm_uvs(const indexed_triangle_set &patch, const TextureDisplacementLayer &layer) +{ + // Padding disabled (0), matching the UV editor: the packed islands the editor shows and the ones the + // bake/preview samples must be laid out identically, or a hand placement made in the editor would + // land somewhere else in the baked result. + const PatchUnwrap unwrap = compute_patch_unwrap(patch, layer.lscm_seam_angle_deg, 0.f, layer.lscm_seam_edges); + if (unwrap.empty()) + return {}; + + // Manual UV edits (UV editor Vertex/Edge modes) replace the automatic raw unwrap coordinate, before the island + // transform - so the edit rides along with any island move/rotate exactly like the rest of the island. + PatchUnwrap edited_unwrap = unwrap; + const std::vector edited = apply_lscm_uv_overrides(edited_unwrap, layer.lscm_uv_overrides); + + // One UV per patch vertex: a seam vertex has several (one per chart it touches) and has to + // settle on one, since it can only be displaced to a single position. See compute_lscm_uvs()'s + // header comment - the surface stays watertight regardless. A copy that was edited by hand wins, + // so the edit is what bakes; otherwise the first copy does. + std::vector per_vertex(patch.vertices.size(), Vec2f::Zero()); + std::vector assigned(patch.vertices.size(), false); + for (const bool edited_pass : { true, false }) + for (size_t i = 0; i < edited_unwrap.uvs.size(); ++i) { + const int pv = edited_unwrap.source_vertex[i]; + if (pv < 0 || assigned[size_t(pv)] || edited[i] != edited_pass) + continue; + per_vertex[size_t(pv)] = apply_island_transform(edited_unwrap.uvs[i], edited_unwrap.vertex_chart[i], unwrap, layer.islands); + assigned[size_t(pv)] = true; + } + return per_vertex; +} + +std::vector compute_lscm_corner_uvs(const indexed_triangle_set &patch, const TextureDisplacementLayer &layer) +{ + // Padding 0 and the layer's own seam angle/edges, exactly as compute_lscm_uvs() does - the two must + // unwrap identically or a hand placement would land in one place on screen and another in the bake. + const PatchUnwrap unwrap = compute_patch_unwrap(patch, layer.lscm_seam_angle_deg, 0.f, layer.lscm_seam_edges); + if (unwrap.empty() || unwrap.source_face.size() != unwrap.indices.size()) + return {}; + + PatchUnwrap edited_unwrap = unwrap; + apply_lscm_uv_overrides(edited_unwrap, layer.lscm_uv_overrides); + + // No first-copy-wins collapse here: the unwrap's triangles are already per chart, so each corner + // simply takes its own chart's copy. A triangle the unwrap dropped (a sliver a chart rejected) keeps + // the zero it was initialised with; the callers treat that as "no placement" the same way they treat + // an empty result. + std::vector corner(patch.indices.size() * 3, Vec2f::Zero()); + for (size_t t = 0; t < edited_unwrap.indices.size(); ++t) { + const int f = edited_unwrap.source_face[t]; + if (f < 0 || size_t(f) >= patch.indices.size()) + continue; + const stl_triangle_vertex_indices &tri = edited_unwrap.indices[t]; + for (int k = 0; k < 3; ++k) { + const int uvi = tri[k]; + if (uvi < 0 || size_t(uvi) >= edited_unwrap.uvs.size()) + continue; + // The island transform is taken against the *unedited* unwrap, whose chart_centroid is the + // pivot the UV editor rotates about - same as compute_lscm_uvs(). + corner[size_t(f) * 3 + size_t(k)] = apply_island_transform(edited_unwrap.uvs[size_t(uvi)], + edited_unwrap.vertex_chart[size_t(uvi)], + unwrap, layer.islands); + } + } + return corner; +} + +namespace { +// apply_uv_transform()'s per-layer constants, worked out once. Triplanar sampling runs the transform +// three times per point, and recomputing the rotation's cos/sin and the tiling reciprocal on every one +// of them was most of the per-sample arithmetic. +struct UVTransform +{ + float scale, cs, sn, aspect; + Vec2f offset; + + UVTransform(const TextureDisplacementLayer &layer, float aspect_) + { + scale = (layer.tiling_scale > 1e-6f) ? (1.f / layer.tiling_scale) : 1.f; + const float rad = layer.rotation_deg * float(M_PI) / 180.f; + cs = std::cos(rad); + sn = std::sin(rad); + aspect = aspect_; + offset = layer.offset; + } + Vec2f operator()(const Vec2f &planar) const + { + const Vec2f scaled = planar * scale; + Vec2f rotated(scaled.x() * cs - scaled.y() * sn, scaled.x() * sn + scaled.y() * cs); + // See apply_uv_transform() for why the aspect correction follows the rotation. + if (aspect > 0.f && aspect != 1.f) + rotated.y() *= aspect; + return rotated + offset; + } +}; + +// |n|^TRIPLANAR_BLEND_SHARPNESS per component. The exponent is a compile-time 4, so two squarings do +// what three std::pow calls per sample did. +static_assert(TRIPLANAR_BLEND_SHARPNESS == 4.f, "triplanar_weights() hard-codes the fourth power"); +inline Vec3f triplanar_weights(const Vec3f &normal) +{ + Vec3f w = normal.cwiseAbs(); + w = w.cwiseProduct(w); + return w.cwiseProduct(w); +} +} // namespace + +Vec2f apply_uv_transform(const Vec2f &planar, const TextureDisplacementLayer &layer, float aspect) +{ + const float scale = (layer.tiling_scale > 1e-6f) ? (1.f / layer.tiling_scale) : 1.f; + const Vec2f scaled = planar * scale; + + const float rad = layer.rotation_deg * float(M_PI) / 180.f; + const float cs = std::cos(rad); + const float sn = std::sin(rad); + Vec2f rotated(scaled.x() * cs - scaled.y() * sn, scaled.x() * sn + scaled.y() * cs); + + // Non-square textures. Without this the [0,1] square of uv covers the whole image whatever its + // proportions, so a 2:1 image is squeezed into a square tile and every feature in it comes out + // half as wide as it should be. `tiling_scale` is the tile's size along u; the tile is + // `tiling_scale * height / width` mm along v, which is exactly what keeps texels square - so + // dividing v by that extent is the same as multiplying it by width / height. A square texture has + // aspect 1 and is untouched, which is why this changes nothing for the shipped library. + // + // Applied after the rotation, not before: scaling one axis of an already-rotated coordinate is a + // shear, and doing it the other way round would make "Rotation" skew the pattern instead of + // turning it. + if (aspect > 0.f && aspect != 1.f) + rotated.y() *= aspect; + + return rotated + layer.offset; +} + +float blend_displacement(float accumulated, float value, TextureBlendMode mode) +{ + switch (mode) { + case TextureBlendMode::Subtract: return accumulated - value; + // Multiply/Divide scale rather than offset, so they take `value` as a factor relative to 1 mm + // (see TextureBlendMode): a 1 mm-deep layer sampling a white texel is then exactly neutral. + case TextureBlendMode::Multiply: return accumulated * value; + case TextureBlendMode::Divide: { + // Every height map has black regions, and a black texel samples to *exactly* zero - so this + // divisor really does hit zero in ordinary use, not just in some contrived edge case. Floor + // its magnitude: an unbounded 1/0 would not merely look wrong, it would fling vertices + // thousands of mm away and poison the mesh's bounding box (and with it every plate/print + // volume check downstream). The floor doubles as a cap on how far Divide can ever amplify + // the relief beneath it - at most 1/0.05 = 20x. + constexpr float min_divisor = 0.05f; + const float divisor = (std::abs(value) < min_divisor) ? std::copysign(min_divisor, value < 0.f ? -1.f : 1.f) : + value; + return accumulated / divisor; + } + case TextureBlendMode::Add: + default: return accumulated + value; + } +} + +bool project_uv_projective(const std::array &m, const Vec3f &position, Vec2f &uv) +{ + const float x = position.x(), y = position.y(), z = position.z(); + const float w = m[8] * x + m[9] * y + m[10] * z + m[11]; + // Strictly greater than zero: at w == 0 the point sits on the projector's plane and maps to + // infinity, and at w < 0 it is behind the projector, where dividing yields a plausible-looking + // but mirrored uv - the classic way a projected decal reappears on the back of a model. + if (!(w > 1e-6f)) + return false; + uv = Vec2f((m[0] * x + m[1] * y + m[2] * z + m[3]) / w, (m[4] * x + m[5] * y + m[6] * z + m[7]) / w); + return true; +} + +float sample_layer_height(const DecodedHeightTexture &texture, const TextureDisplacementLayer &layer, + const Vec3f &position, const Vec3f &normal, + const Vec3f &patch_center, const Vec3f &patch_axis, const Vec2f *lscm_uv) +{ + if (texture.empty()) + return 0.f; + + // width / height of the height map, so a non-square image keeps its proportions (see + // apply_uv_transform()). Every projection except the projective "from view" one funnels through + // here, so this one line is what makes them all aspect-correct. + const float aspect = (texture.height > 0) ? float(texture.width) / float(texture.height) : 1.f; + const UVTransform xf(layer, aspect); + auto sample_at = [&](const Vec2f &planar) { + return texture.sample(xf(planar), layer.tile_enabled, layer.tile_method); + }; + + // Precomputed per-patch LSCM solve wins over the layer's own method (see the header): the + // caller only passes it when the patch actually parameterized successfully, so a patch that + // failed to unwrap falls through to the analytic methods below as its documented fallback. + if (lscm_uv != nullptr) + return sample_at(*lscm_uv); + + switch (layer.projection_method) { + case TextureProjectionMethod::Cylindrical: + return sample_at(project_cylindrical(position, patch_center, patch_axis)); + case TextureProjectionMethod::Spherical: + return sample_at(project_spherical(position, patch_center)); + case TextureProjectionMethod::ViewProjected: + if (layer.view_project_projective) { + // Exact projective placement written by the projection-frame overlay. Sampled directly, + // *without* apply_uv_transform(): the matrix already maps the window's border to the uv + // unit square, so the tiling/rotation/offset controls would displace it off the frame + // the user just aligned. A point behind the projector has no uv at all -> no height. + Vec2f uv; + if (!project_uv_projective(layer.view_project_matrix, position, uv)) + return 0.f; + return texture.sample(uv, layer.tile_enabled, layer.tile_method); + } + // Flat projection onto the captured projector plane. Single-valued per point, so unlike + // blended triplanar it is one sample, and it is what "project from view" places. + return sample_at(Vec2f(position.dot(layer.view_project_right), position.dot(layer.view_project_up))); + case TextureProjectionMethod::LSCM: // no usable unwrap for this patch - fall back to Triplanar + case TextureProjectionMethod::Triplanar: + default: break; + } + + // Blended tri-planar: sample all three axis-aligned planes and cross-fade between them by the + // normal's own components, instead of hard-switching to whichever single axis dominates. The + // hard switch is what produced a visible seam wherever the dominant axis flips (see + // TextureProjectionMethod::Triplanar); a weighted blend is continuous across that transition + // by construction, since the weight of the axis being left behind falls smoothly to zero. + Vec3f w = triplanar_weights(normal); + const float w_sum = w.x() + w.y() + w.z(); + if (w_sum < 1e-8f) + // Degenerate normal: no axis is meaningfully dominant, so no blend is meaningful either. + return sample_at(Vec2f(position.x(), position.y())); + w /= w_sum; + + // Each plane drops the axis it is named for, matching project_planar()'s own convention (which + // the GUI's on-canvas placement gizmo also relies on). + return w.x() * sample_at(Vec2f(position.y(), position.z())) + + w.y() * sample_at(Vec2f(position.x(), position.z())) + + w.z() * sample_at(Vec2f(position.x(), position.y())); +} + +bool sample_layer_color(const DecodedHeightTexture &texture, const TextureDisplacementLayer &layer, + const Vec3f &position, const Vec3f &normal, Vec3f &out, const Vec3f &patch_center, + const Vec3f &patch_axis, const Vec2f *lscm_uv) +{ + if (!texture.has_color()) + return false; + + // Deliberately a transcription of sample_layer_height()'s dispatch rather than a shared template: + // the two differ in what "nothing here" means. Height returns 0, which is a perfectly good height + // (no displacement); colour has no such neutral value - black is a colour - so every path that + // returns 0 there has to report false here instead, and the caller leaves the triangle uncoloured. + const float aspect = (texture.height > 0) ? float(texture.width) / float(texture.height) : 1.f; + const UVTransform xf(layer, aspect); + auto sample_at = [&](const Vec2f &planar) { + return texture.sample_color(xf(planar), layer.tile_enabled, layer.tile_method); + }; + // Outside a non-tiled placement there is no texture at all - the same hard edge sample() gives the + // height. Checked explicitly because sample_color() reports it as black, which is a real colour. + auto covered = [&](const Vec2f &planar) { + if (layer.tile_enabled) + return true; + const Vec2f uv = xf(planar); + return uv.x() >= 0.f && uv.x() < 1.f && uv.y() >= 0.f && uv.y() < 1.f; + }; + + if (lscm_uv != nullptr) { + if (!covered(*lscm_uv)) + return false; + out = sample_at(*lscm_uv); + return true; + } + + switch (layer.projection_method) { + case TextureProjectionMethod::Cylindrical: { + const Vec2f p = project_cylindrical(position, patch_center, patch_axis); + if (!covered(p)) + return false; + out = sample_at(p); + return true; + } + case TextureProjectionMethod::Spherical: { + const Vec2f p = project_spherical(position, patch_center); + if (!covered(p)) + return false; + out = sample_at(p); + return true; + } + case TextureProjectionMethod::ViewProjected: + if (layer.view_project_projective) { + // The frame's own rectangle is the placement, so no apply_uv_transform() - see + // sample_layer_height(). A point behind the projector has no uv, hence no colour. + Vec2f uv; + if (!project_uv_projective(layer.view_project_matrix, position, uv)) + return false; + if (!layer.tile_enabled && (uv.x() < 0.f || uv.x() >= 1.f || uv.y() < 0.f || uv.y() >= 1.f)) + return false; + out = texture.sample_color(uv, layer.tile_enabled, layer.tile_method); + return true; + } else { + const Vec2f p(position.dot(layer.view_project_right), position.dot(layer.view_project_up)); + if (!covered(p)) + return false; + out = sample_at(p); + return true; + } + case TextureProjectionMethod::LSCM: // no usable unwrap for this patch - fall back to Triplanar + case TextureProjectionMethod::Triplanar: + default: break; + } + + // Blended tri-planar, weighted exactly as the height is, so colour and relief stay registered + // across the cross-fade band at a 90-degree edge. + Vec3f w = triplanar_weights(normal); + const float w_sum = w.x() + w.y() + w.z(); + if (w_sum < 1e-8f) { + const Vec2f p(position.x(), position.y()); + if (!covered(p)) + return false; + out = sample_at(p); + return true; + } + w /= w_sum; + + // A blend of three planes is only "not covered" where *every* contributing plane is outside the + // placement; where some are, the covered ones are renormalised so the colour does not fade toward + // black at the edge of an untiled tri-planar layer. + const std::array planes = { Vec2f(position.y(), position.z()), Vec2f(position.x(), position.z()), + Vec2f(position.x(), position.y()) }; + Vec3f acc = Vec3f::Zero(); + float acc_w = 0.f; + for (int i = 0; i < 3; ++i) + if (w[i] > 0.f && covered(planes[size_t(i)])) { + acc += w[i] * sample_at(planes[size_t(i)]); + acc_w += w[i]; + } + if (acc_w <= 0.f) + return false; + out = acc / acc_w; + return true; +} + +indexed_triangle_set extract_painted_patch(const indexed_triangle_set &base_mesh, + const TriangleSelector::TriangleSplittingData &facet_data) +{ + if (facet_data.triangles_to_split.empty()) + return {}; + + const TriangleMesh selector_mesh(base_mesh); + TriangleSelector selector(selector_mesh); + selector.deserialize(facet_data, false); + return selector.get_facets_strict(EnforcerBlockerType::ENFORCER); +} + +bool compute_layer_paint_anchor(const indexed_triangle_set &base_mesh, + const TriangleSelector::TriangleSplittingData &facet_data, + Vec3f &anchor_pos, + Vec3f &anchor_normal) +{ + const indexed_triangle_set patch = extract_painted_patch(base_mesh, facet_data); + if (patch.indices.empty()) + return false; + + Vec3f centroid_sum = Vec3f::Zero(); + Vec3f normal_sum = Vec3f::Zero(); + for (const stl_triangle_vertex_indices &tri : patch.indices) { + const Vec3f &a = patch.vertices[tri[0]]; + const Vec3f &b = patch.vertices[tri[1]]; + const Vec3f &c = patch.vertices[tri[2]]; + // Cross product magnitude is twice the face area, so this area-weights both sums the same + // way texture_displacement_vertex_normals() does above. + normal_sum += (b - a).cross(c - a); + centroid_sum += (a + b + c) / 3.f; + } + + anchor_pos = centroid_sum / float(patch.indices.size()); + anchor_normal = (normal_sum.norm() > 1e-8f) ? Vec3f(normal_sum.normalized()) : Vec3f::UnitZ(); + return true; +} + +// Area-weighted vertex normals of the undisplaced mesh. build_texture_displacement() computes +// these once, up front, and every layer both projects and displaces along them - so a vertex +// covered by several layers is pushed along one single, well-defined direction rather than along +// whatever direction the surface happened to be pointing partway through the stack. +std::vector texture_displacement_vertex_normals(const indexed_triangle_set &its) +{ + std::vector normals(its.vertices.size(), Vec3f::Zero()); + for (const stl_triangle_vertex_indices &tri : its.indices) { + const Vec3f &a = its.vertices[tri[0]]; + const Vec3f &b = its.vertices[tri[1]]; + const Vec3f &c = its.vertices[tri[2]]; + // Cross product magnitude is twice the face area, so this naturally area-weights the + // contribution of each incident face to its vertices. + const Vec3f area_weighted_normal = (b - a).cross(c - a); + normals[tri[0]] += area_weighted_normal; + normals[tri[1]] += area_weighted_normal; + normals[tri[2]] += area_weighted_normal; + } + for (Vec3f &n : normals) { + const float len = n.norm(); + n = (len > 1e-8f) ? Vec3f(n / len) : Vec3f::UnitZ(); + } + return normals; +} + +namespace { +// Shortest along-surface distance from every patch vertex to the patch boundary (the pinned vertices +// shared with the untouched surface), by a multi-source Dijkstra over the patch edges. Used for edge +// smoothing: the displacement is faded out as this distance goes to zero. +std::vector patch_boundary_distance(const indexed_triangle_set &patch, const std::vector &is_boundary) +{ + const size_t n = patch.vertices.size(); + std::vector>> adj(n); + for (const stl_triangle_vertex_indices &tri : patch.indices) + for (int i = 0; i < 3; ++i) { + const int a = tri[i], b = tri[(i + 1) % 3]; + if (a < 0 || b < 0 || size_t(a) >= n || size_t(b) >= n) + continue; + const float w = (patch.vertices[size_t(a)] - patch.vertices[size_t(b)]).norm(); + adj[size_t(a)].push_back({ b, w }); + adj[size_t(b)].push_back({ a, w }); + } + + std::vector dist(n, std::numeric_limits::infinity()); + using QN = std::pair; + std::priority_queue, std::greater> pq; + for (size_t v = 0; v < n; ++v) + if (v < is_boundary.size() && is_boundary[v]) { + dist[v] = 0.f; + pq.push({ 0.f, int(v) }); + } + while (!pq.empty()) { + const auto [d, u] = pq.top(); + pq.pop(); + if (d > dist[size_t(u)]) + continue; + for (const auto &[w, ew] : adj[size_t(u)]) { + const float nd = d + ew; + if (nd < dist[size_t(w)]) { + dist[size_t(w)] = nd; + pq.push({ nd, w }); + } + } + } + return dist; +} +} // namespace + +namespace { +// Majority filter over face adjacency: each triangle takes the most common colour among itself and +// the (up to three) triangles across its edges. Ties, and a triangle whose own colour is already the +// most common, keep what they had - so the filter only ever removes a facet that disagrees with its +// whole neighbourhood, and cannot drift a large region. +// +// Read from a snapshot of the previous pass, so the result does not depend on triangle order. +// Uncoloured triangles (-1) neither vote nor get voted on: the paint boundary is not noise. +void despeckle_triangle_colors(const indexed_triangle_set &mesh, std::vector &color, int passes) +{ + if (passes <= 0 || color.size() != mesh.indices.size()) + return; + const std::vector neighbors = its_face_neighbors(mesh); + if (neighbors.size() != mesh.indices.size()) + return; + + std::vector prev; + for (int pass = 0; pass < passes; ++pass) { + prev = color; + tbb::parallel_for(tbb::blocked_range(0, color.size()), + [&](const tbb::blocked_range &range) { + for (size_t i = range.begin(); i < range.end(); ++i) { + if (prev[i] < 0) + continue; + // At most four candidates (self plus three neighbours), so counting by a linear scan + // is cheaper than any map. + int cand[4] = { prev[i], -1, -1, -1 }; + int count[4] = { 1, 0, 0, 0 }; + int n = 1; + for (int e = 0; e < 3; ++e) { + const int nb = neighbors[i][e]; + if (nb < 0 || size_t(nb) >= prev.size() || prev[size_t(nb)] < 0) + continue; + const int c = prev[size_t(nb)]; + int k = 0; + for (; k < n; ++k) + if (cand[k] == c) { + ++count[k]; + break; + } + if (k == n && n < 4) { + cand[n] = c; + count[n] = 1; + ++n; + } + } + // Strictly greater, so a tie leaves the triangle alone. + int best = 0; + for (int k = 1; k < n; ++k) + if (count[k] > count[best]) + best = k; + if (count[best] > count[0]) + color[i] = cand[best]; + } + }); + } +} +} // namespace + +void merge_small_color_regions(const indexed_triangle_set &mesh, std::vector &color, float min_area_mm2) +{ + const size_t n = mesh.indices.size(); + if (min_area_mm2 <= 0.f || color.size() != n) + return; + const std::vector neighbors = its_face_neighbors(mesh); + if (neighbors.size() != n) + return; + + const auto edge_length = [&mesh](size_t f, int e) { + const stl_triangle_vertex_indices &t = mesh.indices[f]; + return (mesh.vertices[size_t(t[(e + 1) % 3])] - mesh.vertices[size_t(t[e])]).norm(); + }; + + // Connected components of equal colour: `faces` lists every coloured face, component by + // component, `start` delimits them. Uncoloured faces (-1) belong to no component and block the + // flood, so a region never grows across the paint's border. + std::vector component(n, -1); + std::vector faces; + std::vector start; + std::vector area; + std::vector stack; + faces.reserve(n); + for (size_t seed = 0; seed < n; ++seed) { + if (color[seed] < 0 || component[seed] >= 0) + continue; + const int c = color[seed]; + const int id = int(area.size()); + start.push_back(faces.size()); + area.push_back(0.f); + component[seed] = id; + stack.push_back(int(seed)); + while (!stack.empty()) { + const size_t f = size_t(stack.back()); + stack.pop_back(); + faces.push_back(int(f)); + const stl_triangle_vertex_indices &t = mesh.indices[f]; + const Vec3f &a = mesh.vertices[size_t(t[0])], &b = mesh.vertices[size_t(t[1])], &cv = mesh.vertices[size_t(t[2])]; + area[size_t(id)] += 0.5f * (b - a).cross(cv - a).norm(); + for (int e = 0; e < 3; ++e) { + const int nb = neighbors[f][e]; + if (nb < 0 || size_t(nb) >= n || component[size_t(nb)] >= 0 || color[size_t(nb)] != c) + continue; + component[size_t(nb)] = id; + stack.push_back(nb); + } + } + } + start.push_back(faces.size()); + + // Smallest first, so that when a small island borders a slightly larger one the larger one has + // not yet moved and the small one joins whatever the two of them sit in; the larger one then + // reads that colour in turn. + std::vector order; + for (int id = 0; id < int(area.size()); ++id) + if (area[size_t(id)] < min_area_mm2) + order.push_back(id); + std::sort(order.begin(), order.end(), [&area](int l, int r) { return area[size_t(l)] < area[size_t(r)]; }); + + std::vector> weights; // neighbouring colour -> shared edge length + for (const int id : order) { + const size_t begin = start[size_t(id)], end = start[size_t(id) + 1]; + const int own = color[size_t(faces[begin])]; + weights.clear(); + for (size_t k = begin; k < end; ++k) { + const size_t f = size_t(faces[k]); + for (int e = 0; e < 3; ++e) { + const int nb = neighbors[f][e]; + if (nb < 0 || size_t(nb) >= n) + continue; + const int c = color[size_t(nb)]; // read now: an earlier merge may have recoloured it + if (c < 0 || c == own) + continue; + const float len = edge_length(f, e); + auto it = std::find_if(weights.begin(), weights.end(), [c](const std::pair &w) { return w.first == c; }); + if (it == weights.end()) + weights.emplace_back(c, len); + else + it->second += len; + } + } + if (weights.empty()) + continue; // bordered only by uncoloured faces (or nothing): stays + const int target = std::max_element(weights.begin(), weights.end(), + [](const std::pair &l, const std::pair &r) { + return l.second < r.second; + })->first; + for (size_t k = begin; k < end; ++k) + color[size_t(faces[k])] = target; + } +} + +namespace { + +// Wired to the same layer stack via make_combined_displacement_sampler(), so layers, blend modes and +// projections behave identically in both paths and the comparison is between the meshing strategies. +indexed_triangle_set build_texture_displacement_v2(const indexed_triangle_set &mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, + const TextureDisplacementOptions &options, + const DisplacementProgressFn &progress, + const TextureColorRequest *color, + bool flip_normals, + BakeStageRecorder *debug, + TextureBakeStats *stats) +{ + HeightFieldSampler combined = make_combined_displacement_sampler(mesh, layers, facets_data); + if (!combined) + return mesh; // nothing decodable to displace with + + // Unpainted triangles are excluded, keeping them out of refinement and pinned thereafter. The + // paint is finer than that, though: a brush stroke splits a source triangle into pieces, and only + // some of them are painted. `painted_pieces` keeps every layer's painted pieces (they lie in the + // source surface) so the refined faces can be tested against the paint itself, not against the + // source triangle they came from. + std::vector excluded(mesh.indices.size(), 1); + indexed_triangle_set painted_pieces; + { + const TriangleMesh selector_mesh(mesh); + TriangleSelector selector(selector_mesh); + bool dirty = false; + for (const TriangleSelector::TriangleSplittingData &data : facets_data) { + if (data.triangles_to_split.empty()) + continue; + selector.deserialize(data, dirty); + dirty = true; + std::vector piece_src; + const indexed_triangle_set patch = + selector.get_facets_strict(EnforcerBlockerType::ENFORCER, &piece_src); + for (const int src : piece_src) + if (src >= 0 && size_t(src) < excluded.size()) + excluded[size_t(src)] = 0; + // `patch` carries the whole mesh's vertex array (see compact_patch_with_map()); append + // only what its pieces reference. + std::vector unused; + const indexed_triangle_set compact = compact_patch_with_map(patch, unused); + const int offset = int(painted_pieces.vertices.size()); + painted_pieces.vertices.insert(painted_pieces.vertices.end(), compact.vertices.begin(), compact.vertices.end()); + for (const stl_triangle_vertex_indices &t : compact.indices) + painted_pieces.indices.emplace_back(t[0] + offset, t[1] + offset, t[2] + offset); + } + } + if (std::all_of(excluded.begin(), excluded.end(), [](uint8_t e) { return e != 0; }) || painted_pieces.indices.empty()) + return mesh; // nothing painted + + // Distance to the nearest painted piece. Built once here; the tree is read-only afterwards, so + // the parallel stages below share it freely. + const AABBTreeIndirect::Tree3f painted_tree = + AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(painted_pieces.vertices, painted_pieces.indices); + // `foot`/`normal`, when asked for, are the closest point on the painted pieces and that piece's + // normal. The pieces lie in the *undisplaced* surface, so for a displaced point those two are the + // base position and normal underneath it - the frame colour has to be projected in (see below). + const auto painted_closest = [&painted_pieces, &painted_tree](const Vec3f &p, Vec3f *foot, Vec3f *normal) { + size_t hit = 0; + Vec3f hit_point; + const float d2 = AABBTreeIndirect::squared_distance_to_indexed_triangle_set( + painted_pieces.vertices, painted_pieces.indices, painted_tree, p, hit, hit_point); + if (foot != nullptr) + *foot = hit_point; + if (normal != nullptr && hit < painted_pieces.indices.size()) { + const stl_triangle_vertex_indices &t = painted_pieces.indices[hit]; + const Vec3f &a = painted_pieces.vertices[size_t(t[0])], &b = painted_pieces.vertices[size_t(t[1])], + &c = painted_pieces.vertices[size_t(t[2])]; + Vec3f n = (b - a).cross(c - a); + const float l = n.norm(); + *normal = (l > 0.f) ? Vec3f(n / l) : Vec3f::UnitZ(); + } + return d2; + }; + const auto painted_dist2 = [&painted_closest](const Vec3f &p) { return painted_closest(p, nullptr, nullptr); }; + // Before displacement the queried centroids lie in the same surface as the pieces, so anything + // beyond a hair is genuinely outside the paint. + constexpr float paint_tol = 0.05f; + const auto painted_at = [&painted_dist2](const Vec3f &p) { return painted_dist2(p) < paint_tol * paint_tol; }; + + // "Auto" resolution and budget (0 and -1) resolve here, from the texture and the model - the mesh + // is already in world mm at this point, so no transform is needed. + const bool auto_edge = options.v2_refine_mm <= 0.f, auto_budget = options.v2_max_triangles_k < 0; + const V2Resolution rec = (auto_edge || auto_budget) ? recommend_v2_resolution(mesh, layers) : V2Resolution{}; + TextureBake::PipelineSettings settings; + settings.refine_length = auto_edge ? std::max(0.05, double(rec.edge_mm)) : std::max(0.01f, options.v2_refine_mm); + settings.regularize = options.v2_regularize; + settings.max_triangles = size_t(auto_budget ? std::max(0, rec.budget_k) : options.v2_max_triangles_k) * 1000; + BOOST_LOG_TRIVIAL(info) << "TextureBake resolution: " << settings.refine_length << " mm" + << (auto_edge ? " (auto)" : "") << ", budget " << settings.max_triangles / 1000 << " k" + << (auto_budget ? " (auto)" : ""); + // How far a flat-face harvest may move the surface, tied to the resolution: what a bake refined to + // 1.4 mm edges can merge flat is not what one refined to 0.1 mm may touch. A thirty-second of the + // edge is well under a layer either way - at the default resolution it sheds about 5% of the + // triangles on a relief that covers the whole surface, and far more of one with flat ground in it - + // and the floor keeps a very fine resolution from spending the pass for nothing. + settings.harvest_tol = std::clamp(settings.refine_length / 32.0, 0.005, 0.05); + settings.preserve_untextured = true; + // Always on: relief driven under the plate is unprintable whichever pipeline produced it, so this + // is no longer a choice the user has to make. Only geometry that ends up below the model's own + // bottom is moved - downward relief that stays clear of the plate is untouched. + settings.clamp_below_plate = true; + settings.relocate = options.v2_relocate; + settings.flip_edges = options.v2_flip_edges; + // The sampler already returns millimetres, so the displacement stage must not scale it again. + settings.displace.amplitude = 1.f; + settings.displace.symmetric = false; + // The paint decides what moves here, so the angle limits stay off. + settings.displace.bottom_angle_limit = 0.f; + settings.displace.top_angle_limit = 0.f; + // The sampler's normal only picks the projection blend (triplanar weights); the displacement + // direction is the pipeline's own smooth normal. Handing it the Laplacian-smoothed blend normal + // spreads a crease's 50/50 blend over a band of rows instead of one: on a cube edge the single row + // of vertices that samples both faces' patterns half and half otherwise comes out as a row of + // notches, since it matches neither face. + settings.displace.blend_normal_smoothing = 32; + // Refined faces are asked against the paint itself, so a stroke narrower than a source triangle + // moves only what it covers. + // Only when some included source triangle is painted in part: the pieces then cover less area + // than the triangles they came from. Whole-triangle paint (the usual case, and every bench) has + // nothing to gain from a query per refined face. + { + const auto area_of = [](const indexed_triangle_set &its) { + double a = 0.0; + for (const stl_triangle_vertex_indices &t : its.indices) + a += 0.5 * double((its.vertices[size_t(t[1])] - its.vertices[size_t(t[0])]) + .cross(its.vertices[size_t(t[2])] - its.vertices[size_t(t[0])]).norm()); + return a; + }; + double included_area = 0.0; + for (size_t t = 0; t < mesh.indices.size(); ++t) + if (excluded[t] == 0) { + const stl_triangle_vertex_indices &f = mesh.indices[t]; + included_area += 0.5 * double((mesh.vertices[size_t(f[1])] - mesh.vertices[size_t(f[0])]) + .cross(mesh.vertices[size_t(f[2])] - mesh.vertices[size_t(f[0])]).norm()); + } + const double pieces_area = area_of(painted_pieces); + if (pieces_area < included_area * (1.0 - 1e-4)) + settings.painted = painted_at; + } + // Graded wherever some of the surface is unpainted. A yes/no to a radius, not a distance: most + // queries are far from the paint, and those the tree turns down at its root. + const bool all_painted = std::none_of(excluded.begin(), excluded.end(), [](uint8_t e) { return e != 0; }); + if (settings.painted || !all_painted) + settings.paint_within = [&painted_pieces, &painted_tree](const Vec3d &p, double radius) { + float r2 = float(radius * radius); + return AABBTreeIndirect::is_any_triangle_in_radius(painted_pieces.vertices, painted_pieces.indices, + painted_tree, Vec3f(p.cast()), r2); + }; + + TextureBake::DisplaceBounds bounds; + bounds.min = bounds.max = mesh.vertices.empty() ? Vec3f::Zero() : mesh.vertices.front(); + for (const Vec3f &v : mesh.vertices) { + bounds.min = bounds.min.cwiseMin(v); + bounds.max = bounds.max.cwiseMax(v); + } + + const auto sample = [&combined](const Vec3f &pos, const Vec3f &, const Vec3f &blend_normal) { + // The blend normal chooses the projection; the move itself is along the smooth normal, which + // the pipeline applies on its own. + return combined(pos, blend_normal); + }; + + // The pipeline takes its displacement direction from the soup's winding, so a mirrored placement + // would drive the whole relief inwards. The paint masks were read off `mesh` above, against its + // own vertex order, so the winding can only be turned round after that - here, on the copy that + // becomes the soup - and has to be turned back on the way out, since the caller undoes the same + // mirror when it maps the result back into the volume's coordinates. + indexed_triangle_set oriented = mesh; + if (flip_normals) + for (stl_triangle_vertex_indices &t : oriented.indices) + std::swap(t[1], t[2]); + + // 0 means no simplification, i.e. Bake mode. + const TextureBake::PipelineMode mode = settings.max_triangles > 0 ? TextureBake::PipelineMode::Export + : TextureBake::PipelineMode::Bake; + // Colour, when asked for. The sampler is built now so the simplification can see the colour + // boundaries: a simplified triangle must not span two colours, or its one colour is wrong over + // part of it (half a tile in the neighbour's colour, a tile edge that wanders). + const bool want_color = color != nullptr && color->out_triangle != nullptr && bool(color->quantize); + const ColorFieldSampler color_sampler = + want_color ? make_combined_color_sampler(mesh, layers, facets_data, color->quantize, color->quantize_pure) : ColorFieldSampler{}; + // + // The *palette* index, not the printed filament. The decimation treats any edge whose two faces + // differ as a crease (TextureBakeDecimate.cpp), so it must only ever see where the **perceived** + // colour changes - which is exactly what ColorResolveFn's own contract says the interleaving may + // never be fed into. Handing it the resolved filament made every Z band boundary a crease: on an + // upright wall that is one crease per band, so the collapse ran along those lines and left a stack + // of horizontal slivers, each printing in a single filament. Those were the horizontal colour + // lines in the baked result, and they also spent the triangle budget drawing a pattern the eye is + // meant to blend away. Faces the paint excludes are skipped by the pipeline itself. + const TextureBake::ColorSampleFn color_sample = + color_sampler ? TextureBake::ColorSampleFn([&color_sampler](const Vec3f &p, const Vec3f &n) { + return color_sampler(p, n); + }) + : TextureBake::ColorSampleFn{}; + // The pipeline works on `oriented`, whose winding was reversed above for a mirrored placement, so + // the stages it records are wound the same way. Note where they start and turn the whole range + // back afterwards, exactly as the result itself is turned back below. + const size_t debug_mark = (debug != nullptr) ? debug->mark() : 0; + TextureBake::PipelineResult result = TextureBake::run_pipeline( + TextureBake::to_soup(oriented, excluded), sample, settings, bounds, mode, excluded, + [&progress](const char *, double f) { + return !progress || progress(std::clamp(int(f * 100.0), 0, 99)); + }, + debug, color_sample); + if (debug != nullptr && flip_normals) + debug->rebase(debug_mark, nullptr, /* flip_winding */ true); + if (result.canceled || result.geometry.empty()) + return {}; + + if (stats != nullptr) { + stats->triangles_refined = result.triangles_refined; + stats->triangles_budget = result.triangles_budget; + stats->budget_limited = result.budget_limited; + } + indexed_triangle_set out = TextureBake::to_indexed_triangle_set(result.geometry); + if (out.indices.empty()) + return mesh; + if (flip_normals) + for (stl_triangle_vertex_indices &t : out.indices) + std::swap(t[1], t[2]); + + // Colour, per output triangle. The topology is new, so unlike the classic path there is no base + // triangle to inherit a colour from: each output triangle samples the colour stack at its own + // centroid, and takes colour only where the paint is - measured against the painted pieces, which + // an output centroid is never further from than the relief depth. Then the same despeckle and + // filament resolution as the classic path. + if (want_color) { + std::vector out_color(out.indices.size(), 0); + const ColorFieldSampler &sampler = color_sampler; + if (sampler) { + float max_depth = 0.f; + for (const TextureDisplacementLayer &layer : layers) + max_depth = std::max(max_depth, std::abs(layer.depth_mm)); + const float relief_tol = max_depth + paint_tol; + std::vector palette(out.indices.size(), -1); + tbb::parallel_for(tbb::blocked_range(0, out.indices.size()), [&](const tbb::blocked_range &r) { + for (size_t i = r.begin(); i < r.end(); ++i) { + const stl_triangle_vertex_indices &t = out.indices[i]; + const Vec3f &a = out.vertices[size_t(t[0])], &b = out.vertices[size_t(t[1])], &c = out.vertices[size_t(t[2])]; + const Vec3f centroid = (a + b + c) / 3.f; + // Sample on the *base* surface under this face, not on the relief. The projection + // is a function of position and normal, and the displacement has moved both: the + // triplanar blend weights three axis planes by |n|^4, so a face tilted ~45 degrees + // away from its base normal reads the image half through an unrelated plane. The + // patch border is a ring of exactly such faces - the relief ramps to zero there - + // which is the coloured fringe around the border, and the steep interior slopes + // streak for the same reason. The classic path samples the base patch for this very + // reason; this path was the inconsistent one. + Vec3f foot = centroid, base_n = Vec3f::UnitZ(); + const float d2 = painted_closest(centroid, &foot, &base_n); + if (!all_painted && d2 >= relief_tol * relief_tol) + continue; + palette[i] = sampler(foot, base_n); + } + }); + // The despeckle filter is for a fine, uniform mesh, where one facet flipping colour is + // noise. A simplified mesh is neither: its triangles are as large as the colour regions + // themselves and already end on the colour boundaries, so a majority vote among three + // neighbours would repaint whole features. Bake mode (no simplification) keeps it. + // Not "did a collapse run": a flat-face harvest leaves the mesh as fine as it was, and + // reading it as simplified switched the despeckle off for every bake that harvested. + const bool simplified = result.simplified; + despeckle_triangle_colors(out, palette, simplified ? 0 : color->despeckle_passes); + merge_small_color_regions(out, palette, color->min_color_region_mm2); + for (size_t i = 0; i < out.indices.size(); ++i) { + if (palette[i] < 0) + continue; + const stl_triangle_vertex_indices &t = out.indices[i]; + const Vec3f &a = out.vertices[size_t(t[0])], &b = out.vertices[size_t(t[1])], &c = out.vertices[size_t(t[2])]; + const Vec3f centroid = (a + b + c) / 3.f; + Vec3f normal = (b - a).cross(c - a); + const float nl = normal.norm(); + normal = (nl > 0.f) ? Vec3f(normal / nl) : Vec3f::UnitZ(); + const int filament = color->resolve ? color->resolve(palette[i], centroid, normal) : palette[i]; + if (filament >= 0) + out_color[i] = uint8_t(std::min(filament + 1, 255)); + } + } + *color->out_triangle = std::move(out_color); + } + return out; +} + +} // namespace + +// The bake proper. Runs entirely in whatever space `base_mesh` is given in; the public entry point +// below is what puts it in world space and brings the result back. +// `flip_normals` says the mesh is wound the opposite way round from its outward direction, which is +// what a mirroring world transform leaves behind: the positions are right, but every normal derived +// from the winding points into the model. See build_texture_displacement(). +static indexed_triangle_set build_texture_displacement_in_place( + const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, + const TextureDisplacementOptions &options, + const DisplacementProgressFn &progress, + const TextureColorRequest *color, + bool flip_normals, + BakeStageRecorder *debug, + TextureBakeStats *stats) +{ + // The classic path moves the vertices the mesh already has, so there is no budget to report on. + (void) stats; + // Returns true to keep going. An aborted run returns {} (see the header): an empty mesh is the + // one result no caller can mistake for a finished bake and commit onto the volume. + const auto report = [&progress](int percent) { return !progress || progress(percent); }; + + // Stage capture for the debug view. A stage is timed from the end of the previous one, so the + // capture itself - a copy plus an edge scan - sits outside every measurement it reports. + auto stage_clock = std::chrono::steady_clock::now(); + const auto capture = [&](const char *name, const indexed_triangle_set &m, + const std::string &detail = {}) { + if (debug == nullptr) + return; + const double ms = + std::chrono::duration(std::chrono::steady_clock::now() - stage_clock).count(); + debug->capture(name, m.vertices, m.indices, ms, detail); + stage_clock = std::chrono::steady_clock::now(); + }; + + indexed_triangle_set mesh = base_mesh; + // TriangleSelector's vertex array starts with the mesh's own vertices (any extra ones, created + // where a brush stroke split a triangle, are appended after them), and get_facets_strict() + // emits exactly the *referenced* ones, in order. So selector vertex index i is our vertex i - + // but only if every vertex of `mesh` is referenced by some triangle, which is precisely what + // this call establishes. It is a no-op (indices untouched) for any mesh that already is, which + // in practice is all of them; it exists so an input carrying stray unreferenced vertices can't + // silently shift the indexing and displace the wrong vertices. + its_compactify_vertices(mesh); + if (mesh.vertices.empty() || mesh.indices.empty()) + return mesh; + + capture("input", mesh, "as handed to the bake"); + + if (options.pipeline_v2) + return build_texture_displacement_v2(mesh, layers, facets_data, options, progress, color, flip_normals, + debug, stats); + + // Layers are combined in slot order, like stacked layers in an image editor: each one folds its + // own displacement into the running total via its blend mode (see TextureBlendMode). + std::vector ordered_layers; + for (const TextureDisplacementLayer &layer : layers) + if (!layer.empty() && layer.slot >= 0 && size_t(layer.slot) < TEXTURE_DISPLACEMENT_MAX_LAYERS) + ordered_layers.push_back(&layer); + std::sort(ordered_layers.begin(), ordered_layers.end(), + [](const TextureDisplacementLayer *a, const TextureDisplacementLayer *b) { return a->slot < b->slot; }); + + // Every layer measures its displacement against the *original* surface - normals included - + // rather than against whatever the previous layer left behind. That is what lets all the layers + // be evaluated independently and merged per vertex, instead of having to re-mesh and remap the + // paint masks between them (see the header for why that earlier design was dropped). + std::vector vertex_normals = texture_displacement_vertex_normals(mesh); + + // ... with one correction, applied where the painted area does not cover every triangle around a + // vertex: there the direction to move in is the normal of the *painted* surface, not of the whole + // mesh. On the rim of a fully painted top face the whole-mesh normal is the 45 degrees bisector + // between the face and the side wall it meets, so displacing along it flares the rim outwards + // instead of raising it. Taken over the union of every layer's paint (triangles_to_split is + // exactly the set of original triangles a layer's brush touched - serialize() records an entry for + // each one that is split or carries a non-default state), so a vertex still has one single + // direction however many layers cover it. Interior vertices are unaffected: all their triangles + // are painted, so the two normals coincide. + { + std::vector painted_face(mesh.indices.size(), 0); + bool any_paint = false; + for (const TextureDisplacementLayer *layer : ordered_layers) + for (const TriangleSelector::TriangleBitStreamMapping &m : facets_data[size_t(layer->slot)].triangles_to_split) + if (size_t(m.triangle_idx) < mesh.indices.size()) { + painted_face[size_t(m.triangle_idx)] = 1; + any_paint = true; + } + if (any_paint) { + std::vector painted_normals(mesh.vertices.size(), Vec3f::Zero()); + for (size_t i = 0; i < mesh.indices.size(); ++i) { + if (!painted_face[i]) + continue; + const stl_triangle_vertex_indices &t = mesh.indices[i]; + const Vec3f fn = (mesh.vertices[t[1]] - mesh.vertices[t[0]]).cross(mesh.vertices[t[2]] - mesh.vertices[t[0]]); + for (int k = 0; k < 3; ++k) + painted_normals[size_t(t[k])] += fn; // area-weighted, same convention as the full normals + } + for (size_t v = 0; v < vertex_normals.size(); ++v) + if (const float l = painted_normals[v].norm(); l > 1e-8f) + vertex_normals[v] = painted_normals[v] / l; + // else: no painted triangle touches this vertex, so it will not be displaced anyway - + // leave the whole-mesh normal in place rather than zeroing it. + } + } + + // Both normal passes above read their direction out of the triangle winding, so a mirrored + // placement leaves every one of them pointing into the model - the relief would be carved rather + // than raised. Correct them once, here, where every later stage (displacement direction, the + // planar/triplanar projection axes, the cylinder axis) picks them up already right. + if (flip_normals) + for (Vec3f &n : vertex_normals) + n = -n; + + if (!report(5)) + return {}; + + std::vector displacement(mesh.vertices.size(), 0.f); + // uint8_t rather than std::vector: the sampling loop below writes these from several + // threads at once, and vector's bit packing makes writes to *distinct* elements a data + // race on the shared word. + std::vector displaced(mesh.vertices.size(), 0); + // Union, over every layer, of that layer's patch border - the vertices the post-process smoothing + // holds when TextureDisplacementOptions::smooth_skip_border is set. A vertex on any patch's edge + // counts, which is the conservative choice: hold it rather than let one layer's smoothing melt the + // rim another layer put there. + std::vector on_patch_border(mesh.vertices.size(), false); + bool any_displacement = false; + + // Colour is accumulated per *triangle*, not per vertex: it ends up in the volume's + // mmu_segmentation_facets, which assigns one filament to a whole facet. Layers are visited in + // ascending slot order, so a higher layer simply overwrites a lower one's colour where they + // overlap - the painter's-algorithm reading of a layer stack, and the one that matches how the + // panel lists them. + const bool want_color = color != nullptr && color->out_triangle != nullptr && bool(color->quantize); + // Palette indices, not filament indices: -1 for "no colour here". Kept in perceived-colour space + // for the whole pass so the despeckle filter below operates on what the eye sees, and the + // interleaving that turns a mixed entry into two real filaments happens once, at the very end. + std::vector triangle_palette; + if (want_color) + triangle_palette.assign(mesh.indices.size(), -1); + + const TriangleMesh selector_mesh(mesh); + // One selector for the whole stack, re-deserialized per layer. Its constructor computes + // its_face_neighbors() and its_face_normals() over the *entire* mesh, which on a subdivided model + // is by far the most expensive thing here - building a fresh one per layer paid that cost up to + // eight times over. reset() (what deserialize(..., true) calls) only rebuilds the vertex/triangle + // arrays; the neighbour and face-normal tables are immutable members and survive it. + TriangleSelector selector(selector_mesh); + bool selector_dirty = false; + + const int layer_count = std::max(int(ordered_layers.size()), 1); + int layer_index = 0; + for (const TextureDisplacementLayer *layer : ordered_layers) { + // Progress spans 5..65% across the layers; the apply and smoothing passes take it from there. + if (!report(5 + (60 * layer_index++) / layer_count)) + return {}; + + const TriangleSelector::TriangleSplittingData &data = facets_data[size_t(layer->slot)]; + if (data.triangles_to_split.empty()) + continue; + + const DecodedHeightTexture height = decode_height_texture(*layer); + if (height.empty()) + continue; + + // needs_reset only from the second layer on: the selector is already pristine on the first. + selector.deserialize(data, selector_dirty); + selector_dirty = true; + + const bool color_this_layer = want_color && layer->color_enabled; + // A flat-colour image is matched against the filaments alone (see TextureColorRequest). + const ColorQuantizeFn &layer_quantize = + (color_this_layer && color->quantize_pure && analyze_texture_detail(*layer).flat_colors) ? color->quantize_pure + : color->quantize; + std::vector patch_source; // sub-triangle -> base mesh triangle, only built when colouring + const indexed_triangle_set patch = + selector.get_facets_strict(EnforcerBlockerType::ENFORCER, color_this_layer ? &patch_source : nullptr); + if (patch.indices.empty()) + continue; + // get_facets_strict() returns the same vertex array whichever state is asked for (only the + // triangles are filtered), so `patch` and `rest` share one indexing - and, per the + // compactify above, it is our own. + const indexed_triangle_set rest = selector.get_facets_strict(EnforcerBlockerType::NONE); + + // A vertex used by even one *unpainted* triangle sits on this layer's boundary. It is still + // needed either way - the edge-smoothing falloff measures distance from it - but whether it is + // held flat is now the user's call (TextureDisplacementOptions::displace_border), because + // nothing can tear: the bake is topology-preserving, so a border vertex is one vertex shared + // by both regions and moving it just tilts the unpainted triangles that use it. + std::vector is_boundary(patch.vertices.size(), false); + for (const stl_triangle_vertex_indices &tri : rest.indices) + for (int i = 0; i < 3; ++i) { + is_boundary[tri[i]] = true; + if (tri[i] < int(mesh.vertices.size())) + on_patch_border[size_t(tri[i])] = true; + } + const bool pin_boundary = !options.displace_border; + + // Only the Cylindrical/Spherical methods need the centroid and axis; Triplanar blends each + // vertex's own normal and LSCM solves the patch globally. average_normal is also the fallback + // normal the colour pass below uses for a degenerate triangle. + Vec3f average_normal, patch_centroid, patch_axis; + texture_displacement_patch_frame(patch, vertex_normals, patch_centroid, patch_axis, average_normal); + + // A real unwrap of the whole patch, computed once here rather than per vertex - it is a + // per-chart solve over the whole patch, not a per-point formula. Cached, so repeating this + // for every slider tweak costs a hash rather than a re-solve (see compute_patch_unwrap()). + const std::vector lscm_uvs = (layer->projection_method == TextureProjectionMethod::LSCM) ? + compute_lscm_uvs(patch, *layer) : + std::vector{}; + // The colour pass below samples per *triangle*, so it takes the per-corner unwrap instead: the + // per-vertex collapse above would hand a triangle at a seam the island layout did not join its + // neighbour's placement, painting one triangle per face from the wrong part of the texture. + // (The displacement itself stays on lscm_uvs - a vertex has one position, so one height.) + const std::vector lscm_corner_uvs = (layer->projection_method == TextureProjectionMethod::LSCM) ? + compute_lscm_corner_uvs(patch, *layer) : + std::vector{}; + const bool corner_uv_ok = !lscm_corner_uvs.empty() && + lscm_corner_uvs.size() == patch.indices.size() * 3; + + // Colour, if this layer carries any. Area-weighted over each base triangle's *painted* part, + // so a triangle the brush only clipped a corner off takes the colour of that corner rather + // than of the whole triangle's worth of texture - and so a triangle straddling a colour + // boundary lands on whichever side covers more of it, instead of on whichever sub-triangle + // happened to be emitted first. One quantize call per triangle, after the averaging. + if (color_this_layer) { + const DecodedHeightTexture &tex = height; + if (tex.has_color()) { + std::vector sum(mesh.indices.size(), Vec3f::Zero()); + std::vector sum_area(mesh.indices.size(), 0.f); + for (size_t j = 0; j < patch.indices.size() && j < patch_source.size(); ++j) { + const size_t S = size_t(patch_source[j]); + if (S >= mesh.indices.size()) + continue; + const stl_triangle_vertex_indices &t = patch.indices[j]; + const Vec3f &pa = patch.vertices[size_t(t[0])]; + const Vec3f &pb = patch.vertices[size_t(t[1])]; + const Vec3f &pc = patch.vertices[size_t(t[2])]; + const float area2 = (pb - pa).cross(pc - pa).norm(); + if (area2 <= 0.f) + continue; + const Vec3f centroid = (pa + pb + pc) / 3.f; + + // The normal the triplanar blend weights by, and the unwrap coordinate the LSCM + // path needs, both averaged over the sub-triangle's corners - the same quantities + // the per-vertex height sampling uses, evaluated at the centroid instead. + Vec3f n = Vec3f::Zero(); + Vec2f uv = Vec2f::Zero(); + bool have_uv = !lscm_uvs.empty(); + for (int k = 0; k < 3; ++k) { + const int vi = t[k]; + if (vi < int(vertex_normals.size())) + n += vertex_normals[size_t(vi)]; + if (!have_uv) + continue; + if (corner_uv_ok) + uv += lscm_corner_uvs[j * 3 + size_t(k)]; + else if (size_t(vi) < lscm_uvs.size()) + uv += lscm_uvs[size_t(vi)]; + else + have_uv = false; + } + n = (n.norm() > 1e-8f) ? Vec3f(n.normalized()) : average_normal; + uv /= 3.f; + + Vec3f rgb; + if (sample_layer_color(tex, *layer, centroid, n, rgb, patch_centroid, patch_axis, + have_uv ? &uv : nullptr)) { + sum[S] += area2 * rgb; + sum_area[S] += area2; + } + } + for (size_t i = 0; i < mesh.indices.size(); ++i) + if (sum_area[i] > 0.f) { + const int idx = layer_quantize(sum[i] / sum_area[i]); + // A quantizer that declines this colour leaves whatever a lower layer put + // there, rather than punching a hole in it. + if (idx >= 0) + triangle_palette[i] = idx; + } + } + } + + // Edge smoothing: a per-vertex weight in [0, 1] that fades the displacement to zero toward the + // patch boundary. amount->0 leaves only the very edge softened; amount->1 fades the whole patch + // flat. k = (1-a)/a turns the normalized boundary distance into that weight (see the header). + std::vector edge_weight; + if (layer->edge_smoothing && layer->edge_smoothing_amount > 0.f) { + const std::vector bdist = patch_boundary_distance(patch, is_boundary); + float max_d = 0.f; + for (const float d : bdist) + if (std::isfinite(d)) + max_d = std::max(max_d, d); + edge_weight.assign(patch.vertices.size(), 1.f); + if (max_d > 1e-6f) { + const float a = std::clamp(layer->edge_smoothing_amount, 0.f, 1.f); + const float k = (a < 1.f) ? (1.f - a) / std::max(a, 1e-3f) : 0.f; + for (size_t v = 0; v < bdist.size() && v < edge_weight.size(); ++v) { + const float d = std::isfinite(bdist[v]) ? bdist[v] : max_d; + edge_weight[v] = std::clamp((d / max_d) * k, 0.f, 1.f); + } + } + } + + const float sign = layer->invert ? -1.f : 1.f; + // A vertex may be reached by several of the patch's triangles; each must fold into the + // running total exactly once, or a Multiply/Subtract layer would apply two or three times + // over depending on how many painted triangles happen to share the vertex. Collecting the + // unique list up front (cheap, one pass) is also what lets the expensive part - the texture + // sampling, which is three bilinear fetches plus three pow()s per vertex for triplanar - run + // in parallel below, instead of serially inside the triangle walk. + std::vector layer_vertices; + std::vector visited(patch.vertices.size(), 0); + layer_vertices.reserve(patch.vertices.size()); + for (const stl_triangle_vertex_indices &tri : patch.indices) + for (int i = 0; i < 3; ++i) { + const int vi = tri[i]; + // Split vertices the brush introduced live past the end of our own vertex array; + // they carry no displacement of their own and are not part of the output mesh. + if (vi >= int(mesh.vertices.size()) || (pin_boundary && is_boundary[vi]) || visited[vi]) + continue; + visited[vi] = 1; + layer_vertices.push_back(vi); + } + if (layer_vertices.empty()) + continue; + + std::vector sampled(layer_vertices.size(), 0.f); + tbb::parallel_for(tbb::blocked_range(0, layer_vertices.size()), + [&](const tbb::blocked_range &range) { + for (size_t k = range.begin(); k < range.end(); ++k) { + const size_t vi = size_t(layer_vertices[k]); + const Vec2f *lscm_uv = lscm_uvs.empty() ? nullptr : &lscm_uvs[vi]; + const float h = sample_layer_height(height, *layer, mesh.vertices[vi], vertex_normals[vi], + patch_centroid, patch_axis, lscm_uv); + // midlevel is the height that means "stay put", so anything below it displaces + // *inwards* - see TextureDisplacementLayer::midlevel. At the default of 0 this is + // exactly the old outward-only behaviour. + sampled[k] = (h - layer->midlevel) * layer->depth_mm * sign; + } + }); + + for (size_t k = 0; k < layer_vertices.size(); ++k) { + const size_t vi = size_t(layer_vertices[k]); + // The first layer to reach a vertex has nothing underneath it to blend with, so it + // always starts the total off additively - a Multiply/Divide against an implicit + // zero base would otherwise annihilate (or blow up) it, which is never what the + // user means by putting a mask on the bottom of the stack. + const float accumulated = displacement[vi]; + const float blended = blend_displacement(accumulated, sampled[k], + displaced[vi] ? layer->blend_mode : TextureBlendMode::Add); + // Edge smoothing fades this layer's *effect*, not its input. Scaling the input instead is + // only correct for Add/Subtract, whose neutral value is 0: on a Multiply layer a faded + // input approaches 0, which annihilates everything beneath it at the rim rather than + // leaving it alone, and on a Divide layer it approaches the 0.05 divisor floor, which + // amplifies the relief underneath by up to 20x exactly where it was meant to fade out. + // Interpolating the blended result back toward the accumulated total is the neutral + // element for every mode at once, and reduces to the old formula exactly for Add. + const float edge_w = edge_weight.empty() ? 1.f : edge_weight[vi]; + displacement[vi] = accumulated + (blended - accumulated) * edge_w; + displaced[vi] = 1; + } + any_displacement = true; + } + + if (!report(65)) + return {}; + + if (!any_displacement) + return mesh; + + // The model's own resting plane, taken before anything moves - see the clamp after smoothing. + float resting_z = std::numeric_limits::max(); + for (const Vec3f &v : mesh.vertices) + resting_z = std::min(resting_z, v.z()); + + size_t moved_count = 0; + for (size_t vi = 0; vi < mesh.vertices.size(); ++vi) + if (displaced[vi]) { + mesh.vertices[vi] += vertex_normals[vi] * displacement[vi]; + ++moved_count; + } + capture("displace", mesh, std::to_string(moved_count) + " of " + + std::to_string(mesh.vertices.size()) + " vertices moved"); + + // Post-process relaxation of what the height maps left behind, restricted to the vertices that + // actually moved - the untouched part of the model keeps its exact geometry, and the ring of + // vertices just outside the displaced set stays put and anchors the smoothing so the relief does + // not creep outward. `smooth_skip_border` additionally holds the patch's own outermost ring, whose + // neighbours are those pinned outsiders: relaxing it would drag the rim of the relief back down and + // leave the pattern looking half-melted right where it meets the edge. + if (options.smooth_enabled && options.smooth_strength > 0.f && options.smooth_iterations > 0) { + if (!report(70)) + return {}; + std::vector movable(mesh.vertices.size(), 0); + for (size_t vi = 0; vi < mesh.vertices.size(); ++vi) + movable[vi] = (displaced[vi] && !(options.smooth_skip_border && on_patch_border[vi])) ? 1 : 0; + // The pass hook only *stops* the relaxation early; the report(99) below is what turns a + // cancellation into an empty (uncommittable) result, since a cancelled run keeps reporting + // cancelled. + smooth_mesh_vertices(mesh, movable, options.smooth_strength, options.smooth_iterations, + progress ? DisplacementProgressFn([&report, it = options.smooth_iterations](int pass) { + return report(70 + (29 * (pass + 1)) / std::max(it, 1)); + }) : DisplacementProgressFn{}); + capture("smooth", mesh, + std::to_string(options.smooth_iterations) + " iterations at strength " + + std::to_string(options.smooth_strength)); + } + + // Nothing driven below the model's own resting plane can be printed: it is either through the + // build plate or, once the slicer drops the part back down onto it, holding the whole model up in + // the air. Push it back up to the plane. Only vertices the displacement actually moved are + // eligible - untouched geometry is already exactly where it started - and only those that ended + // up below it, so downward relief that stays clear of the plate is left alone. Runs in world + // space (see build_texture_displacement()), so this really is the plate and not some scaled + // stand-in for it. + size_t clamped_count = 0; + if (resting_z < std::numeric_limits::max()) + for (size_t vi = 0; vi < mesh.vertices.size(); ++vi) + if (displaced[vi] && mesh.vertices[vi].z() < resting_z) { + mesh.vertices[vi].z() = resting_z; + ++clamped_count; + } + capture("clamp to plate", mesh, std::to_string(clamped_count) + " vertices raised to z = " + + std::to_string(resting_z)); + + if (!report(99)) + return {}; + if (want_color) { + // Despeckle in perceived-colour space, then resolve each entry to a real filament. The order + // matters both ways round: filtering after the interleave would erase the bands it is supposed + // to keep, and interleaving before the filter would have the filter treat two halves of one + // blended colour as a disagreement. + despeckle_triangle_colors(mesh, triangle_palette, color->despeckle_passes); + merge_small_color_regions(mesh, triangle_palette, color->min_color_region_mm2); + + std::vector out_color(mesh.indices.size(), 0); + for (size_t i = 0; i < mesh.indices.size(); ++i) { + if (triangle_palette[i] < 0) + continue; + const stl_triangle_vertex_indices &t = mesh.indices[i]; + const Vec3f &a = mesh.vertices[size_t(t[0])], &b = mesh.vertices[size_t(t[1])], &c = mesh.vertices[size_t(t[2])]; + const Vec3f centroid = (a + b + c) / 3.f; + Vec3f normal = (b - a).cross(c - a); + const float nl = normal.norm(); + normal = (nl > 0.f) ? Vec3f(normal / nl) : Vec3f::UnitZ(); + const int filament = color->resolve ? color->resolve(triangle_palette[i], centroid, normal) + : triangle_palette[i]; + if (filament >= 0) + out_color[i] = uint8_t(std::min(filament + 1, 255)); + } + // Handed over only on a run that completed: every early return above is a cancellation, and + // the caller must not commit a half-computed colouring any more than a half-displaced mesh. + *color->out_triangle = std::move(out_color); + } + return mesh; +} + +indexed_triangle_set build_texture_displacement(const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, + const TextureDisplacementOptions &options, + const DisplacementProgressFn &progress, + const TextureColorRequest *color, + const Transform3d &volume_to_world, + BakeStageRecorder *debug, + TextureBakeStats *stats) +{ + // An untransformed volume on an untransformed instance is by far the common case, and the round + // trip costs two matrix multiplies per vertex on a mesh that can carry millions of them - so take + // the identity out of the way rather than paying for it. + // The texture is projected in the bake frame - world orientation and scale, anchored at the + // volume's origin (see texture_displacement_bake_frame()). + const Transform3d frame = texture_displacement_bake_frame(volume_to_world); + if (frame.matrix().isApprox(Transform3d::Identity().matrix())) + return build_texture_displacement_in_place(base_mesh, layers, facets_data, options, progress, color, + false, debug, stats); + + const Transform3d to_local = frame.inverse(); + // A mirroring placement leaves the positions correct but every winding-derived normal pointing + // the wrong way. The winding itself is deliberately *not* touched here: the paint masks encode + // each split triangle against its own vertex order, so reordering a triangle's vertices would + // mirror the paint inside it. The bake is told instead, and negates the normals it computes. + const bool mirrored = frame.linear().determinant() < 0.0; + + indexed_triangle_set world = base_mesh; + for (Vec3f &v : world.vertices) + v = (frame * v.cast()).cast(); + + const size_t debug_mark = (debug != nullptr) ? debug->mark() : 0; + indexed_triangle_set out = build_texture_displacement_in_place(world, layers, facets_data, options, + progress, color, mirrored, debug, stats); + // Everything the bake recorded is in world millimetres, like `out` itself. The debug view draws in + // the volume's local frame, so the stages are brought back the same way the result is. + if (debug != nullptr) + debug->rebase(debug_mark, &to_local, /* flip_winding */ false); + // A cancelled run returns {} and must stay {} - an empty mesh is the signal the caller checks + // before committing anything onto the volume. + if (out.vertices.empty()) + return out; + + for (Vec3f &v : out.vertices) + v = (to_local * v.cast()).cast(); + return out; +} + +void texture_displacement_patch_frame(const indexed_triangle_set &patch, const std::vector &vertex_normals, + Vec3f ¢er, Vec3f &axis, Vec3f &average_normal) +{ + Vec3f normal_sum = Vec3f::Zero(); + Vec3f centroid_sum = Vec3f::Zero(); + int count = 0; + for (const stl_triangle_vertex_indices &tri : patch.indices) + for (int i = 0; i < 3; ++i) { + const int vi = tri[i]; + centroid_sum += patch.vertices[size_t(vi)]; + ++count; + // A brush stroke that split a triangle appends new vertices past the base mesh's own, and + // vertex_normals is sized to the base mesh, so those indices must be skipped here. + if (vi < int(vertex_normals.size())) + normal_sum += vertex_normals[size_t(vi)]; + } + average_normal = (normal_sum.norm() > 1e-8f) ? Vec3f(normal_sum.normalized()) : Vec3f::UnitZ(); + center = (count > 0) ? Vec3f(centroid_sum / float(count)) : Vec3f::Zero(); + if (count == 0) { + // Nothing to measure: an upright cylinder about the origin, rather than the axis least aligned + // with a normal that is itself only a fallback. + axis = Vec3f::UnitZ(); + return; + } + + // The world axis least aligned with the average normal - perpendicular to the outward radial + // normal, as a cylinder's own axis would be. + const Vec3f an = average_normal.cwiseAbs(); + axis = (an.x() <= an.y() && an.x() <= an.z()) ? Vec3f::UnitX() : + (an.y() <= an.x() && an.y() <= an.z()) ? Vec3f::UnitY() : Vec3f::UnitZ(); +} + +Transform3d texture_displacement_bake_frame(const Transform3d &volume_to_world) +{ + // World orientation and scale, but the origin moved to where the volume's own origin sits: the + // texture then rides with the model when it is moved about the plate (and a single, untiled stamp + // starts on the model rather than at the plate's corner), while a tile is still `tiling_scale` + // printed millimetres whatever the instance's scale. + return Eigen::Translation3d(-volume_to_world.translation()) * volume_to_world; +} + +Transform3d texture_displacement_volume_to_world(const ModelVolume &volume) +{ + const ModelObject *object = volume.get_object(); + if (object == nullptr || object->instances.empty() || object->instances.front() == nullptr) + return volume.get_matrix(); + return object->instances.front()->get_matrix() * volume.get_matrix(); +} + +indexed_triangle_set build_texture_displacement(const ModelVolume &volume) +{ + TextureDisplacementFacetsData facets_data; + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + facets_data[size_t(i)] = volume.texture_displacement_facet(i).get_data(); + + return build_texture_displacement(volume.mesh().its, volume.texture_displacement_layers, facets_data, + volume.texture_displacement_options, {}, nullptr, + texture_displacement_volume_to_world(volume)); +} + +void smooth_mesh_vertices(indexed_triangle_set &mesh, const std::vector &movable, float strength, + int iterations, const DisplacementProgressFn &on_pass) +{ + if (iterations <= 0 || mesh.vertices.empty() || movable.size() != mesh.vertices.size()) + return; + strength = std::clamp(strength, 0.f, 1.f); + if (strength <= 0.f) + return; + if (std::none_of(movable.begin(), movable.end(), [](uint8_t m) { return m != 0; })) + return; + + // One-ring neighbours as a CSR-style pair of arrays: counted, prefix-summed, then filled. A + // triangle contributes each of its edges to both endpoints, so a shared edge is listed once per + // incident triangle - the duplicates are harmless here, they just weight an interior edge the same + // way from both sides, and dropping them would cost a sort per vertex for no visible difference. + const size_t nv = mesh.vertices.size(); + std::vector start(nv + 1, 0); + for (const stl_triangle_vertex_indices &t : mesh.indices) + for (int e = 0; e < 3; ++e) { + ++start[size_t(t[e]) + 1]; + ++start[size_t(t[(e + 1) % 3]) + 1]; + } + for (size_t v = 0; v < nv; ++v) + start[v + 1] += start[v]; + const size_t total_refs = size_t(start[nv]); + std::vector nbr(total_refs, 0); + std::vector fill(start.begin(), start.begin() + nv); + for (const stl_triangle_vertex_indices &t : mesh.indices) + for (int e = 0; e < 3; ++e) { + const int a = t[e], b = t[(e + 1) % 3]; + nbr[size_t(fill[size_t(a)]++)] = b; + nbr[size_t(fill[size_t(b)]++)] = a; + } + + // Read every pass from a snapshot of the previous one, so the result does not depend on the order + // vertices happen to be visited in (a Gauss-Seidel sweep would smooth several times as hard at the + // end of the array as at the start). + std::vector prev; + for (int it = 0; it < iterations; ++it) { + prev = mesh.vertices; + // Each vertex reads only from `prev` and writes only its own slot, so the sweep parallelises + // with no synchronisation at all. + tbb::parallel_for(tbb::blocked_range(0, nv), [&](const tbb::blocked_range &range) { + for (size_t v = range.begin(); v < range.end(); ++v) { + if (!movable[v] || start[v] == start[v + 1]) + continue; + Vec3f sum = Vec3f::Zero(); + for (int k = start[v]; k < start[v + 1]; ++k) + sum += prev[size_t(nbr[size_t(k)])]; + const Vec3f avg = sum / float(start[v + 1] - start[v]); + mesh.vertices[v] = prev[v] + (avg - prev[v]) * strength; + } + }); + if (on_pass && !on_pass(it)) + return; // cancelled: leave the passes done so far in place, the caller decides what to do + } +} + +namespace { +// One decoded texture + placement per sampleable layer, in blend (slot) order. Held by shared_ptr so +// the returned closure owns it for as long as the subdivider keeps calling back. +// An unwrap turned into something a *point* sampler can use. LSCM has no formula from position to +// uv - it is a per-triangle map - so a point is placed on the painted patch (the nearest patch +// triangle, and its barycentric coordinates there) and the uv is interpolated from that triangle's own +// per-corner uvs. Exact for a point on the base surface, which is where both samplers are queried: the +// displacement samples refined positions before moving them, and the colour pass samples the foot +// point on the painted pieces. +struct LscmLookup { + indexed_triangle_set patch; // the layer's painted patch, as the unwrap was solved on + AABBTreeIndirect::Tree3f tree; + std::vector corner; // compute_lscm_corner_uvs(patch, layer) + + // False when `pos` is not on this layer's patch (farther than `tol`): there is no uv there, so the + // layer contributes nothing - the same as a non-tiled texture outside its placement. + bool uv_at(const Vec3f &pos, float tol, Vec2f &uv) const + { + size_t hit = 0; + Vec3f foot; + const float d2 = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(patch.vertices, patch.indices, tree, + pos, hit, foot); + if (d2 < 0.f || d2 > tol * tol || hit >= patch.indices.size()) + return false; + const stl_triangle_vertex_indices &t = patch.indices[hit]; + const Vec3f &a = patch.vertices[size_t(t[0])], &b = patch.vertices[size_t(t[1])], &c = patch.vertices[size_t(t[2])]; + const Vec3f e0 = b - a, e1 = c - a, ep = foot - a; + const float d00 = e0.dot(e0), d01 = e0.dot(e1), d11 = e1.dot(e1), dp0 = ep.dot(e0), dp1 = ep.dot(e1); + const float den = d00 * d11 - d01 * d01; + float w1 = 1.f / 3.f, w2 = 1.f / 3.f; // a degenerate triangle takes its centroid's uv + if (std::abs(den) > 1e-20f) { + w1 = (d11 * dp0 - d01 * dp1) / den; + w2 = (d00 * dp1 - d01 * dp0) / den; + } + const Vec2f *c3 = &corner[hit * 3]; + uv = (1.f - w1 - w2) * c3[0] + w1 * c3[1] + w2 * c3[2]; + return true; + } +}; + +// A layer's painted patch as a point-in-region test. Every layer is sampled on its own paint only - the +// analytic projections included: unlike an unwrap they are defined everywhere, so without this every layer's +// relief was stacked over every other layer's painted area, and the top layer's texture showed on all of them. +struct PatchRegion { + indexed_triangle_set patch; + AABBTreeIndirect::Tree3f tree; + + bool contains(const Vec3f &pos, float tol) const + { + size_t hit = 0; + Vec3f foot; + const float d2 = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(patch.vertices, patch.indices, tree, + pos, hit, foot); + return d2 >= 0.f && d2 <= tol * tol; + } +}; + +struct PreparedLayer { + DecodedHeightTexture tex; + TextureDisplacementLayer layer; // a copy of the params (depth/tiling/rotation/offset/blend/...) + Vec3f center; // patch centroid, for Cylindrical/Spherical + Vec3f axis; // cylinder axis, for Cylindrical + // Unwrap layers only; null when the unwrap failed, in which case sampling falls through to the + // layer's analytic fallback exactly as build_texture_displacement()'s classic path does. + std::shared_ptr lscm; + // The painted patch of a layer without an unwrap lookup (the unwrap's own lookup already stops at its patch). + // Null when the paint covers the whole mesh, where every point is on it. + std::shared_ptr region; + + // The uv to hand sample_layer_height()/sample_layer_color(): nullptr for every analytic projection + // (they project `pos` themselves). False means `pos` is off this layer's paint and the layer must be + // skipped. + bool lscm_uv(const Vec3f &pos, Vec2f &uv, const Vec2f *&out) const + { + out = nullptr; + // Queries lie on the base surface, so anything beyond a hair is off this layer's patch. + constexpr float ON_PATCH_TOL = 0.05f; + if (region && !region->contains(pos, ON_PATCH_TOL)) + return false; + if (!lscm) + return true; + if (!lscm->uv_at(pos, ON_PATCH_TOL, uv)) + return false; + out = &uv; + return true; + } +}; + +// Shared by both point samplers, so the height field and the colour field can never disagree about +// where a layer is placed. `need_color` additionally drops layers that cannot contribute colour. +std::shared_ptr> prepare_sampleable_layers( + const indexed_triangle_set &base_mesh, const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, bool need_color) +{ + auto prepared = std::make_shared>(); + + if (base_mesh.indices.empty()) + return prepared; + + std::vector ordered; + for (const TextureDisplacementLayer &l : layers) + if (l.slot >= 0 && l.slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS)) + ordered.push_back(&l); + std::sort(ordered.begin(), ordered.end(), + [](const TextureDisplacementLayer *a, const TextureDisplacementLayer *b) { return a->slot < b->slot; }); + + const std::vector vertex_normals = texture_displacement_vertex_normals(base_mesh); + const TriangleMesh selector_mesh(base_mesh); + const float mesh_area = area_3d(base_mesh); + + for (const TextureDisplacementLayer *layer : ordered) { + // Unwrap layers used to be skipped here ("no per-point UV"). That made the default pipeline + // bake an unwrap layer as nothing at all - and since the job then clears the baked layers' + // paint, the painted region simply vanished. They get an LscmLookup below instead. + if (need_color && !layer->color_enabled) + continue; + const TriangleSelector::TriangleSplittingData &data = facets_data[size_t(layer->slot)]; + if (data.triangles_to_split.empty()) + continue; + const DecodedHeightTexture tex = decode_height_texture(*layer); + if (tex.empty() || (need_color && !tex.has_color())) + continue; + + TriangleSelector selector(selector_mesh); + selector.deserialize(data, false); + const indexed_triangle_set patch = selector.get_facets_strict(EnforcerBlockerType::ENFORCER); + if (patch.indices.empty()) + continue; + + // Patch centroid + cylinder axis, shared with build_texture_displacement() so a + // Cylindrical/Spherical layer's detach criterion matches the geometry the bake will produce. + Vec3f centroid, axis, average_normal; + texture_displacement_patch_frame(patch, vertex_normals, centroid, axis, average_normal); + + std::shared_ptr lscm; + if (layer->projection_method == TextureProjectionMethod::LSCM) { + // Solved on the very patch the classic path and the GUI solve it on (same geometry, seam + // angle and edges), so it hits the unwrap cache and lands exactly where the UV editor + // shows it, hand-placed islands and UV edits included. + auto l = std::make_shared(); + l->corner = compute_lscm_corner_uvs(patch, *layer); + if (l->corner.size() == patch.indices.size() * 3) { + l->patch = patch; + l->tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(l->patch.vertices, l->patch.indices); + lscm = std::move(l); + } + } + + std::shared_ptr region; + if (!lscm && area_3d(patch) < 0.9999f * mesh_area) { + auto r = std::make_shared(); + r->patch = patch; + r->tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(r->patch.vertices, r->patch.indices); + region = std::move(r); + } + + prepared->push_back({ tex, *layer, centroid, axis, std::move(lscm), std::move(region) }); + } + return prepared; +} +} // namespace + +ColorFieldSampler make_combined_color_sampler(const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, + ColorQuantizeFn quantize, + ColorQuantizeFn quantize_pure) +{ + if (!quantize) + return nullptr; + auto prepared = prepare_sampleable_layers(base_mesh, layers, facets_data, /* need_color */ true); + if (prepared->empty()) + return nullptr; + // Per layer: a flat-colour image is matched against the filaments alone, when that quantizer + // was supplied; anything else may use the mixes. Decided once here, not per sample. + auto pure = std::make_shared>(prepared->size(), 0); + if (quantize_pure) + for (size_t i = 0; i < prepared->size(); ++i) + (*pure)[i] = analyze_texture_detail((*prepared)[i].layer).flat_colors ? 1 : 0; + + return [prepared, pure, quantize = std::move(quantize), quantize_pure = std::move(quantize_pure)](const Vec3f &pos, const Vec3f &normal) -> int { + // Last one wins: `prepared` is in ascending slot order and the bake lets a higher layer + // overwrite a lower one's colour, so the sampler has to resolve overlaps the same way. + int result = -1; + for (size_t i = 0; i < prepared->size(); ++i) { + const PreparedLayer &p = (*prepared)[i]; + Vec2f uv; + const Vec2f *lscm_uv = nullptr; + if (!p.lscm_uv(pos, uv, lscm_uv)) + continue; + Vec3f rgb; + if (sample_layer_color(p.tex, p.layer, pos, normal, rgb, p.center, p.axis, lscm_uv)) + if (const int idx = ((*pure)[i] ? quantize_pure : quantize)(rgb); idx >= 0) + result = idx; + } + return result; + }; +} + +HeightFieldSampler make_combined_displacement_sampler(const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data) +{ + auto prepared = prepare_sampleable_layers(base_mesh, layers, facets_data, /* need_color */ false); + if (prepared->empty()) + return nullptr; + + return [prepared](const Vec3f &pos, const Vec3f &normal) -> float { + float total = 0.f; + bool any = false; + for (const PreparedLayer &p : *prepared) { + Vec2f uv; + const Vec2f *lscm_uv = nullptr; + if (!p.lscm_uv(pos, uv, lscm_uv)) + continue; // off this unwrap layer's patch: no uv, so no contribution + const float h = sample_layer_height(p.tex, p.layer, pos, normal, p.center, p.axis, lscm_uv); + const float sign = p.layer.invert ? -1.f : 1.f; + const float signed_h = (h - p.layer.midlevel) * p.layer.depth_mm * sign; + // The first (lowest) sampleable layer folds additively; the rest use their own blend mode - + // same rule build_texture_displacement() applies per vertex. + total = blend_displacement(total, signed_h, any ? p.layer.blend_mode : TextureBlendMode::Add); + any = true; + } + return total; + }; +} + +indexed_triangle_set subdivide_mesh_uniform(const indexed_triangle_set &mesh, float max_edge_length_mm, int max_iterations) +{ + indexed_triangle_set current = mesh; + const float max_edge_sq = max_edge_length_mm * max_edge_length_mm; + + for (int iter = 0; iter < max_iterations; ++iter) { + // One vertex-index pair (always stored low-index-first) -> the midpoint vertex already + // created for it in this pass, so the two triangles sharing that edge both get the exact + // same new vertex instead of two separate, coincident-but-distinct ones (which would leave + // the mesh non-manifold even though it looks fine). + std::unordered_map midpoint_cache; + auto edge_key = [](int a, int b) -> uint64_t { + if (a > b) + std::swap(a, b); + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); + }; + auto get_midpoint = [&](int a, int b) -> int { + const uint64_t key = edge_key(a, b); + auto it = midpoint_cache.find(key); + if (it != midpoint_cache.end()) + return it->second; + const int idx = int(current.vertices.size()); + current.vertices.push_back((current.vertices[a] + current.vertices[b]) * 0.5f); + midpoint_cache.emplace(key, idx); + return idx; + }; + + std::vector new_indices; + new_indices.reserve(current.indices.size()); + bool any_split = false; + for (const stl_triangle_vertex_indices &tri : current.indices) { + const Vec3f &a = current.vertices[tri[0]]; + const Vec3f &b = current.vertices[tri[1]]; + const Vec3f &c = current.vertices[tri[2]]; + if ((b - a).squaredNorm() <= max_edge_sq && (c - b).squaredNorm() <= max_edge_sq && (a - c).squaredNorm() <= max_edge_sq) { + new_indices.push_back(tri); + continue; + } + + any_split = true; + const int m01 = get_midpoint(tri[0], tri[1]); + const int m12 = get_midpoint(tri[1], tri[2]); + const int m20 = get_midpoint(tri[2], tri[0]); + new_indices.push_back(stl_triangle_vertex_indices(tri[0], m01, m20)); + new_indices.push_back(stl_triangle_vertex_indices(m01, tri[1], m12)); + new_indices.push_back(stl_triangle_vertex_indices(m20, m12, tri[2])); + new_indices.push_back(stl_triangle_vertex_indices(m01, m12, m20)); + } + + current.indices = std::move(new_indices); + if (!any_split) + break; + } + + return current; +} + +indexed_triangle_set subdivide_mesh_adaptive(const indexed_triangle_set &mesh, + const std::vector &refine_region, + float target_edge_length_mm, int max_triangles, + std::vector *out_source, const HeightFieldSampler &sampler, + float chord_tolerance_mm, float min_edge_length_mm, + float border_edge_length_mm, + const DisplacementProgressFn &progress, + const ColorFieldSampler &color, float color_edge_length_mm, + bool split_multi_crossings) +{ + // Neighbour slots that are not a triangle index. + constexpr int NB_BOUNDARY = -1; // open edge: terminal on its own, bisected from this side alone + constexpr int NB_NONMANIFOLD = -2; // >2 triangles on the edge: never bisected, that would tear it + + // v[] and nb[] are parallel: nb[e] is the triangle across edge (v[e], v[(e+1)%3]). `src` is the + // input triangle this one descends from - children inherit it, so a caller can carry per-triangle + // data (a paint mask) across the topology change with no geometric remap. + struct Tri { int v[3]; int nb[3]; int src; }; + + std::vector verts = mesh.vertices; + std::vector tris(mesh.indices.size()); + for (size_t i = 0; i < mesh.indices.size(); ++i) + tris[i] = { { mesh.indices[i][0], mesh.indices[i][1], mesh.indices[i][2] }, + { NB_BOUNDARY, NB_BOUNDARY, NB_BOUNDARY }, int(i) }; + + auto emit = [&]() -> indexed_triangle_set { + indexed_triangle_set out; + out.vertices = verts; + out.indices.reserve(tris.size()); + if (out_source) { + out_source->clear(); + out_source->reserve(tris.size()); + } + for (const Tri &t : tris) { + out.indices.emplace_back(t.v[0], t.v[1], t.v[2]); + if (out_source) + out_source->push_back(t.src); + } + return out; + }; + + // Feature-adaptive when a sampler and a positive tolerance are supplied; otherwise refinement is + // driven by the length baseline alone. + const bool feature_mode = bool(sampler) && chord_tolerance_mm > 0.f; + const bool color_mode = bool(color) && color_edge_length_mm > 0.f; + const bool multi_mode = feature_mode && split_multi_crossings; + float step_iso_mm = 0.f; // the mid-level a step crosses; set once the region is sampled + float step_dev_mm = std::numeric_limits::max(); // deviations above this are steps + const float color_sq = color_edge_length_mm > 0.f ? color_edge_length_mm * color_edge_length_mm : 0.f; + const float min_floor_sq = min_edge_length_mm > 0.f ? min_edge_length_mm * min_edge_length_mm : 0.f; + const float target_sq = target_edge_length_mm > 0.f ? target_edge_length_mm * target_edge_length_mm : 0.f; + const float border_sq = border_edge_length_mm > 0.f ? border_edge_length_mm * border_edge_length_mm : 0.f; + + // refine_region is indexed by input-triangle index, and every triangle's src stays in that range + // (children inherit their parent's src), so a wrong size would be an out-of-bounds read. Guard it. + if (refine_region.size() != mesh.indices.size() || int(tris.size()) + 2 > max_triangles) + return emit(); + if (!feature_mode && !color_mode && target_sq <= 0.f && border_sq <= 0.f) + return emit(); // no criterion at all + if (std::none_of(refine_region.begin(), refine_region.end(), [](uint8_t v) { return v != 0; })) + return emit(); // nothing flagged: no-op + + auto edge_key = [](int a, int b) -> uint64_t { + if (a > b) + std::swap(a, b); + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); + }; + + // Edge adjacency, built once here and then maintained incrementally by bisect() below. Rebuilding + // it per refinement pass is what made the previous version's cost scale with the whole model + // instead of with the refined region, and what forced the tiny pass budget that stopped + // refinement short. + { + // Sort the half-edges by their edge key and walk the equal runs, rather than hashing every one + // of them twice into an unordered_map. Same result, but the two expensive parts - forming the + // keys and ordering them - both parallelise, where a shared hash map cannot. The map also cost + // a second full pass of lookups purely to read back what the first pass had just inserted. + std::vector> he(tris.size() * 3); // (edge key, triangle * 3 + local edge) + tbb::parallel_for(tbb::blocked_range(0, tris.size()), + [&](const tbb::blocked_range &range) { + for (size_t ti = range.begin(); ti < range.end(); ++ti) + for (int e = 0; e < 3; ++e) + he[ti * 3 + size_t(e)] = { + edge_key(tris[ti].v[e], tris[ti].v[(e + 1) % 3]), int(ti) * 3 + e + }; + }); + tbb::parallel_sort(he.begin(), he.end()); + // Runs of equal key are the half-edges of one edge: one is a boundary, two are neighbours, + // more is non-manifold. Serial, but it is a single linear pass over an already ordered array. + for (size_t i = 0; i < he.size();) { + size_t j = i + 1; + while (j < he.size() && he[j].first == he[i].first) + ++j; + const size_t count = j - i; + if (count == 2) { + const int a = he[i].second, b = he[i + 1].second; + tris[size_t(a / 3)].nb[a % 3] = b / 3; + tris[size_t(b / 3)].nb[b % 3] = a / 3; + } else if (count > 2) { + for (size_t k = i; k < j; ++k) + tris[size_t(he[k].second / 3)].nb[he[k].second % 3] = NB_NONMANIFOLD; + } + // count == 1 keeps the NB_BOUNDARY it was initialised with. + i = j; + } + } + + // Feature mode: per-vertex surface normal, and the sampled displacement height at each vertex. + // Heights are filled in lazily - on a big model only a small painted region is ever looked at, and + // a sampler call is a texture fetch (plus trig) per layer, so sampling every vertex of the whole + // mesh up front was pure waste. Both arrays grow in lockstep with `verts`. + std::vector vnormal; + std::vector vheight; + std::vector vheight_valid; + if (feature_mode) { + vnormal.assign(verts.size(), Vec3f::Zero()); + for (const Tri &t : tris) { + const Vec3f fn = (verts[t.v[1]] - verts[t.v[0]]).cross(verts[t.v[2]] - verts[t.v[0]]); // area-weighted + for (int i = 0; i < 3; ++i) + vnormal[t.v[i]] += fn; + } + for (Vec3f &n : vnormal) { + const float l = n.norm(); + n = (l > 1e-12f) ? Vec3f(n / l) : Vec3f(Vec3f::UnitZ()); + } + vheight.assign(verts.size(), 0.f); + vheight_valid.assign(verts.size(), 0); + } + auto height_of = [&](int v) -> float { + if (!vheight_valid[v]) { + vheight[v] = sampler(verts[v], vnormal[v]); + vheight_valid[v] = 1; + } + return vheight[v]; + }; + + // Per-vertex filament index, sampled lazily and cached the same way the heights are. Needs the + // vertex normals, which feature mode also builds - so colour mode builds them when it is on alone. + std::vector vcolor; + std::vector vcolor_valid; + if (color_mode) { + if (vnormal.empty()) { + vnormal.assign(verts.size(), Vec3f::Zero()); + for (const Tri &t : tris) { + const Vec3f fn = (verts[t.v[1]] - verts[t.v[0]]).cross(verts[t.v[2]] - verts[t.v[0]]); + for (int i = 0; i < 3; ++i) + vnormal[t.v[i]] += fn; + } + for (Vec3f &n : vnormal) { + const float l = n.norm(); + n = (l > 1e-12f) ? Vec3f(n / l) : Vec3f(Vec3f::UnitZ()); + } + } + vcolor.assign(verts.size(), -2); // -2 = not sampled yet; -1 = sampled, no colour there + vcolor_valid.assign(verts.size(), 0); + } + auto color_of = [&](int v) -> int { + if (!vcolor_valid[v]) { + vcolor[v] = color(verts[v], vnormal[v]); + vcolor_valid[v] = 1; + } + return vcolor[v]; + }; + + // Sample the input mesh's own vertices up front, in parallel, for the region that is going to be + // refined. A sampler call is a texture fetch plus the projection's trigonometry per layer, and it + // is by far the most expensive thing here - but taken one at a time from inside the refinement + // loop it is also strictly serial. Every one of these vertices is read by the very first scoring + // pass anyway, so doing them together costs nothing extra and hands the work to every core. + // + // Only the region, and only the *initial* vertices: the laziness this replaces exists so that a + // small painted patch on a big model does not pay for the whole model (see height_of()), and that + // still holds. Midpoints created later stay lazy, because they do not exist yet. + if (feature_mode || color_mode) { + std::vector wanted(verts.size(), 0); + for (const Tri &t : tris) + if (refine_region[t.src] != 0) + for (int i = 0; i < 3; ++i) + wanted[size_t(t.v[i])] = 1; + // Each index is touched by exactly one iteration, so the lazy caches can be filled without + // synchronisation - and every value is the one height_of()/color_of() would have produced. + tbb::parallel_for(tbb::blocked_range(0, verts.size()), + [&](const tbb::blocked_range &range) { + for (size_t v = range.begin(); v < range.end(); ++v) { + if (!wanted[v]) + continue; + if (feature_mode) { + vheight[v] = sampler(verts[v], vnormal[v]); + vheight_valid[v] = 1; + } + if (color_mode) { + vcolor[v] = color(verts[v], vnormal[v]); + vcolor_valid[v] = 1; + } + } + }); + if (multi_mode) { + // The level a step crosses: midway through the relief actually present on the region. + float lo = std::numeric_limits::max(), hi = -lo; + for (size_t v = 0; v < verts.size(); ++v) + if (wanted[v]) { lo = std::min(lo, vheight[v]); hi = std::max(hi, vheight[v]); } + step_iso_mm = (lo < hi) ? 0.5f * (lo + hi) : 0.f; + step_dev_mm = (lo < hi) ? 0.4f * (hi - lo) : std::numeric_limits::max(); + } + } + + auto elen_sq = [&](int a, int b) -> float { return (verts[a] - verts[b]).squaredNorm(); }; + + // The one edge of a triangle taken as its "longest": greatest squared length, exact ties broken by + // the smaller (sorted) vertex-index key. Both triangles sharing an edge compute the same key for + // it, so they can never disagree about which of them is longest - the property the conformality + // argument and the LEPP walk's termination both rest on. + auto longest_local = [&](int ti) -> int { + const Tri &t = tris[ti]; + int best = 0; + float bl = elen_sq(t.v[0], t.v[1]); + uint64_t bk = edge_key(t.v[0], t.v[1]); + for (int e = 1; e < 3; ++e) { + const float l = elen_sq(t.v[e], t.v[(e + 1) % 3]); + const uint64_t k = edge_key(t.v[e], t.v[(e + 1) % 3]); + if (l > bl || (l == bl && k < bk)) { + bl = l; + bk = k; + best = e; + } + } + return best; + }; + + // How far the *displaced* surface departs from the flat triangle, sampled across the WHOLE + // triangle - the three edge midpoints and the centroid - not just one edge midpoint. Sampling the + // interior is what catches a hill that sits inside a triangle (the blind spot of an edge-only + // test). Cached per triangle: it can only change when the triangle is split, and then both + // children are fresh entries. + std::vector tri_err; + if (feature_mode) + tri_err.assign(tris.size(), -1.f); + // True when this triangle straddles a colour boundary: its corners, its edge midpoints and its + // centroid do not all take the same filament. The midpoints and centroid matter for the same + // reason they do in detail_error() - a boundary can cross a triangle without separating any two of + // its corners. Cached per triangle; a split invalidates both children. + std::vector tri_color_split; // 0 = unknown, 1 = straddles, 2 = uniform + if (color_mode) + tri_color_split.assign(tris.size(), 0); + auto straddles_color = [&](int ti) -> bool { + if (tri_color_split[ti] != 0) + return tri_color_split[ti] == 1; + const Tri &t = tris[ti]; + const Vec3f pa = verts[t.v[0]], pb = verts[t.v[1]], pc = verts[t.v[2]]; + const Vec3f na = vnormal[t.v[0]], nb = vnormal[t.v[1]], nc = vnormal[t.v[2]]; + const int ca = color_of(t.v[0]); + bool split = color_of(t.v[1]) != ca || color_of(t.v[2]) != ca; + if (!split) { + static const float BARY[4][3] = { { 0.5f, 0.5f, 0.f }, { 0.f, 0.5f, 0.5f }, + { 0.5f, 0.f, 0.5f }, { 1.f / 3, 1.f / 3, 1.f / 3 } }; + for (const auto &w : BARY) { + Vec3f n = w[0] * na + w[1] * nb + w[2] * nc; + const float nl = n.norm(); + n = (nl > 1e-12f) ? Vec3f(n / nl) : na; + if (color(w[0] * pa + w[1] * pb + w[2] * pc, n) != ca) { + split = true; + break; + } + } + } + tri_color_split[ti] = split ? 1 : 2; + return split; + }; + + // The spacing at which the chord test samples a triangle. Features narrower than the resolution + // floor cannot be resolved by refinement anyway, so sampling any finer than that only costs time; + // sampling any coarser is what let thin features fall between the samples. Below the floor's own + // scale it is held at 0.05 mm, since finer is invisible on an FDM part. + const float sample_spacing = std::max(min_edge_length_mm, 0.05f); + + auto detail_error = [&](int ti) -> float { + if (tri_err[ti] >= 0.f) + return tri_err[ti]; + const Tri &t = tris[ti]; + const Vec3f pa = verts[t.v[0]], pb = verts[t.v[1]], pc = verts[t.v[2]]; + const Vec3f na = vnormal[t.v[0]], nb = vnormal[t.v[1]], nc = vnormal[t.v[2]]; + const float ha = height_of(t.v[0]), hb = height_of(t.v[1]), hc = height_of(t.v[2]); + + // A barycentric lattice over the whole triangle, dense enough that no feature wider than the + // sample spacing can hide between two samples. Four fixed samples (the three edge midpoints + // and the centroid) were the previous test, and on a 1 mm starting triangle they left 0.5 mm + // gaps - wider than a grid line or a knurl ridge - so whole features were never seen, the + // triangle scored zero, and it was never refined. The lattice is bounded at 8 subdivisions + // (45 points) so a large triangle does not cost thousands of samples; anything it misses at + // that size is caught once its children are small enough for the lattice to reach it. + const float longest = std::sqrt(std::max({ (pb - pa).squaredNorm(), (pc - pb).squaredNorm(), (pa - pc).squaredNorm() })); + const int n = std::clamp(int(std::ceil(longest / sample_spacing)), 2, 8); + float maxerr = 0.f; + // Whether the mid-level contour crosses an edge with a jump that is a step's worth, walked at + // the sample spacing (the lattice below is too coarse on a long edge: a 1 mm edge gets 8 + // samples, and a 0.15 mm grid line slips between them). Such a triangle is the cutter's. + bool sharp_cross = false; + if (multi_mode) { + const Vec3f *P[3] = { &pa, &pb, &pc }; + const Vec3f *Nn[3] = { &na, &nb, &nc }; + const float H[3] = { ha, hb, hc }; + for (int e = 0; e < 3; ++e) { + const Vec3f &p0 = *P[e], &p1 = *P[(e + 1) % 3], &n0 = *Nn[e], &n1 = *Nn[(e + 1) % 3]; + const int m = std::clamp(int(std::ceil((p1 - p0).norm() / sample_spacing)), 2, 32); + float last = H[e]; + for (int i = 1; i <= m; ++i) { + float h; + if (i == m) h = H[(e + 1) % 3]; + else { + const float t = float(i) / float(m); + Vec3f nn = n0 + (n1 - n0) * t; + const float nl = nn.norm(); + nn = (nl > 1e-12f) ? Vec3f(nn / nl) : n0; + h = sampler(p0 + (p1 - p0) * t, nn); + } + if ((h > step_iso_mm) != (last > step_iso_mm) && std::abs(h - last) > step_dev_mm) { + sharp_cross = true; + break; + } + last = h; + } + if (sharp_cross) + break; + } + } + for (int i = 0; i <= n; ++i) + for (int j = 0; j <= n - i; ++j) { + const int k = n - i - j; + const float wa = float(i) / float(n), wb = float(j) / float(n), wc = float(k) / float(n); + float actual; + if (i == n) actual = ha; + else if (j == n) actual = hb; + else if (k == n) actual = hc; + else { + Vec3f nn = wa * na + wb * nb + wc * nc; + const float nl = nn.norm(); + nn = (nl > 1e-12f) ? Vec3f(nn / nl) : na; + actual = sampler(wa * pa + wb * pb + wc * pc, nn); + // Corners lie on the plane by construction; only the rest carry chord error. + maxerr = std::max(maxerr, std::abs(actual - (wa * ha + wb * hb + wc * hc))); + } + } + // A sharp step crossing the triangle is the cutter's job. Refinement cannot bring such a + // triangle under tolerance - a discontinuity has no chord - and would only carpet the step + // down to the floor, so its chord error is not counted. A feature lying entirely inside the + // triangle crosses no edge and still counts, which is what makes it surface until it does + // cross one. + if (multi_mode && sharp_cross) + maxerr = 0.f; + tri_err[ti] = maxerr; + return maxerr; + }; + + // How many times over its criteria a triangle is: <= 1 means "good enough, leave it alone", and + // the larger the value the more a split buys. Driving the heap with this is what makes a run that + // runs out of budget spend it on the worst offenders instead of wherever a sweep happened to + // reach. Triangles outside the region always score 0 - they are only ever touched by the conformal + // closure below, never refined on their own account. + auto priority = [&](int ti) -> float { + const Tri &t = tris[ti]; + const uint8_t flags = refine_region[t.src]; + if (flags == 0) + return 0.f; + const int le = longest_local(ti); + const float ll = elen_sq(t.v[le], t.v[(le + 1) % 3]); + if (ll <= min_floor_sq) + return 0.f; // at the resolution floor - also what stops a sharp texture step going forever + float p = 0.f; + if (flags & REFINE_PAINTED) { + p = (target_sq > 0.f) ? ll / target_sq : 0.f; + if (feature_mode) { + p = std::max(p, detail_error(ti) / chord_tolerance_mm); + } + // Colour is per facet, so a colour boundary can only be drawn where there are edges along + // it. Length target, floored by min_edge_length_mm above, exactly like the border band. + if (color_mode && straddles_color(ti)) + p = std::max(p, ll / color_sq); + } + // The band straddling the paint's edge, refined by plain edge length. Deliberately *not* run + // through detail_error(): the sampler reports no relief off the paint, so across its edge the + // chord test sees a step and would chase it down to the length floor. Length alone is what this + // band needs - the error it is fixing is the size of the triangles spanning the displacement + // step, not the curvature of anything. + if ((flags & REFINE_BORDER) && border_sq > 0.f) + p = std::max(p, ll / border_sq); + return p; + }; + + // What ordering the heap by. priority() alone saturates: a triangle straddling a hard step in the + // texture scores relief / tolerance however small it gets, so its children always come back to the + // top and the whole budget is spent carpeting step edges down to the floor while a large triangle + // with a moderate error a few millimetres away is never reached. Weighting by area makes the key + // the surface error a split actually removes, which is what a fixed budget should be spent on - + // and once the budget is gone, what remains is spread evenly instead of piled on one feature. + auto tri_area = [&](int ti) -> float { + const Tri &t = tris[ti]; + return 0.5f * (verts[t.v[1]] - verts[t.v[0]]).cross(verts[t.v[2]] - verts[t.v[0]]).norm(); + }; + auto heap_key = [&](int ti, float p) -> float { return p * tri_area(ti); }; + + auto set_nb = [&](int ti, int u, int v, int val) { + if (ti < 0) + return; + Tri &t = tris[ti]; + for (int e = 0; e < 3; ++e) + if ((t.v[e] == u && t.v[(e + 1) % 3] == v) || (t.v[e] == v && t.v[(e + 1) % 3] == u)) { + t.nb[e] = val; + return; + } + }; + + // Bisects triangle `ti` across its local edge `e`, which the caller has established is terminal. + // Both triangles on that edge are split in the one operation, around a single shared midpoint - + // which is exactly why a hanging node (and so a crack) can never appear. `ti` and the opposite + // triangle are each reused as one of their own children, so only two back-pointers in the + // surrounding mesh need repointing. Triangles whose geometry changed are left in `touched`. + std::vector touched; + auto bisect = [&](int ti, int e) -> bool { + const int a = tris[ti].v[e], b = tris[ti].v[(e + 1) % 3], c = tris[ti].v[(e + 2) % 3]; + const int n = tris[ti].nb[e]; + // Locate the shared edge from the far side before touching anything: bailing out half way + // through would be the one way this could leave a crack. + int f = -1; + if (n >= 0) { + for (int k = 0; k < 3; ++k) { + const int u = tris[n].v[k], w = tris[n].v[(k + 1) % 3]; + if ((u == a && w == b) || (u == b && w == a)) { + f = k; + break; + } + } + if (f < 0) { + tris[ti].nb[e] = NB_NONMANIFOLD; // inconsistent adjacency: refuse to split across it + return false; + } + } + + const int m = int(verts.size()); + verts.push_back(0.5f * (verts[a] + verts[b])); + if (feature_mode || color_mode) { + const Vec3f mn = vnormal[a] + vnormal[b]; + const float ml = mn.norm(); + vnormal.push_back(ml > 1e-12f ? Vec3f(mn / ml) : vnormal[a]); + } + if (feature_mode) { + vheight.push_back(0.f); + vheight_valid.push_back(0); + } + if (color_mode) { + vcolor.push_back(-2); + vcolor_valid.push_back(0); + } + + // Near side: ti becomes (a, m, c), the new triangle is (m, b, c). Both keep the original + // a->b->c winding. + const int nb_bc = tris[ti].nb[(e + 1) % 3]; + const int nb_ca = tris[ti].nb[(e + 2) % 3]; + const int src = tris[ti].src; + const int t2 = int(tris.size()); + tris.push_back(Tri{ { m, b, c }, { NB_BOUNDARY, nb_bc, ti }, src }); + { + Tri &t1 = tris[ti]; + t1.v[0] = a; t1.v[1] = m; t1.v[2] = c; + t1.nb[0] = NB_BOUNDARY; t1.nb[1] = t2; t1.nb[2] = nb_ca; + } + set_nb(nb_bc, b, c, t2); // that outer neighbour borders the second child now, not ti + if (feature_mode) { + tri_err.push_back(-1.f); + tri_err[ti] = -1.f; + } + if (color_mode) { + tri_color_split.push_back(0); + tri_color_split[ti] = 0; + } + touched.assign({ ti, t2 }); + + if (n < 0) { + return true; // boundary edge: nothing on the far side to split + } + + // Far side, same shape: n becomes (p, m, d), the new triangle is (m, q, d). + const int p = tris[n].v[f], q = tris[n].v[(f + 1) % 3], d = tris[n].v[(f + 2) % 3]; + const int nb_qd = tris[n].nb[(f + 1) % 3]; + const int nb_dp = tris[n].nb[(f + 2) % 3]; + const int nsrc = tris[n].src; + const int n2 = int(tris.size()); + tris.push_back(Tri{ { m, q, d }, { NB_BOUNDARY, nb_qd, n }, nsrc }); + { + Tri &n1 = tris[n]; + n1.v[0] = p; n1.v[1] = m; n1.v[2] = d; + n1.nb[0] = NB_BOUNDARY; n1.nb[1] = n2; n1.nb[2] = nb_dp; + } + set_nb(nb_qd, q, d, n2); + if (feature_mode) { + tri_err.push_back(-1.f); + tri_err[n] = -1.f; + } + if (color_mode) { + tri_color_split.push_back(0); + tri_color_split[n] = 0; + } + + // Stitch the two sides back together: whichever far child holds `a` borders the near child + // that holds `a`. (Which one that is depends on how n happens to be wound.) + const int side_a = (p == a) ? n : n2; + const int side_b = (p == a) ? n2 : n; + tris[ti].nb[0] = side_a; // near child (a, m, c), edge (a, m) + tris[t2].nb[0] = side_b; // near child (m, b, c), edge (m, b) + set_nb(side_a, a, m, ti); + set_nb(side_b, b, m, t2); + touched.assign({ ti, t2, n, n2 }); + return true; + }; + + // Worst-first. Entries go stale as their triangle is split; a stale entry is harmless - it is + // re-scored on pop and dropped or re-pushed. The ordering is a budget-allocation heuristic only: + // neither correctness nor conformality depends on it. + std::priority_queue> queue; + { + // Scoring the starting mesh means a detail_error() per triangle - four more sampler calls each + // - so it is worth spreading, even though the refinement that follows cannot be. Each entry is + // written by one iteration only, and the caches those calls fill (tri_err, tri_color_split) are + // likewise per triangle, so there is nothing shared to guard. The heap is then built from the + // finished array in index order, which is exactly the order the serial loop pushed in. + std::vector initial(tris.size(), 0.f); + tbb::parallel_for(tbb::blocked_range(0, tris.size()), + [&](const tbb::blocked_range &range) { + for (size_t ti = range.begin(); ti < range.end(); ++ti) + initial[ti] = priority(int(ti)); + }); + for (int ti = 0; ti < int(tris.size()); ++ti) + if (initial[size_t(ti)] > 1.f) + queue.emplace(heap_key(ti, initial[size_t(ti)]), ti); + } + + // Every iteration either drops one satisfied triangle from the queue or performs exactly one + // bisection, and bisections are capped by the triangle budget, so this always terminates. + // Progress is reported against the triangle budget, which is what the loop is bounded by. Polled + // rather than pushed on every bisection: a refinement spends its budget in hundreds of thousands + // of them, and every hook call wakes the UI's idle loop to repaint the notification. + const int start_tris = int(tris.size()); + const int budget_tris = std::max(1, max_triangles - start_tris); + int next_poll = start_tris; + while (!queue.empty() && int(tris.size()) + 2 <= max_triangles) { + if (progress && int(tris.size()) >= next_poll) { + next_poll = int(tris.size()) + std::max(1024, budget_tris / 100); + if (!progress(std::clamp((int(tris.size()) - start_tris) * 100 / budget_tris, 0, 100))) + break; // still conformal - whole bisections only; the caller decides whether to keep it + } + const int ti = queue.top().second; + queue.pop(); + if (priority(ti) <= 1.f) + continue; // stale: already refined past its criteria + + // Longest-Edge Propagation Path: step to the neighbour across the current longest edge for as + // long as that neighbour has a strictly longer one, then bisect the terminal edge we land on. + // Length strictly increases along the path, so it cannot cycle. + int cur = ti, split_edge = -1; + for (size_t guard = 0; guard <= tris.size(); ++guard) { + const int le = longest_local(cur); + const int nbr = tris[cur].nb[le]; + if (nbr == NB_NONMANIFOLD) + break; // cannot split across it without tearing the mesh: give up on this path + if (nbr == NB_BOUNDARY) { + split_edge = le; // boundary longest edge -> terminal + break; + } + const int nle = longest_local(nbr); + if (edge_key(tris[nbr].v[nle], tris[nbr].v[(nle + 1) % 3]) == + edge_key(tris[cur].v[le], tris[cur].v[(le + 1) % 3])) { + split_edge = le; // mutual longest edge -> terminal + break; + } + cur = nbr; + } + if (split_edge < 0 || !bisect(cur, split_edge)) + continue; // ti sits in a non-manifold neighbourhood and cannot be refined safely + + for (const int t : touched) + if (const float p = priority(t); p > 1.f) + queue.emplace(heap_key(t, p), t); + // The bisection may have been a step on the way to ti rather than ti itself, in which case ti + // is not in `touched` and has to go back on the heap to be walked again. + if (cur != ti) + if (const float p = priority(ti); p > 1.f) + queue.emplace(heap_key(ti, p), ti); + } + + return emit(); +} + +namespace { + +// Ear clipping of a simple polygon given counter-clockwise in 2D; `pts` are indexed by `poly`. Small +// polygons only (a triangle clipped by a few contour polylines), so the plain O(n^2) form is enough. +// A vertex that lies on a candidate ear's boundary does not block it, and when no ear can be found +// (numerically degenerate input) the flattest vertex is dropped rather than fanning blindly, which +// on a concave region would put triangles outside it; the zero-area triangle keeps the edges paired. +void ear_clip(const std::vector &pts, std::vector poly, const std::function &emit) +{ + auto cross2 = [](const Vec2f &o, const Vec2f &a, const Vec2f &b) { + return (a.x() - o.x()) * (b.y() - o.y()) - (a.y() - o.y()) * (b.x() - o.x()); + }; + // A corner flatter than this is collinear: several vertices along one edge of the triangle. Such + // a corner is never an ear - the zero-area triangle would lie on the edge, where the neighbour, + // seeing the same points from its side, may emit the same one. + float flat = 0.f; + { + Vec2f lo = pts[size_t(poly[0])], hi = lo; + for (int id : poly) { lo = lo.cwiseMin(pts[size_t(id)]); hi = hi.cwiseMax(pts[size_t(id)]); } + flat = 1e-5f * (hi - lo).squaredNorm(); + } + while (poly.size() > 3) { + const size_t n = poly.size(); + bool found = false; + for (size_t i = 0; i < n && !found; ++i) { + const int ia = poly[(i + n - 1) % n], ib = poly[i], ic = poly[(i + 1) % n]; + const Vec2f &a = pts[size_t(ia)], &b = pts[size_t(ib)], &c = pts[size_t(ic)]; + const float area2 = cross2(a, b, c); + if (area2 <= flat) + continue; // reflex or flat corner + const float eps = 1e-6f * area2; + bool clean = true; + size_t on_base = 0; + for (size_t j = 0; j < n && clean; ++j) { + const int ij = poly[j]; + if (ij == ia || ij == ib || ij == ic) + continue; + const Vec2f &p = pts[size_t(ij)]; + clean = !(cross2(a, b, p) > eps && cross2(b, c, p) > eps && cross2(c, a, p) > eps); + // On the ear's base, between its ends: a run of vertices along the base, as when + // several sit on one edge of the triangle. + if (std::abs(cross2(c, a, p)) <= flat && (p - c).dot(a - c) > 0.f && (p - a).dot(c - a) > 0.f) + ++on_base; + } + if (!clean) + continue; + if (on_base > 0) { + // The base carries other vertices. When those are all that is left of the polygon, + // in order from c round to a, fan them from b and finish; otherwise the ear is not + // clear of the rest of the polygon. + if (on_base + 3 != n) + continue; + for (size_t j = 0; j + 1 < n - 1; ++j) { + const int u = poly[(i + 1 + j) % n], v = poly[(i + 2 + j) % n]; + emit(ib, u, v); + } + poly.clear(); + return; + } + emit(ia, ib, ic); + poly.erase(poly.begin() + long(i)); + found = true; + } + if (!found) { + // Clip the smallest convex corner anyway, or failing that the flattest: a thin triangle + // keeps every edge accounted for, and a convex one at least stays on the polygon's side. + size_t pick = 0; + float best = std::numeric_limits::max(); + bool convex_found = false; + for (size_t i = 0; i < n; ++i) { + const Vec2f &a = pts[size_t(poly[(i + n - 1) % n])], &b = pts[size_t(poly[i])], &c = pts[size_t(poly[(i + 1) % n])]; + const float m = cross2(a, b, c); + if (m > flat && (!convex_found || m < best)) { best = m; pick = i; convex_found = true; } + else if (!convex_found && std::abs(m) < best) { best = std::abs(m); pick = i; } + } + emit(poly[(pick + n - 1) % n], poly[pick], poly[(pick + 1) % n]); + poly.erase(poly.begin() + long(pick)); + } + } + if (poly.size() == 3) + emit(poly[0], poly[1], poly[2]); +} + +// Douglas-Peucker on an open polyline; endpoints always survive. +void simplify_polyline(const std::vector &in, float tol, std::vector &out) +{ + out.clear(); + if (in.size() < 3) { out = in; return; } + std::vector keep(in.size(), 0); + keep.front() = keep.back() = 1; + std::vector> stack = { { 0, in.size() - 1 } }; + while (!stack.empty()) { + const auto [i0, i1] = stack.back(); + stack.pop_back(); + if (i1 <= i0 + 1) + continue; + const Vec2f d = in[i1] - in[i0]; + const float len = d.norm(); + float best = -1.f; + size_t bi = i0; + for (size_t i = i0 + 1; i < i1; ++i) { + const Vec2f r = in[i] - in[i0]; + const float dist = (len > 1e-12f) ? std::abs(d.x() * r.y() - d.y() * r.x()) / len : r.norm(); + if (dist > best) { best = dist; bi = i; } + } + if (best > tol) { + keep[bi] = 1; + stack.push_back({ i0, bi }); + stack.push_back({ bi, i1 }); + } + } + for (size_t i = 0; i < in.size(); ++i) + if (keep[i]) out.push_back(in[i]); +} + +} // namespace + +namespace { + +// The cutter's view of one crossing of the mid-level contour with a mesh edge. +struct Crossing +{ + Vec3f p, n; + float t; // parameter from the edge's lower vertex id toward the higher + int a = -1, b = -1; // the edge, lower vertex id first + float sin_min = 1.f; // sine of the smallest angle a contour makes with the edge + float dt_max = std::numeric_limits::max(); // room along the edge before a copy could + // pass the copies of the contour's next vertex + bool used = false; // some cut triangle's contour ends here + bool no_seam = false; // a contour joins it straight to its neighbour on the edge: nothing between + bool sharp = false; + float thick = 0.f; // narrower side of the feature at the crossing, along the gradient + int single = -1, lo = -1, hi = -1; + int near_a = -1, near_b = -1; // the copy on a's side and on b's, when doubled +}; +struct Edge +{ + std::vector xs; // sorted by t +}; + +inline uint64_t step_edge_key(int a, int b) +{ + if (a > b) std::swap(a, b); + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); +} + +// What cut_mesh_at_steps() learns about the mesh before it cuts anything: the vertex heights (and the +// nudged vertex positions), the crossings on every painted edge, and the verdict `ok` - whether this +// is a step texture worth cutting at all. The verdict is what the prepare path probes on the coarse +// mesh before it chooses how to refine, so refinement and cut agree on which textures are stepped. +struct StepScan +{ + bool ok = false; + std::vector pos, vnormal; + std::vector vh; + float iso = 0.f, range = 0.f; + std::unordered_map edges; + + std::pair sample_between(int a, int b, float t) const + { + const Vec3f p = pos[size_t(a)] + (pos[size_t(b)] - pos[size_t(a)]) * t; + Vec3f n = vnormal[size_t(a)] + (vnormal[size_t(b)] - vnormal[size_t(a)]) * t; + const float l = n.norm(); + n = (l > 1e-12f) ? Vec3f(n / l) : vnormal[size_t(a)]; + return std::make_pair(p, n); + } + bool side_of(float h) const { return h > iso; } +}; + +StepScan scan_steps(const indexed_triangle_set &mesh, const std::vector ®ion, + const HeightFieldSampler &sampler, float step_width_mm, float seam_gap_mm, + float min_feature_mm, bool nudge) +{ + StepScan scan; + const size_t nv = mesh.vertices.size(), nt = mesh.indices.size(); + if (!sampler || region.size() != nt || step_width_mm <= 0.f) + return scan; + + // 1. Heights at the vertices of the cuttable triangles, along the same normals the bake will use. + // Vertex positions are worked on in `pos`: a vertex that happens to sit within a texel of a step + // is nudged off it below, and everything from the edge march to the output uses the nudged place. + std::vector &pos = scan.pos; + std::vector &vnormal = scan.vnormal; + pos = mesh.vertices; + vnormal = texture_displacement_vertex_normals(mesh); + std::vector wanted(nv, 0); + for (size_t t = 0; t < nt; ++t) + if (region[t] != 0) + for (int k = 0; k < 3; ++k) + wanted[size_t(mesh.indices[t][k])] = 1; + std::vector &vh = scan.vh; + vh.assign(nv, 0.f); + tbb::parallel_for(tbb::blocked_range(0, nv), [&](const tbb::blocked_range &r) { + for (size_t v = r.begin(); v < r.end(); ++v) + if (wanted[v]) + vh[v] = sampler(pos[v], vnormal[v]); + }); + float hmin = std::numeric_limits::max(), hmax = -hmin; + for (size_t v = 0; v < nv; ++v) + if (wanted[v]) { hmin = std::min(hmin, vh[v]); hmax = std::max(hmax, vh[v]); } + const float range = scan.range = hmax - hmin; + if (!(range > 1e-6f)) + return scan; + const float iso = scan.iso = 0.5f * (hmin + hmax); + // Only a texture that is mostly steps is cut: one whose heights sit at two levels with little in + // between (a grid, a knurl, a logo). On a smooth or noisy relief the mid-level contour runs through + // every triangle without being a step anywhere, and cutting along it would only multiply the + // triangles; the chord-based refinement is the right tool there. Judged from the vertex heights, + // which sample the whole painted surface. + { + size_t near_level = 0, total = 0; + for (size_t v = 0; v < nv; ++v) + if (wanted[v]) { ++total; near_level += std::abs(vh[v] - iso) > 0.35f * range; } + if (total == 0 || double(near_level) < 0.6 * double(total)) + return scan; + } + + // 1b. A vertex inside the blend of a sharp step - the texture's bilinear ramp is a texel wide - would + // be displaced to a height between the two sides, and every triangle at it would ramp. Such a vertex + // is nudged along the surface away from the step, down its own side's slope, until it samples a + // pure value; a step's width or so. Only where the surface is flat around it: a vertex on a crease + // of the model (a box edge) stays where it is. Skipped by a probe, which only wants the verdict. + if (nudge) { + std::vector creased(nv, 0); + std::vector first_normal(nv, Vec3f::Zero()); + std::vector shortest(nv, std::numeric_limits::max()); // shortest edge at the vertex + for (size_t t = 0; t < nt; ++t) { + const auto &tri = mesh.indices[t]; + const Vec3f &a = pos[size_t(tri[0])]; + Vec3f fn = (pos[size_t(tri[1])] - a).cross(pos[size_t(tri[2])] - a); + const float fl = fn.norm(); + if (fl < 1e-12f) continue; + fn /= fl; + for (int k = 0; k < 3; ++k) { + Vec3f &f0 = first_normal[size_t(tri[k])]; + if (f0.isZero()) f0 = fn; + else if (f0.dot(fn) < 0.985f) creased[size_t(tri[k])] = 1; // ~10 degrees + const float el = (pos[size_t(tri[(k + 1) % 3])] - pos[size_t(tri[k])]).norm(); + shortest[size_t(tri[k])] = std::min(shortest[size_t(tri[k])], el); + shortest[size_t(tri[(k + 1) % 3])] = std::min(shortest[size_t(tri[(k + 1) % 3])], el); + } + } + tbb::parallel_for(tbb::blocked_range(0, nv), [&](const tbb::blocked_range &r) { + for (size_t v = r.begin(); v < r.end(); ++v) { + if (!wanted[v] || creased[v] || std::abs(vh[v] - iso) > 0.47f * range) + continue; + const Vec3f &n = vnormal[v]; + const Vec3f ax = (std::abs(n.x()) < 0.9f) ? Vec3f::UnitX() : Vec3f::UnitY(); + const Vec3f t1 = n.cross(ax).normalized(), t2 = n.cross(t1).normalized(); + const float d = step_width_mm; + const float gx = sampler(pos[v] + t1 * d, n) - sampler(pos[v] - t1 * d, n); + const float gy = sampler(pos[v] + t2 * d, n) - sampler(pos[v] - t2 * d, n); + Vec3f g = t1 * gx + t2 * gy; + const float gl = g.norm(); + if (gl < 0.25f * range) + continue; // not at a step: a slope, which the chord test handles + g /= gl; + // Down the slope for a low vertex, up it for a high one, in steps of half a texel, and + // never by more than a fraction of the shortest edge at the vertex: on a finely refined + // mesh a texel-sized move would fold the triangles around it. + const Vec3f dir = (vh[v] > iso) ? g : Vec3f(-g); + Vec3f best = pos[v]; + float bh = vh[v]; + const float limit = std::min(2.f * step_width_mm, 0.3f * shortest[v]); + for (int i = 1; i <= 8; ++i) { + const float dist = 0.25f * step_width_mm * float(i); + if (dist > limit) + break; + const Vec3f q = pos[v] + dir * dist; + const float h = sampler(q, n); + if ((h > iso) != (vh[v] > iso)) + break; // crossed the step: the nudge would change the vertex's side + best = q; bh = h; + if (std::abs(h - iso) > 0.48f * range) + break; + } + if (std::abs(bh - iso) > std::abs(vh[v] - iso)) { pos[v] = best; vh[v] = bh; } + } + }); + } + + const auto sample_between = [&scan](int a, int b, float t) { return scan.sample_between(a, b, t); }; + const auto side_of = [&scan](float h) { return scan.side_of(h); }; + + // 2. Crossings on the edges, found on the field itself - on a 1 mm edge over a texture with 30 um + // texels, interpolating the endpoint heights could put a step anywhere along the edge. Both + // triangles on an edge see the same crossings, which is what keeps the cut conformal. + auto &edges = scan.edges; + edges.reserve(nt); + + const auto find_crossings = [&](int a, int b, Edge &edge) { + if (a > b) std::swap(a, b); + const float len = (pos[size_t(b)] - pos[size_t(a)]).norm(); + const int steps = std::clamp(int(std::ceil(len / (0.5f * step_width_mm))), 4, 128); + float t0 = 0.f, h0 = vh[size_t(a)] - iso; + for (int i = 1; i <= steps; ++i) { + const float ti = float(i) / float(steps); + const auto [pp, nn] = sample_between(a, b, ti); + const float hi_ = sampler(pp, nn) - iso; + if (h0 * hi_ < 0.f || (hi_ == 0.f && h0 != 0.f)) { + float lo_t = t0, hi_t = ti, lo_h = h0; + for (int k = 0; k < 10; ++k) { + const float tm = 0.5f * (lo_t + hi_t); + const auto [pm, nm] = sample_between(a, b, tm); + if (lo_h * (sampler(pm, nm) - iso) <= 0.f) hi_t = tm; else { lo_t = tm; } + } + Crossing c; + c.a = a; c.b = b; + // Never exactly on a vertex: that would make a zero-area triangle of the split. + c.t = std::clamp(0.5f * (lo_t + hi_t), 1e-3f, 1.f - 1e-3f); + std::tie(c.p, c.n) = sample_between(a, b, c.t); + // Sharp means the field changes by at least half its range across `step_width_mm` in + // the steepest tangent direction - a step, not a slope that merely passes mid-level. + const Vec3f ax = (std::abs(c.n.x()) < 0.9f) ? Vec3f::UnitX() : Vec3f::UnitY(); + const Vec3f t1v = c.n.cross(ax).normalized(), t2v = c.n.cross(t1v).normalized(); + const float d = 0.5f * step_width_mm; + const float gx = sampler(c.p + t1v * d, c.n) - sampler(c.p - t1v * d, c.n); + const float gy = sampler(c.p + t2v * d, c.n) - sampler(c.p - t2v * d, c.n); + const float gl = std::sqrt(gx * gx + gy * gy); + c.sharp = gl >= 0.5f * range; + // How wide the feature is on either side of the step, along the gradient: the + // distance until the field returns to mid-level, in steps of half the step width, up + // to `thick_max`. A texture whose features are only a few texels wide has no pure + // interior for a seam copy to land in and is left to refinement (see the gate below). + { + const float thick_max = 4.f * step_width_mm; + c.thick = thick_max; + if (gl > 1e-12f) { + const Vec3f g = (t1v * gx + t2v * gy) / gl; + for (int sgn = -1; sgn <= 1; sgn += 2) { + const bool high = sgn > 0; // uphill along the gradient + for (int i = 1; i <= 8; ++i) { + const float dist = 0.5f * step_width_mm * float(i); + if (dist >= c.thick) + break; + if (side_of(sampler(c.p + g * (float(sgn) * dist), c.n)) != high) { + c.thick = std::min(c.thick, dist); + break; + } + } + } + } + } + edge.xs.push_back(c); + } + t0 = ti; h0 = hi_; + } + // A pair of crossings closer than the smallest feature the mesh is meant to carry is a feature + // too thin to print, and one closer than the seam gap has no room for two seams: dropping both + // leaves the surface flat there, at the side around it. + const float thinnest = std::max(min_feature_mm, seam_gap_mm); + for (size_t i = 0; i + 1 < edge.xs.size();) { + if ((edge.xs[i + 1].t - edge.xs[i].t) * len < thinnest) + edge.xs.erase(edge.xs.begin() + long(i), edge.xs.begin() + long(i) + 2); + else + ++i; + } + // Parity: the endpoints' sides say whether the count must be odd or even; the march starts and + // ends on the vertex heights themselves, so a mismatch is a numerical accident. Drop the lot + // then - a triangle split on a wrong count is worse than a ramp there. + const bool odd_expected = side_of(vh[size_t(a)]) != side_of(vh[size_t(b)]); + if ((edge.xs.size() % 2 == 1) != odd_expected) + edge.xs.clear(); + }; + + // Edges to examine, in a fixed order so the crossings can be found in parallel. + std::vector edge_keys; + for (size_t t = 0; t < nt; ++t) { + if (region[t] == 0) + continue; + const auto &tri = mesh.indices[t]; + for (int e = 0; e < 3; ++e) + edge_keys.push_back(step_edge_key(tri[e], tri[(e + 1) % 3])); + } + std::sort(edge_keys.begin(), edge_keys.end()); + edge_keys.erase(std::unique(edge_keys.begin(), edge_keys.end()), edge_keys.end()); + std::vector found(edge_keys.size()); + tbb::parallel_for(tbb::blocked_range(0, edge_keys.size()), [&](const tbb::blocked_range &r) { + for (size_t i = r.begin(); i < r.end(); ++i) + find_crossings(int(edge_keys[i] >> 32), int(uint32_t(edge_keys[i])), found[i]); + }); + size_t crossings = 0, sharp = 0; + double thick_sum = 0.; + for (size_t i = 0; i < edge_keys.size(); ++i) { + for (const Crossing &c : found[i].xs) { ++crossings; sharp += c.sharp; thick_sum += c.thick; } + edges.emplace(edge_keys[i], std::move(found[i])); + } + // The mid-level contour has to be a step nearly everywhere it is crossed, or this is not a step + // texture: a noisy relief that happens to sit at two levels is crossed all over, mostly gently. + if (crossings == 0 || double(sharp) < 0.8 * double(crossings)) + return scan; + // And the features have to be wider than the step itself. A texture whose blobs are only a few + // texels across (noise, a fine grain) is bimodal and sharp at every crossing, yet has no pure + // interior for the seam copies to land in, and its contour runs through every triangle: cutting it + // doubles the triangle count for walls the same size as the interpolation blur. Judged from the + // mean feature thickness at the crossings, measured in step widths (2.25 = four to five texels). + if (thick_sum < 2.25 * double(step_width_mm) * double(crossings)) + return scan; + + scan.ok = true; + return scan; + +} + +} // namespace + +bool texture_has_steps_to_cut(const indexed_triangle_set &mesh, const std::vector ®ion, + const HeightFieldSampler &sampler, float step_width_mm, float seam_gap_mm, + float min_feature_mm) +{ + return scan_steps(mesh, region, sampler, step_width_mm, seam_gap_mm, min_feature_mm, /*nudge*/ false).ok; +} + +indexed_triangle_set cut_mesh_at_steps(const indexed_triangle_set &mesh, const std::vector ®ion, + const HeightFieldSampler &sampler, float step_width_mm, + float seam_gap_mm, float min_feature_mm, std::vector *out_source, + size_t *out_cut_count) +{ + const size_t nv = mesh.vertices.size(), nt = mesh.indices.size(); + if (out_cut_count) + *out_cut_count = 0; + const auto passthrough = [&]() { + if (out_source) { + out_source->resize(nt); + std::iota(out_source->begin(), out_source->end(), 0); + } + return mesh; + }; + if (!sampler || region.size() != nt || step_width_mm <= 0.f) + return passthrough(); + + StepScan scan = scan_steps(mesh, region, sampler, step_width_mm, seam_gap_mm, min_feature_mm, /*nudge*/ true); + if (!scan.ok) + return passthrough(); + std::vector &pos = scan.pos; + const std::vector &vnormal = scan.vnormal; + std::vector &vh = scan.vh; + const float iso = scan.iso, range = scan.range; + auto &edges = scan.edges; + const auto sample_between = [&scan](int a, int b, float t) { return scan.sample_between(a, b, t); }; + const auto side_of = [&scan](float h) { return scan.side_of(h); }; + const auto edge_key = [](int a, int b) { return step_edge_key(a, b); }; + (void) vnormal; (void) range; (void) iso; + + // 3. Per triangle: the perimeter as a loop of corners and crossings, and the contour inside the + // triangle traced from a local raster of the field (marching squares at half the step width), as + // polylines from one crossing to another. The trace is what makes a corner of the pattern come out + // as a corner instead of a chord clipping it, and what pairs the crossings up - no guessing. A + // polyline is kept only when its two ends land on distinct crossings the edge march found; + // otherwise the triangle is split at its crossings without a seam (the neighbours' cuts still meet + // no T-junction) and the surface ramps there. Unpainted neighbours of a crossed edge are split the + // same way. + struct Chain + { + int i = -1, j = -1; // crossing indices in the loop, from i to j + std::vector pts; // interior vertices, from i toward j + std::vector lo, hi; // output copies of the interior vertices (same when single) + float clearance = std::numeric_limits::max(); // distance to the nearest other contour + }; + struct Loop + { + std::vector ids; // perimeter entries: corner vertex ids (>= 0) or -(1 + crossing index) + std::vector xs; // crossings in perimeter order + std::vector xpos; // their positions in ids + std::vector chains; + std::vector partner; // per crossing: the crossing its chain leads to + std::vector chain_of; + std::vector no_seam; // crossings joined to their neighbour on the edge with nothing between + Vec3f N = Vec3f::Zero(); + bool ok = false; + }; + const auto walk_edge = [&](int a, int b, std::vector &out) { + auto it = edges.find(edge_key(a, b)); + if (it == edges.end()) return; + Edge &edge = it->second; + if (a < b) for (auto &c : edge.xs) out.push_back(&c); + else for (auto ci = edge.xs.rbegin(); ci != edge.xs.rend(); ++ci) out.push_back(&*ci); + }; + std::vector loops(nt); + for (size_t t = 0; t < nt; ++t) { + const auto &tri = mesh.indices[t]; + Loop &L = loops[t]; + for (int e = 0; e < 3; ++e) { + L.ids.push_back(tri[e]); + std::vector on_edge; + walk_edge(tri[e], tri[(e + 1) % 3], on_edge); + for (Crossing *c : on_edge) { + L.xpos.push_back(int(L.ids.size())); + L.ids.push_back(-(1 + int(L.xs.size()))); + L.xs.push_back(c); + } + } + const Vec3f &a0 = pos[size_t(tri[0])]; + L.N = (pos[size_t(tri[1])] - a0).cross(pos[size_t(tri[2])] - a0); + const float nl = L.N.norm(); + if (nl > 1e-12f) L.N /= nl; + } + + const float cell = 0.5f * step_width_mm; + const auto trace = [&](size_t t) { + Loop &L = loops[t]; + const int n = int(L.xs.size()); + const auto &tri = mesh.indices[t]; + if (n == 0 || region[t] == 0) + return; + if (n % 2 != 0 || L.N.squaredNorm() < 0.5f) + return; + // Local frame on the triangle's plane; the loop runs counter-clockwise in it. + const Vec3f &A = pos[size_t(tri[0])], &B = pos[size_t(tri[1])], &C = pos[size_t(tri[2])]; + const Vec3f U = (B - A).normalized(), V = L.N.cross(U); + const auto to2 = [&](const Vec3f &p) { return Vec2f((p - A).dot(U), (p - A).dot(V)); }; + const auto to3 = [&](const Vec2f &q) { return Vec3f(A + U * q.x() + V * q.y()); }; + const Vec2f a2 = to2(A), b2 = to2(B), c2 = to2(C); + const float det = (b2.x() - a2.x()) * (c2.y() - a2.y()) - (c2.x() - a2.x()) * (b2.y() - a2.y()); + if (std::abs(det) < 1e-12f) + return; + + // A barycentric lattice over the triangle, dense enough that its boundary rows are at least as + // fine as the edge march. Its boundary points take their side from the march - the lower + // corner's side, flipped at every crossing passed - so the contour traced through the lattice + // ends exactly at the crossings the neighbours share; no clipping, no matching. A conflict + // between that and the far corner's own side (an edge whose crossings the march dropped for + // parity) leaves the triangle uncut. + const float longest = std::sqrt(std::max({ (b2 - a2).squaredNorm(), (c2 - b2).squaredNorm(), (a2 - c2).squaredNorm() })); + const int N = std::clamp(int(std::ceil(longest / cell)), 4, 96); + const float h = longest / float(N); + const int W = N + 1; + // Lattice point (j, k): A + (B - A) j/N + (C - A) k/N, j + k <= N. Edge 0 (A->B) is k == 0, + // edge 1 (B->C) is j + k == N, edge 2 (C->A) is j == 0. + const auto at2 = [&](int j, int k) { return Vec2f(a2 + (b2 - a2) * (float(j) / float(N)) + (c2 - a2) * (float(k) / float(N))); }; + std::vector f(size_t(W) * size_t(W), 0.f); + std::vector sign(size_t(W) * size_t(W), 0); + const auto id = [&](int j, int k) { return size_t(k) * size_t(W) + size_t(j); }; + for (int k = 0; k <= N; ++k) + for (int j = 0; j + k <= N; ++j) { + const float wb = float(j) / float(N), wc = float(k) / float(N), wa = 1.f - wb - wc; + Vec3f nn = wa * vnormal[size_t(tri[0])] + wb * vnormal[size_t(tri[1])] + wc * vnormal[size_t(tri[2])]; + const float nl = nn.norm(); + nn = (nl > 1e-12f) ? Vec3f(nn / nl) : L.N; + const float v = sampler(A + (B - A) * wb + (C - A) * wc, nn) - iso; + f[id(j, k)] = v; + sign[id(j, k)] = v > 0.f ? 1 : -1; + } + // Boundary sides from the march. Each edge walks from its first corner in loop order; the + // crossings on it are in that order in L.xs. Position along edge e of lattice point m/N. + const auto edge_point = [&](int e, int m) -> std::pair { // (j, k) + return e == 0 ? std::make_pair(m, 0) : e == 1 ? std::make_pair(N - m, m) : std::make_pair(0, N - m); + }; + // The crossings of edge e, with their parameter from the edge's first corner in loop order. + std::vector>> edge_x(3); + { + int e = -1, k = 0; + for (int idv : L.ids) { + if (idv >= 0) { ++e; continue; } + const Crossing &c = *L.xs[size_t(k)]; + // c.t runs from the lower vertex id; the loop walks tri[e] -> tri[(e + 1) % 3]. + const float u = (tri[e] < tri[(e + 1) % 3]) ? c.t : 1.f - c.t; + edge_x[size_t(e)].push_back({ u, k }); + ++k; + } + } + for (int e = 0; e < 3; ++e) { + int8_t s = side_of(vh[size_t(tri[e])]) ? 1 : -1; + size_t next = 0; + for (int m = 0; m <= N; ++m) { + const float u = float(m) / float(N); + while (next < edge_x[size_t(e)].size() && edge_x[size_t(e)][next].first < u) { s = -s; ++next; } + const auto [j, k] = edge_point(e, m); + sign[id(j, k)] = s; + // Keep the value on the march's side of zero, so interpolation toward the interior + // does not put a crossing where the march has none - and clear of zero, so a contour + // that does pass between this point and the next row is not put on the boundary. + if ((f[id(j, k)] > 0.f) != (s > 0)) + f[id(j, k)] = float(s) * std::max(std::abs(f[id(j, k)]), 0.05f * range); + } + if ((s > 0) != side_of(vh[size_t(tri[(e + 1) % 3])])) + return; // parity conflict on this edge + } + + // Marching triangles. A contour point lives on a lattice edge, keyed by its lower point and + // direction: 0 (j,k)-(j+1,k), 1 (j,k)-(j,k+1), 2 (j+1,k)-(j,k+1). A boundary lattice edge with + // a sign change carries exactly the march crossing in its interval, and is that crossing. + std::vector pts; + std::vector pt_x; // crossing index, or -1 for an interior point + std::unordered_map point_of; + std::vector> link; + bool bad = false; + const auto point_on = [&](int j, int k, int dir) -> int { + const uint32_t key = (uint32_t(j) << 16) | (uint32_t(k) << 2) | uint32_t(dir); + auto it = point_of.find(key); + if (it != point_of.end()) + return it->second; + // Endpoints (j0, k0) and (jb, kb). + const int j0 = dir == 2 ? j + 1 : j, k0 = k; + const int jb = dir == 0 ? j + 1 : j, kb = dir == 0 ? k : k + 1; + int xk = -1; + Vec2f p; + int e = -1; + float u0 = 0.f, u1 = 0.f; + if (k0 == 0 && kb == 0) { e = 0; u0 = float(j0) / float(N); u1 = float(jb) / float(N); } + else if (j0 + k0 == N && jb + kb == N) { e = 1; u0 = float(k0) / float(N); u1 = float(kb) / float(N); } + else if (j0 == 0 && jb == 0) { e = 2; u0 = float(N - k0) / float(N); u1 = float(N - kb) / float(N); } + if (e >= 0) { + const float lo = std::min(u0, u1), hi = std::max(u0, u1); + for (const auto &[u, k_] : edge_x[size_t(e)]) + if (u >= lo && u < hi) { if (xk >= 0) bad = true; xk = k_; } + if (xk < 0) { bad = true; p = 0.5f * (at2(j0, k0) + at2(jb, kb)); } + else p = to2(L.xs[size_t(xk)]->p); + } else { + const float fa = f[id(j0, k0)], fb = f[id(jb, kb)]; + const float s = (fa != fb) ? std::clamp(fa / (fa - fb), 0.f, 1.f) : 0.5f; + p = at2(j0, k0) + (at2(jb, kb) - at2(j0, k0)) * s; + } + const int pid = int(pts.size()); + pts.push_back(p); + pt_x.push_back(xk); + link.push_back({ -1, -1 }); + point_of.emplace(key, pid); + return pid; + }; + const auto connect = [&](int p, int q) { + for (int *slot : { &link[size_t(p)][0], &link[size_t(p)][1] }) + if (*slot < 0) { *slot = q; break; } + for (int *slot : { &link[size_t(q)][0], &link[size_t(q)][1] }) + if (*slot < 0) { *slot = p; break; } + }; + // Up triangle (j,k),(j+1,k),(j,k+1): edges dir 0 at (j,k), dir 1 at (j,k), dir 2 at (j,k). + // Down triangle (j+1,k),(j+1,k+1),(j,k+1): dir 1 at (j+1,k), dir 0 at (j,k+1), dir 2 at (j,k). + for (int k = 0; k < N; ++k) + for (int j = 0; j + k < N; ++j) { + { + const int8_t s0_ = sign[id(j, k)], s1_ = sign[id(j + 1, k)], s2_ = sign[id(j, k + 1)]; + if (!(s0_ == s1_ && s1_ == s2_)) { + std::vector ends; + if (s0_ != s1_) ends.push_back(point_on(j, k, 0)); + if (s0_ != s2_) ends.push_back(point_on(j, k, 1)); + if (s1_ != s2_) ends.push_back(point_on(j, k, 2)); + if (ends.size() == 2) connect(ends[0], ends[1]); + } + } + if (j + k + 1 < N) { + const int8_t s0_ = sign[id(j + 1, k)], s1_ = sign[id(j + 1, k + 1)], s2_ = sign[id(j, k + 1)]; + if (!(s0_ == s1_ && s1_ == s2_)) { + std::vector ends; + if (s0_ != s1_) ends.push_back(point_on(j + 1, k, 1)); + if (s1_ != s2_) ends.push_back(point_on(j, k + 1, 0)); + if (s0_ != s2_) ends.push_back(point_on(j, k, 2)); + if (ends.size() == 2) connect(ends[0], ends[1]); + } + } + } + if (bad) + return; + + // Chains from every crossing to the crossing it leads to. Closed loops never touch the + // boundary and are left alone - refinement resolves a feature that sits entirely inside a + // triangle. + std::vector matched(static_cast(n), -1); + std::vector chains; + std::vector> raws; // the traced polyline of each chain, crossing to crossing + std::vector seen(pts.size(), 0); + for (size_t s = 0; s < pts.size(); ++s) { + if (seen[s] || pt_x[s] < 0) + continue; + std::vector full; + int prev = -1, cur = int(s); + while (cur >= 0 && !seen[size_t(cur)]) { + seen[size_t(cur)] = 1; + full.push_back(pts[size_t(cur)]); + if (pt_x[size_t(cur)] >= 0 && cur != int(s)) + break; + const int nx0 = link[size_t(cur)][0], nx1 = link[size_t(cur)][1]; + const int next = (nx0 != prev) ? nx0 : nx1; + prev = cur; cur = next; + } + if (cur < 0 || pt_x[size_t(cur)] < 0 || cur == int(s)) + return; // a contour that starts at a crossing and ends nowhere: the lattice is inconsistent + Chain ch; + ch.i = pt_x[s]; + ch.j = pt_x[size_t(cur)]; + if (matched[size_t(ch.i)] >= 0 || matched[size_t(ch.j)] >= 0 || ch.i == ch.j) + return; + matched[size_t(ch.i)] = ch.j; + matched[size_t(ch.j)] = ch.i; + chains.push_back(std::move(ch)); + raws.push_back(std::move(full)); + } + // How close each contour comes to another: two sides of a thin feature. Simplifying either by + // the usual tolerance, or offsetting its copies by the usual gap, could then push it across + // the other, so both are scaled to the clearance. Segment-to-segment over every pair. + { + const auto seg_dist = [](const Vec2f &a, const Vec2f &b, const Vec2f &c, const Vec2f &d) { + const auto pt_seg = [](const Vec2f &q, const Vec2f &u, const Vec2f &v) { + const Vec2f uv = v - u; + const float t = std::clamp((q - u).dot(uv) / std::max(uv.squaredNorm(), 1e-12f), 0.f, 1.f); + return (q - (u + uv * t)).norm(); + }; + return std::min({ pt_seg(a, c, d), pt_seg(b, c, d), pt_seg(c, a, b), pt_seg(d, a, b) }); + }; + for (size_t x = 0; x < raws.size(); ++x) + for (size_t y = x + 1; y < raws.size(); ++y) { + float best = std::min(chains[x].clearance, chains[y].clearance); + for (size_t i = 0; i + 1 < raws[x].size(); ++i) + for (size_t j = 0; j + 1 < raws[y].size(); ++j) + best = std::min(best, seg_dist(raws[x][i], raws[x][i + 1], raws[y][j], raws[y][j + 1])); + chains[x].clearance = std::min(chains[x].clearance, best); + chains[y].clearance = std::min(chains[y].clearance, best); + } + } + for (size_t c = 0; c < chains.size(); ++c) { + Chain &ch = chains[c]; + const std::vector &full = raws[c]; + const float tol = std::min(h, 0.25f * ch.clearance); + const float gap = std::min(seam_gap_mm, 0.5f * ch.clearance); + std::vector simple; + simplify_polyline(full, tol, simple); + // A vertex within the seam gap of the previous one, or of the far end, leaves its copies no + // room to clear the blend of the step, and a corner that close to an edge is within the + // seam's own width anyway: it is merged into its neighbour. + { + std::vector spaced; + spaced.push_back(simple.front()); + for (size_t m = 1; m + 1 < simple.size(); ++m) + if ((simple[m] - spaced.back()).norm() >= gap && (simple[m] - simple.back()).norm() >= gap) + spaced.push_back(simple[m]); + spaced.push_back(simple.back()); + simple = std::move(spaced); + } + const int m_loop = int(L.ids.size()); + const bool adjacent = (L.xpos[size_t(ch.j)] - L.xpos[size_t(ch.i)] + m_loop) % m_loop == 1 || + (L.xpos[size_t(ch.i)] - L.xpos[size_t(ch.j)] + m_loop) % m_loop == 1; + if (simple.size() == 2 && full.size() > 2 && adjacent) { + // Never down to a bare chord between two crossings next to each other on one edge: the + // shallow pocket between them would be joined along the edge itself, and the regions on + // either side would overlap. The raw point farthest from the chord stays. + const Vec2f d = full.back() - full.front(); + const float dl = std::max(d.norm(), 1e-9f); + size_t bi = full.size() / 2; + float bd = 0.1f * tol; // below this the contour is straight: take its middle point + for (size_t m = 1; m + 1 < full.size(); ++m) { + const Vec2f r = full[m] - full.front(); + const float dist = std::abs(d.x() * r.y() - d.y() * r.x()) / dl; + if (dist > bd) { bd = dist; bi = m; } + } + simple.insert(simple.begin() + 1, full[bi]); + } + // Hairpins - the contour doubling back on itself with less than the seam gap between the + // two sides, the tip of a grain line thinner than the gap - would give a region polygon + // whose two sides cross. The spike vertex goes, and the feature is flattened there, as a + // thin feature on an edge is. + for (bool again = true; again;) { + again = false; + for (size_t m = 1; m + 1 < simple.size(); ++m) { + const Vec2f d1 = simple[m] - simple[m - 1], d2 = simple[m + 1] - simple[m]; + const float l1 = d1.norm(), l2 = d2.norm(); + if (l1 < 1e-9f || l2 < 1e-9f) { simple.erase(simple.begin() + long(m)); again = true; break; } + if (d1.dot(d2) / (l1 * l2) > -0.5f) + continue; // turns less than 120 degrees: a corner, not a hairpin + // Distance between the two sides: the shorter side's far end to the other side. + const Vec2f &tip = simple[m]; + const auto dist_to = [&](const Vec2f &q, const Vec2f &a, const Vec2f &b) { + const Vec2f ab = b - a; + const float t = std::clamp((q - a).dot(ab) / std::max(ab.squaredNorm(), 1e-12f), 0.f, 1.f); + return (q - (a + ab * t)).norm(); + }; + const float between = (l1 < l2) ? dist_to(simple[m - 1], tip, simple[m + 1]) : dist_to(simple[m + 1], simple[m - 1], tip); + if (between < seam_gap_mm) { + simple.erase(simple.begin() + long(m)); + again = true; + break; + } + } + } + for (size_t m = 1; m + 1 < simple.size(); ++m) + ch.pts.push_back(to3(simple[m])); + if (ch.pts.empty() && adjacent) { + // Two crossings next to each other on one edge and the contour, once simplified, going + // straight from one to the other: an empty pocket. There is nothing to wall off - a wall + // along the edge would be a zero-area strip, and the neighbour would lay its own on top + // - so neither crossing gets a seam. Recorded here and applied once the tracing is done. + L.no_seam.push_back(ch.i); + L.no_seam.push_back(ch.j); + } + } + for (int k = 0; k < n; ++k) + if (matched[size_t(k)] < 0) + return; + L.chains = std::move(chains); + L.partner = std::move(matched); + L.chain_of.assign(static_cast(n), -1); + for (size_t c = 0; c < L.chains.size(); ++c) { + L.chain_of[size_t(L.chains[c].i)] = int(c); + L.chain_of[size_t(L.chains[c].j)] = int(c); + } + L.ok = true; + }; + tbb::parallel_for(tbb::blocked_range(0, nt), [&](const tbb::blocked_range &r) { + for (size_t t = r.begin(); t < r.end(); ++t) + trace(t); + }); + size_t cut_count = 0; + for (size_t t = 0; t < nt; ++t) { + cut_count += loops[t].ok ? 1 : 0; + if (loops[t].ok) + for (int k : loops[t].no_seam) + loops[t].xs[size_t(k)]->no_seam = true; + } + + // 4. Which crossings a contour reaches, and how obliquely: the copies of a doubled crossing are moved + // apart along the edge, so the shallower the contour meets the edge the further apart they need to + // be to sit the same distance clear of it. + for (size_t t = 0; t < nt; ++t) { + Loop &L = loops[t]; + if (!L.ok) + continue; + for (auto &ch : L.chains) { + Crossing &p = *L.xs[size_t(ch.i)], &q = *L.xs[size_t(ch.j)]; + p.used = q.used = true; + const Vec3f p_next = ch.pts.empty() ? q.p : ch.pts.front(); + const Vec3f q_prev = ch.pts.empty() ? p.p : ch.pts.back(); + for (auto [c, toward] : { std::make_pair(&p, p_next), std::make_pair(&q, q_prev) }) { + Vec3f d = toward - c->p; + const float dl = d.norm(); + if (dl < 1e-12f) continue; + const Vec3f ed = (pos[size_t(c->b)] - pos[size_t(c->a)]).normalized(); + c->sin_min = std::min(c->sin_min, ed.cross(d / dl).norm()); + // Only the part of a move along the edge that runs along the contour brings the copy + // toward the next vertex's copies. With no interior vertex the chord's two ends share + // it; otherwise the interior copies, placed first, say how much room there is. + if (ch.pts.empty()) + c->dt_max = std::min(c->dt_max, 0.45f * dl / std::max(std::abs(ed.dot(d / dl)), 1e-3f)); + } + } + } + + // 5. Output vertices: the originals, then one or two per crossing and per interior contour vertex. + // A sharp crossing that a contour reaches is doubled, into two vertices on the edge either side of + // it, each on its own side of the contour; a triangle on that edge that is not cut itself simply + // carries both on its perimeter, one after the other, so the cut neighbour's wall still meets a + // closed surface. Keeping the copies on the edge is what keeps every triangle's split planar and + // inside the triangle. A crossing that is not sharp, or that no contour reaches, stays one vertex + // and the surface ramps there. + indexed_triangle_set out; + out.vertices = pos; + const float half_gap = 0.5f * seam_gap_mm; + // Interior contour vertices: doubled when the contour's ends are, offset across the contour along + // the bisector of the two segments meeting there, toward the high side; mitre limited, and held + // inside the triangle - a copy pushed across an edge would fold the region over the neighbour. + for (size_t t = 0; t < nt; ++t) { + Loop &L = loops[t]; + if (!L.ok) + continue; + const auto &tri = mesh.indices[t]; + const Vec3f &A = pos[size_t(tri[0])], &B = pos[size_t(tri[1])], &C = pos[size_t(tri[2])]; + const Vec3f U = (B - A).normalized(), V = L.N.cross(U); + const Vec2f a2(0.f, 0.f), b2((B - A).dot(U), (B - A).dot(V)), c2((C - A).dot(U), (C - A).dot(V)); + const float det = (b2.x() - a2.x()) * (c2.y() - a2.y()) - (c2.x() - a2.x()) * (b2.y() - a2.y()); + const auto bary2 = [&](const Vec3f &p) { + const Vec2f q((p - A).dot(U), (p - A).dot(V)); + const float wb = ((q.x() - a2.x()) * (c2.y() - a2.y()) - (c2.x() - a2.x()) * (q.y() - a2.y())) / det; + const float wc = ((b2.x() - a2.x()) * (q.y() - a2.y()) - (q.x() - a2.x()) * (b2.y() - a2.y())) / det; + return Vec3f(1.f - wb - wc, wb, wc); + }; + // The largest fraction of the offset that keeps the copy inside, with a little to spare. + const auto inside_fraction = [&](const Vec3f &p, const Vec3f &off) { + const Vec3f w0 = bary2(p), w1 = bary2(p + off); + float lambda = 1.f; + for (int i = 0; i < 3; ++i) + if (w1[i] < 0.f && w0[i] > w1[i]) + lambda = std::min(lambda, w0[i] / (w0[i] - w1[i])); + return 0.9f * std::max(lambda, 0.f); + }; + const bool s0 = side_of(vh[size_t(mesh.indices[t][0])]); + for (auto &ch : L.chains) { + const Crossing &p = *L.xs[size_t(ch.i)], &q = *L.xs[size_t(ch.j)]; + const bool doubled = p.sharp && p.used && !p.no_seam && q.sharp && q.used && !q.no_seam; + // The arc right after crossing ch.i lies on one side; which way that is from the contour + // says where "high" is. The arc's side: the loop's first corner's, flipped once per + // crossing passed, so after crossing index k it is !s0 for even k and s0 for odd. + const bool arc_high = (ch.i % 2 == 0) ? !s0 : s0; + const int after_pos = L.xpos[size_t(ch.i)] + 1; + const int entry = L.ids[size_t(after_pos) % L.ids.size()]; + const Vec3f ref = entry >= 0 ? pos[size_t(entry)] : L.xs[size_t(-entry - 1)]->p; + const size_t m = ch.pts.size(); + ch.lo.resize(m); ch.hi.resize(m); + // The left of the walk from i to j is one side of the contour all along it; whether that + // side is high is settled once, at the first segment, where the arc is a known reference. + // The direction the contour leaves the crossing in, taken over a usable length: the first + // interior vertex may sit right next to it. + Vec3f d_first = q.p - p.p; + for (size_t k = 0; k < m; ++k) + if ((ch.pts[k] - p.p).norm() > 0.25f * seam_gap_mm) { d_first = ch.pts[k] - p.p; break; } + d_first.normalize(); + const bool left_high = (L.N.cross(d_first).dot(ref - p.p) > 0.f) == arc_high; + for (size_t k = 0; k < m; ++k) { + if (!doubled) { + ch.lo[k] = ch.hi[k] = int(out.vertices.size()); + out.vertices.push_back(ch.pts[k]); + continue; + } + const Vec3f prev = (k == 0) ? p.p : ch.pts[k - 1]; + const Vec3f next = (k + 1 == m) ? q.p : ch.pts[k + 1]; + Vec3f d1 = (ch.pts[k] - prev).normalized(), d2 = (next - ch.pts[k]).normalized(); + Vec3f n1 = L.N.cross(d1), n2 = L.N.cross(d2); + Vec3f bis = n1 + n2; + float bl = bis.norm(); + Vec3f off; + if (bl < 1e-6f) off = n1; + else { + bis /= bl; + // Mitre: the offset polyline stays `half_gap` from both segments, up to twice that. + const float cos_half = std::max(bis.dot(n1), 0.5f); + off = bis / cos_half; + } + if (!left_high) off = -off; + // No further along either segment than half its length, so copies never cross their + // neighbours'; across the segments the offset is free. + const float ol = off.norm(); + const float reach = std::min({ half_gap, 0.45f * ch.clearance, + 0.45f * (ch.pts[k] - prev).norm() / std::max(std::abs(off.dot(d1)) / ol, 1e-3f), + 0.45f * (next - ch.pts[k]).norm() / std::max(std::abs(off.dot(d2)) / ol, 1e-3f) }); + const Vec3f off_lo = -off * (reach * inside_fraction(ch.pts[k], -off * reach)); + const Vec3f off_hi = off * (reach * inside_fraction(ch.pts[k], off * reach)); + // As for the crossings: each copy at the first of a few positions outward that samples + // pure, or the vertex stays single. + const auto place = [&](const Vec3f &o, bool high) -> int { + for (int step = 1; step <= 4; ++step) { + const Vec3f q = ch.pts[k] + o * (0.5f * float(step)); + if (step > 2 && inside_fraction(ch.pts[k], q - ch.pts[k]) < 0.999f) break; + const float h = sampler(q, L.N) - iso; + if ((h > 0.f) == high && std::abs(h) >= 0.3f * range) { + out.vertices.push_back(q); + return int(out.vertices.size()) - 1; + } + } + return -1; + }; + const int il = place(off_lo, false), ih = place(off_hi, true); + if (il < 0 || ih < 0) { + out.vertices.resize(out.vertices.size() - (il >= 0 ? 1 : 0) - (ih >= 0 ? 1 : 0)); + ch.lo[k] = ch.hi[k] = int(out.vertices.size()); + out.vertices.push_back(ch.pts[k]); + continue; + } + ch.lo[k] = il; ch.hi[k] = ih; + } + // Room for the end crossings' copies along the edge: the nearer of the first interior + // vertex's copies, measured along the contour, less a margin, over the edge's share of + // that direction. + if (m > 0) + for (auto [c, k, other] : { std::make_tuple(&p, size_t(0), q.p), std::make_tuple(&q, m - 1, p.p) }) { + (void) other; + Crossing &cr = const_cast(*c); + const Vec3f d = ch.pts[k] - cr.p; + const float dl = d.norm(); + if (dl < 1e-9f) continue; + const Vec3f dn = d / dl; + const float u_lo = (out.vertices[size_t(ch.lo[k])] - cr.p).dot(dn); + const float u_hi = (out.vertices[size_t(ch.hi[k])] - cr.p).dot(dn); + const Vec3f ed = (pos[size_t(cr.b)] - pos[size_t(cr.a)]).normalized(); + cr.dt_max = std::min(cr.dt_max, 0.9f * std::max(std::min(u_lo, u_hi), 0.f) / std::max(std::abs(ed.dot(dn)), 1e-3f)); + } + } + } + + for (auto &kv : edges) { + Edge &edge = kv.second; + for (size_t i = 0; i < edge.xs.size(); ++i) { + Crossing &c = edge.xs[i]; + if (!(c.sharp && c.used) || c.no_seam) { + c.single = int(out.vertices.size()); + out.vertices.push_back(c.p); + continue; + } + const float len = (pos[size_t(c.b)] - pos[size_t(c.a)]).norm(); + // Room along the edge: a third of the way to the previous and the next crossing or vertex, + // and less than half the shortest contour segment leaving the crossing, so the copies of + // the contour's next vertex cannot cross these. + const float t_prev = (i == 0) ? 0.f : edge.xs[i - 1].t; + const float t_next = (i + 1 == edge.xs.size()) ? 1.f : edge.xs[i + 1].t; + float dt = half_gap / std::max(c.sin_min, 0.15f) / std::max(len, 1e-6f); + dt = std::min({ dt, (c.t - t_prev) / 3.f, (t_next - c.t) / 3.f, c.dt_max / std::max(len, 1e-6f) }); + if (!(dt > 1e-6f)) { + c.single = int(out.vertices.size()); + out.vertices.push_back(c.p); + continue; + } + // The side of the edge before this crossing: the lower vertex's, flipped once per crossing + // passed on the way. + const bool before_high = side_of(vh[size_t(c.a)]) != (i % 2 == 1); + // Each copy has to sample a pure value of its own side - inside the step's blend it would be + // displaced to a height between the sides, and one such vertex tilts every triangle at it. + // The copy is placed at the first of a few positions along the edge, from dt outward, that + // samples pure; when none does the crossing stays one vertex and the surface ramps across + // that edge only. + // The search never goes past what the neighbours allow: less than half way to the next + // crossing along the edge (so two crossings' copies never meet), most of the way to the + // edge's vertex, and not past dt_max toward the contour's next vertex. + const float lo_share = (i == 0) ? 0.9f : 0.49f, hi_share = (i + 1 == edge.xs.size()) ? 0.9f : 0.49f; + const float t_lo_lim = c.t - std::min(lo_share * (c.t - t_prev), c.dt_max / std::max(len, 1e-6f)); + const float t_hi_lim = c.t + std::min(hi_share * (t_next - c.t), c.dt_max / std::max(len, 1e-6f)); + const auto place = [&](float sgn, bool high) -> int { + for (int step = 1; step <= 6; ++step) { + const float tt = c.t + sgn * dt * (0.5f * float(step)); + if (tt < t_lo_lim || tt > t_hi_lim) break; + const auto [q, qn] = sample_between(c.a, c.b, tt); + const float h = sampler(q, qn) - iso; + if ((h > 0.f) == high && std::abs(h) >= 0.3f * range) { + out.vertices.push_back(q); + return int(out.vertices.size()) - 1; + } + } + return -1; + }; + const int na = place(-1.f, before_high), nb = place(+1.f, !before_high); + if (na < 0 || nb < 0) { + out.vertices.resize(out.vertices.size() - (na >= 0 ? 1 : 0) - (nb >= 0 ? 1 : 0)); + c.single = int(out.vertices.size()); + out.vertices.push_back(c.p); + continue; + } + c.near_a = na; c.near_b = nb; + c.lo = before_high ? c.near_b : c.near_a; + c.hi = before_high ? c.near_a : c.near_b; + } + } + // 6. Output triangles: each region of a cut triangle ear-clipped on its own side's copies, a wall + // strip per contour wound with the surface, everything else passed through or plainly split. + out.indices.reserve(nt * 2); + std::vector source; + source.reserve(nt * 2); + const auto emit = [&](int a, int b, int c, int src) { out.indices.emplace_back(a, b, c); source.push_back(src); }; + const auto copy_for = [&](const Crossing &c, bool high) { return c.single >= 0 ? c.single : (high ? c.hi : c.lo); }; + // Triangulates a triangle that carries extra vertices on its edges without a zero-area sliver: the + // first extra vertex found is joined to the opposite corner, which splits the triangle in two that + // carry fewer extras each, and so on. A fan from a corner cannot do this - the extras on that + // corner's own edges are collinear with it. Each side is the corner followed by the extras on the + // way to the next corner. + const std::function, 3>, int)> split_tri = + [&](std::array, 3> side, int src) { + for (int e = 0; e < 3; ++e) + if (side[size_t(e)].size() > 1) { + const auto &S = side[size_t(e)]; + const int a = S[0], x = S[1], c = side[size_t((e + 2) % 3)][0]; + std::vector rest(S.begin() + 1, S.end()); // x and the extras after it + split_tri({ std::vector{ a }, std::vector{ x }, side[size_t((e + 2) % 3)] }, src); + split_tri({ std::move(rest), side[size_t((e + 1) % 3)], std::vector{ c } }, src); + return; + } + emit(side[0][0], side[1][0], side[2][0], src); + }; + // A wall strip between the low and high copies of a contour, from crossing p to crossing q. + const auto emit_wall = [&](const Crossing &p, const Chain &ch, const Crossing &q, const Vec3f &N, int src) { + std::vector lo, hi; + lo.push_back(copy_for(p, false)); hi.push_back(copy_for(p, true)); + for (size_t k = 0; k < ch.pts.size(); ++k) { lo.push_back(ch.lo[k]); hi.push_back(ch.hi[k]); } + lo.push_back(copy_for(q, false)); hi.push_back(copy_for(q, true)); + auto tri_up = [&](int i, int j, int k) { + if (i == j || j == k || k == i) return; + const Vec3f &A = out.vertices[size_t(i)], &B = out.vertices[size_t(j)], &C = out.vertices[size_t(k)]; + if ((B - A).cross(C - A).dot(N) >= 0.f) emit(i, j, k, src); else emit(i, k, j, src); + }; + for (size_t k = 0; k + 1 < lo.size(); ++k) { + tri_up(lo[k], lo[k + 1], hi[k + 1]); + tri_up(lo[k], hi[k + 1], hi[k]); + } + }; + + for (size_t t = 0; t < nt; ++t) { + const auto &tri = mesh.indices[t]; + const Loop &L = loops[t]; + const int n = int(L.xs.size()); + if (n == 0) { emit(tri[0], tri[1], tri[2], int(t)); continue; } + const size_t m = L.ids.size(); + const bool s0 = side_of(vh[size_t(tri[0])]); + + if (L.ok) { + // Every crossing starts one region: the run of the loop after it, on the side the field has + // there, following any other contour it meets back to the loop, until it returns to the + // start. Each region is tracked per (crossing, side) so the one between two contours is + // emitted once, not once per contour. The region's vertices are collected in the triangle's + // plane for ear clipping, since a traced contour can make it concave. + const Vec3f &A = pos[size_t(tri[0])], &B = pos[size_t(tri[1])]; + const Vec3f U = (B - A).normalized(), V = L.N.cross(U); + std::vector pts2; + std::vector ids2; + const auto push = [&](int id) { + const Vec3f &p = out.vertices[size_t(id)]; + pts2.emplace_back((p - A).dot(U), (p - A).dot(V)); + ids2.push_back(id); + }; + // Interior vertices of chain c, walking from crossing `from`, on side S. + const auto push_chain = [&](int c, int from, bool S) { + const Chain &ch = L.chains[size_t(c)]; + const auto &cp = S ? ch.hi : ch.lo; + if (from == ch.i) for (size_t k = 0; k < cp.size(); ++k) push(cp[k]); + else for (size_t k = cp.size(); k-- > 0;) push(cp[k]); + }; + const auto side_after = [&](int k) { return (k % 2 == 0) ? !s0 : s0; }; + std::vector> consumed(static_cast(n), { false, false }); + for (int k = 0; k < n; ++k) { + const bool S = side_after(k); + if (consumed[size_t(k)][S]) + continue; + pts2.clear(); ids2.clear(); + push(copy_for(*L.xs[size_t(k)], S)); + consumed[size_t(k)][S] = true; + size_t i = size_t(L.xpos[size_t(k)] + 1) % m; + for (size_t guard = 0; guard < 2 * m; ++guard) { + const int id = L.ids[i]; + if (id >= 0) { push(id); i = (i + 1) % m; continue; } + const int c = -id - 1; + consumed[size_t(c)][S] = true; + push(copy_for(*L.xs[size_t(c)], S)); + if (c == L.partner[size_t(k)]) + break; + // Follow the contour from c to its partner, then continue the loop after it. + const int pc = L.partner[size_t(c)]; + push_chain(L.chain_of[size_t(c)], c, S); + consumed[size_t(pc)][S] = true; + push(copy_for(*L.xs[size_t(pc)], S)); + if (pc == L.partner[size_t(k)]) + break; + i = size_t(L.xpos[size_t(pc)] + 1) % m; + } + // Close the polygon along the region's own contour back to k, in reverse. + push_chain(L.chain_of[size_t(k)], L.partner[size_t(k)], S); + std::vector poly(ids2.size()); + std::iota(poly.begin(), poly.end(), 0); + ear_clip(pts2, poly, [&](int a, int b, int c) { emit(ids2[size_t(a)], ids2[size_t(b)], ids2[size_t(c)], int(t)); }); + } + for (const auto &ch : L.chains) + emit_wall(*L.xs[size_t(ch.i)], ch, *L.xs[size_t(ch.j)], L.N, int(t)); + continue; + } + // Not cut: split at the crossings so the neighbours' cuts meet no T-junction. A doubled crossing + // contributes both copies, the one nearer the vertex the walk comes from first. + std::array, 3> side; + int e = -1; + for (size_t i = 0; i < m; ++i) { + if (L.ids[i] >= 0) { ++e; side[size_t(e)].push_back(L.ids[i]); continue; } + const Crossing &c = *L.xs[size_t(-L.ids[i] - 1)]; + if (c.single >= 0) { side[size_t(e)].push_back(c.single); continue; } + const bool from_a = tri[e] == c.a; + side[size_t(e)].push_back(from_a ? c.near_a : c.near_b); + side[size_t(e)].push_back(from_a ? c.near_b : c.near_a); + } + split_tri(std::move(side), int(t)); + } + // Safety net: a texture whose features are of the seam's own scale can fold copies over each + // other in spite of everything above. When more than a trace of the output faces the wrong way, + // the cut is not trusted and the mesh goes out as it came in. + { + size_t inverted = 0; + for (size_t i = 0; i < out.indices.size(); ++i) { + const auto &f = out.indices[i]; + const auto &g = mesh.indices[size_t(source[i])]; + const Vec3f n = (out.vertices[size_t(f[1])] - out.vertices[size_t(f[0])]).cross(out.vertices[size_t(f[2])] - out.vertices[size_t(f[0])]); + const Vec3f ns = (mesh.vertices[size_t(g[1])] - mesh.vertices[size_t(g[0])]).cross(mesh.vertices[size_t(g[2])] - mesh.vertices[size_t(g[0])]); + inverted += n.dot(ns) < 0.f && n.norm() > 1e-7f; + } + if (double(inverted) > 0.002 * double(out.indices.size())) + return passthrough(); + } + if (out_source) *out_source = std::move(source); + if (out_cut_count) *out_cut_count = cut_count; + return out; +} + +} // namespace Slic3r diff --git a/src/libslic3r/TextureDisplacement.hpp b/src/libslic3r/TextureDisplacement.hpp new file mode 100644 index 0000000000..e97178abca --- /dev/null +++ b/src/libslic3r/TextureDisplacement.hpp @@ -0,0 +1,1139 @@ +#ifndef slic3r_TextureDisplacement_hpp_ +#define slic3r_TextureDisplacement_hpp_ + +#include +#include +#include +#include +#include + +#include +#include // view_project_matrix is a std::array +#include +#include + +#include + +#include "Point.hpp" +#include "TriangleMesh.hpp" +#include "TriangleSelector.hpp" + +namespace Slic3r { + +// Optional step-by-step capture of a bake; see TextureBake/TextureBakeDebug.hpp. Forward declared and +// taken by pointer so this header, which most of the texture feature includes, does not grow a +// dependency for something only the debug view and the benchmarks use. +class BakeStageRecorder; + +class ModelVolume; + +// Bits of subdivide_mesh_adaptive()'s per-triangle `refine_region` mask. See that function. +static constexpr uint8_t REFINE_PAINTED = 1; +static constexpr uint8_t REFINE_BORDER = 2; + +// Progress/cancellation hook for the (potentially multi-second) bake. Called with a 0..100 +// percentage; return false to abort. See build_texture_displacement(). +using DisplacementProgressFn = std::function; + +// Maximum number of simultaneous texture-displacement layers a single ModelVolume can hold. +// Each layer owns its own paint mask (ModelVolume::texture_displacement_facet(slot)), so this +// is also the number of independent EnforcerBlockerType selectors kept per volume. +static constexpr size_t TEXTURE_DISPLACEMENT_MAX_LAYERS = 8; + +// How a layer's height texture is sampled outside its [0, 1) tile when tiling is enabled. Ignored +// (always clamp) when TextureDisplacementLayer::tile_enabled is false. +enum class TextureTileMethod : int +{ + Repeat = 0, // wrap around, tile i and tile i+1 are identical (default) + MirroredRepeat = 1, // wrap around, every other tile is mirrored (no visible seam at tile edges) +}; + +// How a layer's texture is mapped onto the mesh. +enum class TextureProjectionMethod : int +{ + // Standard *blended* tri-planar projection: the texture is sampled once per world axis (the + // XY, XZ and YZ planes) and the three samples are blended per vertex, weighted by that + // vertex's own normal raised to TRIPLANAR_BLEND_SHARPNESS. + // + // Earlier versions instead *hard-picked* the single axis most aligned with the normal. That + // has a real, visible failure mode at any edge where the dominant axis flips: on a +X face the + // planar coordinate is (y, z), on a -Y face it is (x, z), so at the shared edge u jumps from + // y_edge to x_edge. On a box centred near the origin those two agree at the (+,+) and (-,-) + // corners (making them look fine) but differ by the full corner width at the (+,-) and (-,+) + // corners, which is exactly the "two bad corners, two good ones" seam that was reported. + // Blending across the transition removes that hard discontinuity by construction. + Triplanar = 0, + // Wrapped around an axis running through the patch's centroid. The axis itself is picked + // automatically as the world axis *least* aligned with the patch's average normal (since a + // cylinder's own axis is perpendicular to its outward radial normal) - a reasonable default + // for roughly cylindrical selections, not a precise fit for arbitrary geometry. + Cylindrical = 1, + // Wrapped around the patch's centroid using longitude/latitude - reasonable for roughly + // spherical/rounded selections, again an approximation rather than an exact geodesic map. + Spherical = 2, + // Real UV unwrap of the painted patch - a proper low-distortion flattening rather than a + // planar/cylindrical/spherical approximation. The patch is first cut into charts along its + // sharp edges and each chart is flattened on its own (see compute_patch_unwrap()), so a patch + // that is not a single developable surface still unwraps sensibly. Falls back to Triplanar for + // any chart that cannot be flattened at all. + LSCM = 3, + // Flat projection along a fixed direction captured from the 3D camera ("project from view"): the + // texture is laid onto the painted area as seen from that angle, like a decal projector. Single + // planar map (no per-face axis switch), so it can smear on faces turned away from the projector - + // that is inherent to view projection and is the user's call, not a bug. The projector's two + // in-plane axes live in TextureDisplacementLayer::view_project_right/up. + ViewProjected = 4, +}; + +// Dihedral angle (degrees) above which an edge between two painted triangles becomes a chart seam +// - i.e. the unwrap is cut there rather than being forced to flatten across it. +// +// The whole point of this being a threshold rather than "flatten everything as one piece": three +// faces meeting at a cube corner are not developable, so a single-chart solve has to distort them +// badly to lie flat (they splay out into a fan, which is what "it merges all the edges into a +// triangle" describes). Cutting at the 90-degree edges instead lets each face flatten exactly. +// Meanwhile a smoothly curved surface - a subdivided sphere, say - has only small angles between +// neighbouring triangles, stays a single chart, and unwraps as one piece the way it should. +static constexpr float LSCM_DEFAULT_SEAM_ANGLE_DEG = 30.f; + +// Exponent the tri-planar blend weights are raised to (see TextureProjectionMethod::Triplanar). +// Higher means a tighter, more "hard-edged" transition between the three axis projections; lower +// means a wider cross-fade. 4 is the usual default: tight enough that a flat face is sampled +// almost purely along its own axis, wide enough that a 90-degree edge has no visible hard seam. +static constexpr float TRIPLANAR_BLEND_SHARPNESS = 4.f; + +// How a layer's displacement combines with the displacement accumulated by the layers below it +// (i.e. those in lower slots), evaluated per vertex. Analogous to an image editor's layer blend +// modes, except the quantity being blended is a signed displacement distance in mm rather than a +// pixel value. +// +// Add/Subtract are in mm and need no further explanation. Multiply/Divide are *scaling* operations +// and therefore need a unit convention: they treat the layer's own value as a unitless factor +// relative to 1 mm. That makes `depth_mm` act as a gain - a layer with depth 1 mm and a white +// (1.0) texel multiplies the accumulated relief by exactly 1, i.e. leaves it unchanged - which is +// the behaviour that makes a Multiply layer usable as a mask over the layers beneath it. +enum class TextureBlendMode : int +{ + Add = 0, // acc + value (default; several layers pile their relief up together) + Subtract = 1, // acc - value (carve this layer's relief out of the layers below) + Multiply = 2, // acc * (value / 1mm) (mask/modulate the layers below by this layer) + Divide = 3, // acc / (value / 1mm) (inverse mask; guarded against a zero/near-zero divisor) +}; + +// Combines one layer's signed displacement `value` (mm) into `accumulated` (mm) per `mode`. +// Shared by the bake/preview path and exposed for tests. +float blend_displacement(float accumulated, float value, TextureBlendMode mode); + +// Where one unwrap island (chart) sits in UV space, on top of wherever compute_patch_unwrap() first +// packed it. This is what the UV editor's drag/rotate gestures write to, so a user can lay the +// islands out by hand - move them, rotate them, overlap them - rather than being stuck with the +// automatic packing. +// +// Indexed by chart id, which compute_patch_unwrap() assigns in first-encountered-triangle order. That +// is stable for a given patch and seam angle, but *not* across a change to either: repainting the +// patch, or moving the seam-angle slider, can renumber the charts and so leave a hand-placed island +// applied to a different one. Accepted deliberately - the alternative is a persistent chart identity +// that survives arbitrary re-segmentation, which is a much larger problem than this feature warrants. +struct TextureIsland +{ + Vec2f offset = Vec2f::Zero(); // in the unwrap's own mm space + float rotation_deg = 0.f; // about the island's own centroid + // About the island's own centroid too. 1 = the size compute_patch_unwrap() gave it, which is + // already its true surface area in mm - so scaling an island away from 1 deliberately makes its + // texel density differ from its neighbours'. See average_island_scales(). + float scale = 1.f; + + template void serialize(Archive &ar) { ar(offset, rotation_deg, scale); } +}; + +// Sets every island's scale to the mean of the current ones (Blender's "Average Islands Scale"). +// Only meaningful after islands have been scaled by hand: compute_patch_unwrap() already sizes every +// chart to its true mm area, so a freshly unwrapped patch has uniform texel density to begin with. +void average_island_scales(std::vector &islands); + +// One texture asset plus its projection/displacement parameters. Several layers may be painted +// onto overlapping areas of the same volume: their displacements are combined per vertex, in slot +// order, each layer folding into the total via its own TextureBlendMode (see +// build_texture_displacement()). This is what "layered/blended" texture displacement means here. +struct TextureDisplacementLayer +{ + // Index into ModelVolume::texture_displacement_facets, assigned once when the layer is + // created. Not reused for the lifetime of the ModelVolume, so a deleted layer's slot simply + // becomes unused rather than being handed to a different layer. + int slot = -1; + + std::string name; + // Path on the local filesystem the image was loaded from (informational; may be stale or + // empty, e.g. after loading a .3mf on a different machine). + std::string path; + // Path inside the .3mf archive once saved (empty until the project is saved once). + std::string path_in_3mf; + // Raw encoded image bytes. Only 8-bit grayscale PNG is understood by decode_height_texture() + // (libslic3r has no GUI image toolkit available); the GUI converts any imported image to that + // format before storing it here, so the baking code never needs to depend on wxWidgets. + std::shared_ptr> image_data; + + float depth_mm = 0.4f; // maximum displacement along the surface normal, in mm + float tiling_scale = 12.5f; // size of one texture tile, in mm + float rotation_deg = 0.f; + Vec2f offset = Vec2f::Zero(); + bool invert = false; + + // The height value that means "don't move this vertex". The sampled height (0..1) has this + // subtracted before being scaled by depth_mm, so with the default of 0 the surface only ever + // moves *outwards* (the classic height-map convention), while 0.5 makes mid-grey neutral and + // lets darker texels cut *into* the surface - an engraved-and-embossed result from one map. + // + // Cutting inward is not free: vertices move along their own normals, which converge inside a + // concave corner and inside a thin wall, so a large depth_mm against a small feature really can + // fold the surface through itself. There is no cheap way to detect that here (it needs a full + // self-intersection test on the displaced mesh), so the GUI warns rather than promising safety. + float midlevel = 0.f; + + // Optional blur applied to the decoded height map before it is sampled, in [0, 1]: 0 is the raw + // texture, 1 the strongest blur. Softens the relief (rounds hard edges, removes speckle) without + // needing a pre-blurred source image. Applied in decode_height_texture(), so it feeds the true + // preview, the UV editor backdrop and the bake identically. + float smoothing = 0.f; + + // Optional feathering of the displacement toward the edge of the painted patch. When enabled, the + // displacement is scaled down as a vertex approaches the patch boundary, so the relief blends + // smoothly into the surrounding surface instead of ending abruptly. `edge_smoothing_amount` in + // (0, 1] sets how far the fade reaches into the patch: small values only soften a thin band at the + // very edge, 1 fades the whole patch to nothing (the painted face comes out flat). Off by default. + bool edge_smoothing = false; + float edge_smoothing_amount = 0.5f; + + // Only used by TextureProjectionMethod::LSCM: when set, a fresh unwrap is laid out as a connected + // net (adjacent charts unfolded edge-to-edge along a spanning tree, see compute_connected_net()) + // rather than as separately packed islands. On by default. Hand-moving an island overrides its + // placement until the next re-unwrap. + bool auto_connect_islands = true; + + // When false, the texture is sampled once (clamped to its edge pixels outside [0, 1)) instead + // of being repeated - useful for a single decal-like placement rather than a repeating tile. + bool tile_enabled = true; + TextureTileMethod tile_method = TextureTileMethod::Repeat; + + TextureProjectionMethod projection_method = TextureProjectionMethod::Triplanar; + // Only used by TextureProjectionMethod::LSCM. See LSCM_DEFAULT_SEAM_ANGLE_DEG. + float lscm_seam_angle_deg = LSCM_DEFAULT_SEAM_ANGLE_DEG; + // Only used by TextureProjectionMethod::LSCM: gap left between islands by the automatic packing, + // in the unwrap's mm space. Negative means "auto" (a small fraction of the packed size), which is + // what a patch that has never had the slider touched gets. + float island_padding_mm = -1.f; + // Only used by TextureProjectionMethod::LSCM: edges the unwrap is forced to cut along, on top of + // whatever the seam angle already cuts. Each pair is an undirected edge in *mesh vertex index* + // space (first < second). This is what "mark seam" (manual) and "cut island" (auto) both write to. + // Mesh-index space, so like the paint masks these are dropped on any topology change. + std::vector> lscm_seam_edges; + + // Only used by TextureProjectionMethod::ViewProjected: the projector's in-plane axes, in the + // volume's *local* space, captured from the camera when the user hits "Project from view". A point + // projects to Vec2f(dot(pos, right), dot(pos, up)) before the usual tiling/rotation/offset. + Vec3f view_project_right = Vec3f::UnitX(); + Vec3f view_project_up = Vec3f::UnitY(); + + // Also ViewProjected, and takes precedence over the two axes above when set: an exact *projective* + // map from a local-space position straight to a texture uv, written by the projection-frame overlay + // (the semi-transparent window dragged over the 3D view - its border becomes the uv unit square). + // + // Row-major 3x4, applied to the homogeneous point p~ = (x, y, z, 1): + // uv = ( row0.p~ / row2.p~ , row1.p~ / row2.p~ ) + // The perspective divide is the whole point. view_project_right/up can only express an *affine* + // projection, which matches an orthographic camera exactly but not a perspective one - under + // perspective the near end of a part projects larger than the far end, and no pair of axes + // reproduces that. Folding the camera's full projection*view*model product into one matrix does. + // Because a point behind the projector has row2.p~ <= 0 and no meaningful uv, sampling must check + // the sign rather than divide blindly; see project_uv_projective(). + // + // Note this map already includes placement, so the usual tiling/rotation/offset transform is NOT + // applied on top of it - the window's own position and size are the placement. + bool view_project_projective = false; + std::array view_project_matrix{}; + // Only used by TextureProjectionMethod::LSCM: hand placement of the unwrap's islands, indexed by + // chart id (see TextureIsland). Shorter than the chart count simply means the missing ones are + // still where the automatic packing put them. + std::vector islands; + + // Only used by TextureProjectionMethod::LSCM: persistent "join" groups, indexed by chart id. Charts + // that share a group id move together as one in the UV editor - this is what the explicit "Join" + // command records (over and above placing the child next to its parent). An entry of -1, or an index + // past the end of the vector, means the chart is its own singleton group (moves alone). Empty means + // every chart is a singleton. Same chart-renumbering caveat as `islands`: a re-unwrap can reshuffle + // chart ids, so this is meaningful only against the unwrap it was made on. + std::vector island_groups; + + // Only used by TextureProjectionMethod::LSCM: manual UV edits made in the UV editor's Vertex/Edge + // select modes. Each pair is (key, its overriding raw-unwrap coordinate in mm) - the *raw* unwrap + // position, i.e. before the island transform, so the edited vertex still moves and rotates with its + // island. The key names what is edited (see apply_lscm_uv_overrides()): + // - negative: one unwrapped vertex of the current unwrap, as lscm_uv_override_key(index). This is what + // the editor stores, so a seam vertex dragged in one island leaves its copies in the neighbouring + // islands where they are. Like `islands`, meaningful only against the unwrap it was made on. + // - zero or positive: a mesh vertex, every unwrapped copy of it (how edits were stored before). + std::vector> lscm_uv_overrides; + + // How this layer folds into the displacement accumulated by the layers below it. Ignored for + // the lowest-slot painted layer, which has nothing beneath it to combine with (the GUI shows + // it as the "Base" layer and hides the control). + TextureBlendMode blend_mode = TextureBlendMode::Add; + + // Colour this layer's painted area from the texture's own colours, on top of displacing by its + // height. Only meaningful when the texture actually has colour (DecodedHeightTexture::has_color()): + // the shipped library is grayscale, so this does nothing there. + // + // Colour lands in the volume's mmu_segmentation_facets - the same per-triangle filament assignment + // the MMU paint gizmo writes - so its resolution is the *mesh's*, not the image's, and a triangle + // gets exactly one filament. That is why the adaptive subdivision has a colour criterion of its + // own (see subdivide_mesh_adaptive()): without triangles along a colour boundary there is nothing + // for the boundary to be drawn on. + bool color_enabled = false; + + bool empty() const { return !image_data || image_data->empty(); } + + template void save(Archive &ar) const + { + std::string blob = image_data ? std::string(image_data->begin(), image_data->end()) : std::string(); + ar(slot, name, path, path_in_3mf, blob, depth_mm, tiling_scale, rotation_deg, offset, invert, tile_enabled, + static_cast(tile_method), static_cast(projection_method), lscm_seam_angle_deg, islands, + static_cast(blend_mode), midlevel, island_padding_mm, lscm_seam_edges, view_project_right, + view_project_up, smoothing, edge_smoothing, edge_smoothing_amount, auto_connect_islands, island_groups, + lscm_uv_overrides, view_project_projective, view_project_matrix, color_enabled); + } + template void load(Archive &ar) + { + std::string blob; + int tile_method_int = 0; + int projection_method_int = 0; + int blend_mode_int = 0; + ar(slot, name, path, path_in_3mf, blob, depth_mm, tiling_scale, rotation_deg, offset, invert, tile_enabled, + tile_method_int, projection_method_int, lscm_seam_angle_deg, islands, blend_mode_int, midlevel, + island_padding_mm, lscm_seam_edges, view_project_right, view_project_up, smoothing, edge_smoothing, + edge_smoothing_amount, auto_connect_islands, island_groups, lscm_uv_overrides, view_project_projective, + view_project_matrix, color_enabled); + image_data = blob.empty() ? nullptr : std::make_shared>(blob.begin(), blob.end()); + tile_method = static_cast(tile_method_int); + projection_method = static_cast(projection_method_int); + blend_mode = static_cast(blend_mode_int); + } +}; + +// How a *mixed* palette entry - one that names two filaments rather than one - is turned into real +// per-facet paint. An MMU extrudes one filament at a time, so an intermediate colour exists only by +// interleaving two of them finely enough that the eye does the blending. +enum class ColorMixMode : int +{ + // Horizontal bands: which of the two filaments a point takes depends on its height, so + // consecutive print layers alternate. This is how filament-blend prints actually work, and on a + // vertical-ish surface it reads as a genuinely smooth colour. On a near-horizontal surface a whole + // layer is one band, so the blend disappears - that is what XYDither is for. + ZBands = 0, + // An ordered (Bayer) checkerboard across the surface, at any orientation. Independent of layer + // height, but its cell is around the size of one facet, so a fine mix can read as texture rather + // than as a clean blend. + XYDither = 1, + // Per triangle, by its orientation: bands where the surface is upright enough for consecutive + // layers to alternate, the checkerboard where it faces up or down and a layer would be one band. + // The default - a flat-topped part with a mix on top gets no blend at all from bands alone. + Auto = 2, +}; + +// Settings that apply to the whole layer stack rather than to one layer, held per ModelVolume next +// to texture_displacement_layers and consumed by build_texture_displacement(). +struct TextureDisplacementOptions +{ + // Whether the painted patch's *border* vertices - the ones also used by unpainted triangles - + // are displaced along with the rest, or pinned flat. + // + // Pinning them was originally justified as keeping the patch from tearing away from the + // surrounding surface. That reasoning no longer applies: since the bake became + // topology-preserving it only ever *moves* the input's own vertices, so a border vertex is one + // vertex shared by both regions and moving it simply tilts the unpainted triangles that use it - + // nothing can come apart. What pinning actually does is clamp the outermost ring of the relief to + // zero, which on a fully painted face collapses the pattern into a ring of steep ramps right at + // the edge (the "it doesn't extrude at the border" artifact). Displacing it is the default; + // pinning is kept for the case where the relief must not spill past the paint at all. + bool displace_border = true; + + // Optional Laplacian relaxation of the displaced surface, run after all layers have been folded + // in - a post-process, not a texture filter (TextureDisplacementLayer::smoothing blurs the height + // map instead, before it is ever sampled). Rounds off the hard steps a bitmap height map leaves + // behind. Restricted to vertices the displacement actually moved, so the rest of the model keeps + // its exact geometry. `smooth_strength` in [0, 1] is how far each pass moves a vertex toward the + // average of its neighbours. + bool smooth_enabled = false; + float smooth_strength = 0.3f; + int smooth_iterations = 2; + + // Hold the painted patch's outermost ring of vertices out of the smoothing. Those vertices sit + // next to unpainted ones that are pinned by definition, so relaxing them drags the rim of the + // relief back down toward the undisplaced surface - the pattern looks half-melted exactly where it + // meets the edge, however crisp the rest of it is. Excluding them keeps the border extruded at + // full depth and smooths only the interior. On by default; turn it off to soften the outer edge + // deliberately (which is a blunter version of the per-layer edge-smoothing falloff). + bool smooth_skip_border = true; + + // Which bake pipeline. On (the default): refine, remove slivers, displace and simplify in one run, + // nothing to prepare first. Off, the classic path: the mesh is prepared first (remesh, adaptive + // subdivision, step cut) and then displaced vertex by vertex, keeping the topology - which is what + // colour needs, since the per-facet assignment has nothing stable to attach to once the topology is + // rebuilt. Projects saved with the classic path keep it: the flag is stored per volume. + bool pipeline_v2 = true; + // Refinement edge length, mm. 0 (the default) means automatic: chosen from the texture's texel + // size and sharpness and the model's size, see recommend_v2_resolution(). A saved project with an + // explicit value keeps it. + float v2_refine_mm = 0.f; + bool v2_regularize = false; + // Simplification target in thousands of triangles. -1 (the default) means automatic, from the + // same recommendation; 0 skips simplification, which is worth comparing on its own. + int v2_max_triangles_k = -1; + // Slide vertices onto the texture's own edges before displacing. Displacement moves vertices along + // the normal only, so without this a step in the image is reproduced wherever the triangle grid + // happens to fall, as a staircase rather than a straight wall. + bool v2_relocate = false; + // Data-dependent edge flips before displacement (see TextureBakeFlip.hpp). On by default and not a + // user setting; deliberately left out of serialize() so project files are unaffected. + bool v2_flip_edges = true; + + // Colour, all of which belongs to the stack rather than to any one layer: it is about how the + // printer will realise the colours, not about which image they came from. + + // Interleave pairs of filaments to get colours between them - so four loaded filaments offer far + // more than four colours. Whether a given layer's colours actually use mixes is decided from its + // image (TextureDetail::flat_colors): a texture of flat colours prints in single filaments, a + // photograph or gradient in mixes. Off forces single filaments everywhere. + bool color_mix_enabled = true; + ColorMixMode color_mix_mode = ColorMixMode::Auto; + // Majority-filter passes over the assigned colours. See TextureColorRequest::despeckle_passes - + // this is the control for it, and 2 is enough to clear the salt-and-pepper an image with detail + // finer than the mesh leaves behind, without eating features that are genuinely a facet wide. + int color_despeckle = 2; + + template void serialize(Archive &ar) + { + int mix_mode = int(color_mix_mode); + ar(displace_border, smooth_enabled, smooth_strength, smooth_iterations, smooth_skip_border, + pipeline_v2, v2_refine_mm, v2_regularize, v2_max_triangles_k, + v2_relocate, color_mix_enabled, mix_mode, color_despeckle); + color_mix_mode = ColorMixMode(mix_mode); + } +}; + +// How much detail a height texture carries: central differences of the grey image, the mean gradient +// and the share of texels steeper than 30 grey levels, mapped to how many texels one mesh edge may +// span (1 for a hard-edged image, 4 for a smooth one). Cached per image, like the decode. +struct TextureDetail +{ + float mean_gradient = 0.f; + float sharp_fraction = 0.f; + float pixels_per_edge = 4.f; + // How much of the image its eight most common colours cover (8 levels per channel), and the + // verdict: a "flat-colour" image (tiles, logos, camouflage) whose colours should each print in a + // single filament, versus a photograph or gradient where interleaved filament mixes pay off. + float flat_share = 0.f; + bool flat_colors = false; +}; +TextureDetail analyze_texture_detail(const TextureDisplacementLayer &layer); + +// The default pipeline's automatic resolution and budget, when the options leave them at "auto": +// edge = the model's world-space diagonal / 250, clamped to [0.05, 5] mm and rounded up to 0.01; +// budget 750 k. The texel size of the finest layer and its sharpness class are +// reported alongside for the panel. `edge_mm` is 0 for an empty mesh. +struct V2Resolution +{ + float edge_mm = 0.f; + int budget_k = 0; + float texel_mm = 0.f; + float pixels_per_edge = 0.f; + bool budget_bound = false; // the edge came from the triangle cap, not from the texture +}; +V2Resolution recommend_v2_resolution(const indexed_triangle_set &mesh, + const std::vector &layers, + const Transform3d &volume_to_world = Transform3d::Identity()); + +// Decoded height (and, for a colour source image, colour) samples, independent of any GUI/OpenGL +// texture object so they can be evaluated from a background bake Job as well as from GUI-side +// preview code. +struct DecodedHeightTexture +{ + std::vector pixels; // height: row-major, top-to-bottom, one byte per pixel + // Colour: the same grid, three bytes per pixel, or empty when the source image was grayscale. + // A grayscale height map has no colour to give - `pixels` is not a colour, it is a height - so + // has_color() is what the whole colour feature keys off: a layer set to colour a model with a + // grayscale texture on it simply colours nothing. + std::vector rgb; + int width = 0; + int height = 0; + + bool empty() const { return width <= 0 || height <= 0 || pixels.empty(); } + bool has_color() const { return !empty() && rgb.size() == size_t(width) * size_t(height) * 3; } + // Bilinearly sampled height in [0, 1] at a normalized uv coordinate. When tile_enabled is false, + // a uv outside [0, 1) samples as 0 - the texture simply is not there, rather than its border + // row/column being smeared outward forever (which is what clamping the coordinate would do, and + // was a real reported bug). Callers rely on this to get a hard edge: it is how the projection + // frame's border becomes the edge of the displacement. + float sample(const Vec2f &uv, bool tile_enabled = true, TextureTileMethod tile_method = TextureTileMethod::Repeat) const; + // The same sample, in colour: linear RGB components in [0, 1]. Outside a non-tiled placement, and + // for a grayscale source, this is (0, 0, 0) - callers pair it with has_color() and with the + // height's own coverage rather than trying to read "no texture here" out of the colour itself. + Vec3f sample_color(const Vec2f &uv, bool tile_enabled = true, + TextureTileMethod tile_method = TextureTileMethod::Repeat) const; + + // Where a uv lands on the texel grid: the four texels of the bilinear tap and their weights. + // Shared by sample() and sample_color(), so a layer's height and its colour can never end up + // read from different places in the image. False means the uv is outside a non-tiled placement - + // no texture there at all (see sample()). + struct TexelTap + { + int x0 = 0, y0 = 0, x1 = 0, y1 = 0; + float tx = 0.f, ty = 0.f; + }; + bool texel_tap(const Vec2f &uv, bool tile_enabled, TextureTileMethod tile_method, TexelTap &out) const; +}; + +// Decode a layer's raw image bytes into sampleable height data, plus colour when the source has any. +// Both 8-bit grayscale PNGs (the shipped library, and anything imported before colour was kept) and +// colour PNGs are accepted; for a colour source the height is its luminance, using the same +// coefficients wxImage::ConvertToGreyscale() uses, so a texture imported as colour displaces exactly +// as it did when the importer flattened it to grey on the way in. Returns an empty +// DecodedHeightTexture if image_data is empty or is not a PNG at all. +DecodedHeightTexture decode_height_texture(const TextureDisplacementLayer &layer); + +// Maps a linear RGB colour in [0, 1] to an index into the caller's palette, or -1 for "no colour". +// +// Deliberately a callback rather than a function here: matching a colour to a filament is a +// *perceptual* question (CIEDE2000 over CIELAB), and that machinery - slic3r/Utils/ColorSpaceConvert +// and GuiColor - lives on the GUI side along with the list of filaments actually loaded. libslic3r +// samples the image and decides *where* colour changes; the GUI decides *which* filament each colour +// is. See GLGizmoTextureDisplacement::make_palette_quantizer(). +using ColorQuantizeFn = std::function; + +// Resolves a palette index plus a surface position to the filament index that position should print +// in. A pure entry ignores the position; a mixed one interleaves its two filaments per ColorMixMode. +// +// Deliberately separate from ColorQuantizeFn, and deliberately *not* used by the subdivision's colour +// criterion: that criterion asks where the **perceived** colour changes, and must not see the +// interleaving. Refining on every band or dither-cell boundary would spend the whole triangle budget +// drawing a pattern the eye is supposed to blend away. +using ColorResolveFn = std::function; + +// One printable colour: either a loaded filament on its own, or a blend of two of them realised by +// interleaving (see ColorMixMode). Plain data, so it can be captured into a background job. +struct PrintableColor +{ + Vec3f rgb = Vec3f::Zero(); // what it looks like; for a mix, the perceptual average of the two + int a = 0; // filament index + int b = 0; // the second filament; == a for a pure entry + int num = 1; // a's share of the interleave, out of `den` + int den = 1; + bool is_mix() const { return a != b; } +}; + +// Everything needed to colour a mesh, captured on the main thread and handed to a job. An empty +// palette means nothing is colouring, which is the state every one of these paths starts in. +struct TextureColorSettings +{ + std::vector palette; + std::vector palette_pure; // the filaments alone, for flat-colour images + ColorMixMode mix_mode = ColorMixMode::ZBands; + float layer_height = 0.2f; // sizes the Z bands + float dither_cell_mm = 0.4f; // sizes the XY dither cells + int despeckle_passes = 2; + + bool empty() const { return palette.empty(); } +}; + +// Raw dominant-axis planar projection of `position` (in mm, not yet scaled/rotated/offset by any +// layer), dropping the axis position that best aligns with `normal`. Exposed on its own (rather +// than only inline inside project_texture_displacement_uv()) so GUI code - the on-canvas +// "adjust texture placement" gizmo - can map a dragged 3D point into the exact same 2D space +// tiling_scale/rotation_deg/offset operate in, without duplicating the axis-selection logic. +Vec2f project_planar(const Vec3f &position, const Vec3f &normal); + +// Applies a layer's tiling_scale/rotation_deg/offset to an already-projected planar coordinate +// (in mm, dominant-axis planar, cylindrical, spherical, or CGAL LSCM output - any of them, all +// share this same final step). Exposed separately so build_texture_displacement() can route CGAL +// LSCM's per-patch UV solve through the same scale/rotate/offset controls as every other +// projection method, without going through project_texture_displacement_uv()'s own dispatch +// (which only knows how to compute the *analytic* methods from a single vertex + normal). +// `aspect` is the height map's width / height. It scales the v axis so a non-square image is not +// squeezed into a square tile: `tiling_scale` is the tile's size along u, and the tile is +// `tiling_scale * height / width` mm along v, which keeps texels square. 1 (the default) is the +// square case and leaves the coordinate exactly as it always was. +Vec2f apply_uv_transform(const Vec2f &planar, const TextureDisplacementLayer &layer, float aspect = 1.f); + +// Applies a row-major 3x4 projective matrix (see TextureDisplacementLayer::view_project_matrix) to a +// local-space point, writing the resulting texture uv. Returns false - and leaves `uv` untouched - +// when the point lies behind the projector or on its plane (w <= 0), where there is no meaningful uv +// and dividing would produce a mirrored or infinite coordinate. Callers treat that as "no height". +bool project_uv_projective(const std::array &m, const Vec3f &position, Vec2f &uv); + +// Sample a layer's height texture at a mesh-local position, honouring the layer's projection +// method, tiling scale, rotation, offset and tiling mode. Returns a height in [0, 1]. +// +// This returns a *height* rather than a UV because TextureProjectionMethod::Triplanar is a blend +// of three separate axis projections and therefore takes three texture samples per vertex - there +// is no single UV that represents it. The other methods do map to one UV internally. +// - `normal` is this specific vertex's own normal; used only by Triplanar (for its blend weights). +// - `patch_center`/`patch_axis` describe the painted patch as a whole (its centroid, and - for +// Cylindrical only - the wrap axis); used only by the Cylindrical/Spherical methods. +// - `lscm_uv`, when non-null, is this vertex's precomputed LSCM coordinate and takes precedence +// over `layer.projection_method` (LSCM is a single per-patch solve, not a per-vertex formula, +// so build_texture_displacement() computes it once up front and passes it in here). +// patch_center/patch_axis are cheap to compute once per patch and passed through unchanged for +// every vertex rather than being re-derived per call. +float sample_layer_height(const DecodedHeightTexture &texture, const TextureDisplacementLayer &layer, + const Vec3f &position, const Vec3f &normal, + const Vec3f &patch_center = Vec3f::Zero(), const Vec3f &patch_axis = Vec3f::UnitZ(), + const Vec2f *lscm_uv = nullptr); + +// The same sample, in colour, through the identical projection/tiling/placement path - so a layer's +// colour lands on the model exactly where its relief does, whatever projection it is using. Returns +// false (leaving `out` untouched) when the texture has no colour, or when the point falls outside a +// non-tiled placement, or behind a projective "from view" projector: all three mean "this layer does +// not colour this point", which is different from "this layer colours it black". +bool sample_layer_color(const DecodedHeightTexture &texture, const TextureDisplacementLayer &layer, + const Vec3f &position, const Vec3f &normal, Vec3f &out, + const Vec3f &patch_center = Vec3f::Zero(), const Vec3f &patch_axis = Vec3f::UnitZ(), + const Vec2f *lscm_uv = nullptr); + +// Area-weighted centroid and average normal of a layer's currently painted patch, in mesh-local +// coordinates - the same measurements build_texture_displacement() uses to pick its dominant +// projection axis. Used by the GUI to anchor the on-canvas "adjust texture placement" gizmo to +// wherever the layer is actually painted. Returns false (leaving the outputs untouched) if the +// layer has nothing painted yet. +bool compute_layer_paint_anchor(const indexed_triangle_set &base_mesh, + const TriangleSelector::TriangleSplittingData &facet_data, + Vec3f &anchor_pos, + Vec3f &anchor_normal); + +// Extracts the currently painted patch from a volume's base mesh + stored facet data - the same +// extraction build_texture_displacement() and compute_layer_paint_anchor() each do internally via +// TriangleSelector::get_facets_strict(ENFORCER). Returns an empty mesh if nothing is painted. +// Exposed so GUI code (the LSCM "UV editor" preview pane) can get the same patch build_texture_ +// displacement() would act on, without duplicating the deserialize/get_facets_strict boilerplate. +indexed_triangle_set extract_painted_patch(const indexed_triangle_set &base_mesh, + const TriangleSelector::TriangleSplittingData &facet_data); + +// A patch flattened into 2D. The patch is first split into charts along edges sharper than +// `seam_angle_deg` (see LSCM_DEFAULT_SEAM_ANGLE_DEG), each chart is flattened independently, the +// charts are scaled to their true mm size and packed side by side. +// +// A vertex sitting on a seam belongs to several charts at once and therefore has a *different* UV +// in each of them, so this cannot be a plain "one UV per patch vertex" array: seam vertices are +// duplicated, once per chart touching them. `indices` is the patch's own triangle list re-indexed +// onto that duplicated vertex set, and `source_vertex` maps each duplicate back to the patch vertex +// it came from. +struct PatchUnwrap +{ + std::vector uvs; // one per unwrapped vertex, in mm + std::vector source_vertex; // unwrapped vertex -> index into patch.vertices + std::vector vertex_chart; // unwrapped vertex -> chart (island) id + // The patch's triangles re-indexed into `uvs` - but *grouped by chart*, not left in the patch's + // own order: the charts are flattened one at a time and then concatenated. `source_face` is the + // map back, so anything that needs UVs per triangle corner (as opposed to per vertex) can place + // them against its own triangle list. See compute_lscm_corner_uvs(). + std::vector indices; + std::vector source_face; // unwrapped triangle -> index into patch.indices + // Per chart, the centroid of its uvs - the point a TextureIsland's rotation turns about. + std::vector chart_centroid; + // Edges belonging to exactly one triangle: the outline of each island. Indices into `uvs`. This + // is what the UV editor draws highlighted, so the boundaries the seam angle cut are visible. + std::vector> boundary_edges; + int chart_count = 0; + + bool empty() const { return indices.empty(); } +}; + +// Applies an island's hand placement (scale + rotation about its own centroid, then offset) to one +// unwrapped UV. A chart with no entry in `islands` is left exactly where the packing put it. +Vec2f apply_island_transform(const Vec2f &uv, int chart, const PatchUnwrap &unwrap, const std::vector &islands); + +// The same transform as a 2x3 affine matrix (columns: x basis, y basis, translation), for callers +// that would otherwise apply it to every vertex of an island one at a time. The UV editor renders +// each island through this as a uniform, which is what lets a drag move an island without touching +// its vertex buffer at all. +Eigen::Matrix island_transform_matrix(int chart, const PatchUnwrap &unwrap, const std::vector &islands); + +// Lays the unwrap's charts out as connected nets: charts that share a mesh edge are unfolded so +// their shared edge coincides (a cube -> its six faces joined along a spanning tree of edges, the rest +// left as free borders). Charts stay separate islands, so their borders still show and any of them can +// still be moved by hand afterwards. Each net grows from the largest chart not yet placed; a chart whose +// triangles would overlap the net stays out of it and starts a net of its own. The nets are then packed +// side by side. Returns one placement per chart. See the gizmo's auto-connect option. +std::vector compute_connected_net(const PatchUnwrap &unwrap); + +// The placement that unfolds `child` onto `parent` along their shared mesh edge, honouring `parent`'s +// current placement in `islands`. Returns false if the two charts share no edge. Backs the manual +// "Join" command; compute_connected_net() does the same thing across a whole spanning tree. +bool join_chart_placement(const PatchUnwrap &unwrap, const std::vector &islands, + int child, int parent, TextureIsland &out_child); + +// Unwraps `patch` as described above. Charts that are flat (within a degree) are projected onto +// their own tangent plane directly, which is both exact and far cheaper than a solve; only genuinely +// curved charts go through CGAL's LSCM parameterizer (MeshBoolean::cgal::parameterize_lscm()). A +// chart that LSCM cannot flatten at all (it is not a topological disk - closed, or with a hole) +// falls back to that same tangent-plane projection. +// +// `padding_mm` is the gap the packing leaves between islands; negative means auto (see +// TextureDisplacementLayer::island_padding_mm). `seam_edges` are extra edges to cut along regardless +// of angle (manual/auto seams), in the patch's own vertex-index space (which is the mesh's, since the +// patch carries the whole vertex array - see get_facets_strict()). +// +// Results are cached, keyed on the patch's geometry, the seam angle, the padding and the seam edges: +// nothing else about a layer (depth, tiling, rotation, offset, texture, island placement) changes the +// unwrap, so dragging any of those sliders must not pay for a re-solve. +PatchUnwrap compute_patch_unwrap(const indexed_triangle_set &patch, float seam_angle_deg = LSCM_DEFAULT_SEAM_ANGLE_DEG, + float padding_mm = -1.f, const std::vector> &seam_edges = {}); + +// One UV per patch vertex, **for displacement only**. Displacement is inherently per-vertex - a +// vertex has exactly one position, so it can only be pushed out by one height - which means a seam +// vertex has to settle on a single one of its charts' UVs (the first, arbitrarily). That is not a +// compromise in the result: the surface stays watertight either way, since neighbouring vertices +// each move along their own normals and nothing depends on the UVs agreeing across the seam. +// +// Anything that samples or draws per *triangle* must use compute_lscm_corner_uvs() instead. This +// collapse is wrong for those: a triangle at a seam that the island layout did not join gets handed +// a neighbouring island's placement, which showed up as a single skewed triangle per face and as +// every island's texture following the lowest-numbered island when it was dragged. +// +// Returns an empty vector if the patch has no triangles. Takes the whole layer because it applies +// both the layer's seam angle and its hand-placed islands. +std::vector compute_lscm_uvs(const indexed_triangle_set &patch, const TextureDisplacementLayer &layer); + +// Three UVs per patch triangle (corner 0, 1, 2 of triangle i at index 3i..3i+2), in the patch's own +// triangle order. Unlike compute_lscm_uvs() this keeps a seam vertex's separate per-chart copies: a +// triangle belongs to exactly one chart and is given that chart's UVs, which is what every consumer +// that works per triangle rather than per vertex needs - the fast preview's flat mesh, the checker +// overlay and the bake's per-facet colour. +// +// Returns an empty vector if the patch has no triangles or the unwrap carries no source_face map. +std::vector compute_lscm_corner_uvs(const indexed_triangle_set &patch, const TextureDisplacementLayer &layer); + +// The TextureDisplacementLayer::lscm_uv_overrides key for one unwrapped vertex (an index into PatchUnwrap::uvs). +inline int lscm_uv_override_key(int unwrapped_vertex) { return -(unwrapped_vertex + 1); } + +// Writes the overrides into `unwrap.uvs`: mesh-vertex keys onto every copy of their vertex, then unwrapped-vertex +// keys onto their one copy. Returns, per unwrapped vertex, whether an override set it. +std::vector apply_lscm_uv_overrides(PatchUnwrap &unwrap, const std::vector> &overrides); + +// One paint mask (as stored by ModelVolume::texture_displacement_facets) per possible layer slot. +using TextureDisplacementFacetsData = std::array; + +// Bake all painted texture-displacement layers into `base_mesh`'s geometry, restricted to the +// painted area(s) only (the rest of the mesh is left untouched). Returns the mesh unchanged if +// nothing is painted or no layer has a usable texture. +// +// **Topology-preserving**: the returned mesh has exactly `base_mesh`'s vertices and triangles, in +// the same order - only the positions of displaced vertices differ. Every layer's paint mask is +// evaluated against `base_mesh` directly, and each vertex accumulates a single signed displacement +// (in mm) that all the layers covering it fold into, in slot order, via their TextureBlendMode. +// The vertex is then moved once, along its base-mesh normal, by that accumulated total. +// +// This replaced an earlier design that instead applied the layers *sequentially*, re-meshing after +// each one and carrying the next layer's paint mask onto the result with +// TriangleSelector::remap_painting(). That was the cause of a real "the second texture is never +// applied" bug: remapping a mask onto a mesh whose vertices had just been displaced out from under +// it routinely produced an empty bitstream, and the layer was then silently skipped. It is also +// what forced the per-layer vertex duplication and the final its_compactify_vertices() pass. The +// accumulate-then-displace formulation has neither problem, is substantially faster (no remap, no +// welding, one pass over the mesh), and - because the output keeps the input's exact vertex +// indexing - lets the GUI overlay a preview on the base mesh without any index translation. +// +// A vertex used by even one *unpainted* triangle of a layer's mask sits on that layer's boundary. +// Whether it moves is TextureDisplacementOptions::displace_border; see that field for why displacing +// it is safe (and the default). Either way the *direction* every vertex moves in is the area-weighted +// normal of the triangles that are painted in at least one layer - not of the whole mesh - so a +// border vertex travels along the painted surface's own normal instead of a blend with whatever +// unpainted geometry meets it there. Without that, the rim of a fully painted face would displace +// along the 45 degrees bisector it shares with the side wall and flare outwards. Interior vertices +// have every incident triangle painted, so for them the two are the same normal. +// +// Takes plain copied data rather than a ModelVolume reference so it is safe to call from a +// background thread (e.g. a bake Job's process() method) on a snapshot captured on the main +// thread, without touching the live Model concurrently with the UI. +// +// Known limitation: this does not attempt to remap texture-displacement paint data across +// topology-changing operations performed outside this gizmo (e.g. ModelObject::split(), +// mesh-boolean ops) the way TriangleSelector::remap_painting() does for the other paint channels. +// Such operations will silently drop any unbaked texture-displacement paint on the affected +// volume. This is an explicit extension point for a later phase, not an oversight. +// +// `progress`, when set, is called from the worker thread with a 0..100 completion percentage as the +// bake proceeds. Returning false from it aborts the run, which then returns an *empty* mesh - never +// a partially displaced one, so a cancelled bake can never be mistaken for a finished result and +// committed. It exists because this is the one call in the feature that can take seconds on a +// subdivided mesh, and without it the progress notification the Job framework puts on screen sits at +// 0% for the whole run and offers no way to close it (its close button only appears at 100%). +// +// `color`, when given, also reports which filament each triangle should print in - see +// TextureColorRequest. +struct TextureColorRequest +{ + // RGB -> palette index. Supplied by the GUI, which owns both the perceptual matching and the list + // of filaments actually loaded (see ColorQuantizeFn). + ColorQuantizeFn quantize; + // The same over the loaded filaments alone, no mixes. Optional; when given, a layer whose image is + // made of flat colours (TextureDetail::flat_colors) is matched with this one, so a tile or a logo + // prints in single filaments while a photograph on another layer may still use mixes. + ColorQuantizeFn quantize_pure; + // Palette index + position -> filament. Optional: without it a palette index is taken to be a + // filament index directly, which is the no-mixing case. + ColorResolveFn resolve; + // Majority-filter passes over the *perceived* colour, before any interleaving is resolved. + // + // Sampling a detailed image once per triangle leaves salt-and-pepper wherever the image's own + // detail is finer than the mesh: two neighbouring facets land either side of some contour and flip + // colour independently. Replacing each facet's colour with the most common one among itself and + // its edge neighbours removes exactly that, and leaves any feature wider than a facet alone. 0 + // turns it off. + int despeckle_passes = 0; + // After the despeckle: connected patches of one colour smaller than this (mm^2) are recoloured + // to whatever borders them most - see merge_small_color_regions(). The despeckle only reaches + // single facets; an image detail a few facets wide still leaves thousands of pinhead islands + // that the slicer's multi-material segmentation cannot digest. 0 turns it off. + float min_color_region_mm2 = 0.5f; + // Filled per *base mesh* triangle (the bake is topology-preserving, so this indexes the returned + // mesh too): the quantize callback's index plus one, or 0 for "this triangle takes no colour from + // the texture". The +1 is not arbitrary - it lines up with EnforcerBlockerType, where 0 is NONE + // ("use the volume's own filament") and 1..16 are Extruder1..16, so the caller can hand these + // straight to a TriangleSelector without a second mapping table. + std::vector *out_triangle = nullptr; +}; + +// Recolours connected patches of one colour whose area is under `min_area_mm2` to the colour that +// borders them most (by shared edge length). Colour is per triangle, -1 = none (never merged into, +// never merged away). Removes the confetti a detailed image leaves on a fine mesh - thousands of +// one-facet zones, which the slicer's multi-material segmentation cannot digest. Patches are +// processed smallest-first, reading their neighbours' current colour, so a chain of tiny islands +// collapses into its surroundings rather than into each other. +void merge_small_color_regions(const indexed_triangle_set &mesh, std::vector &color, float min_area_mm2); + +// Where the volume sits on the plate: its instance transform times its own volume transform, i.e. +// mesh coordinates -> world millimetres. +// +// Every number the user sets is in real millimetres on the printed part - "Depth (mm)", "Tile size +// (mm)" - and the build plate is a world plane, so the bake runs in world space and transforms the +// result back. Doing it in the volume's own coordinates instead made a scaled instance stretch both +// the relief depth and the tiling by the scale factor, and under a non-uniform scale it also +// displaced along the wrong direction: a mesh normal maps to the world normal through the inverse +// transpose, not through the transform itself, so the relief leaned. Identity - the default - is +// exactly the old behaviour and is what an untransformed volume gives. +// What a bake spent, for whoever wants to report it. Only the default pipeline fills it in; the +// classic path moves the vertices the mesh already has and has nothing to say here. +struct TextureBakeStats +{ + // What the refinement produced, before simplification. + size_t triangles_refined = 0; + // What the result had to fit into: the budget for what this bake refines, plus the triangles it + // only preserves (an earlier bake's relief, which this one does not paint). + size_t triangles_budget = 0; + // The refined mesh did not fit, and removing its flat faces was not enough, so the simplification + // had to take detail out of it: the result carries less of the texture than the resolution asked for. + bool budget_limited = false; +}; + +indexed_triangle_set build_texture_displacement(const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, + const TextureDisplacementOptions &options = {}, + const DisplacementProgressFn &progress = {}, + const TextureColorRequest *color = nullptr, + const Transform3d &volume_to_world = Transform3d::Identity(), + // When given and enabled, receives the mesh after each + // stage, already brought back into `base_mesh`'s frame. + BakeStageRecorder *debug = nullptr, + // When given, receives what the bake spent. + TextureBakeStats *stats = nullptr); + +// `volume`'s mesh coordinates -> world millimetres: its first instance's transform times its own. +// The mesh is shared by every instance, so a multi-instance object can only be baked for one of +// them; the first is what the gizmo edits against. Identity when the volume has no object yet. +Transform3d texture_displacement_volume_to_world(const ModelVolume &volume); +// The frame the bake and the previews project the texture in: `volume_to_world` with its translation +// removed, i.e. world orientation and scale about the volume's own origin. See build_texture_displacement(). +Transform3d texture_displacement_bake_frame(const Transform3d &volume_to_world); + +// Area-weighted vertex normals of `its` - the directions the bake both projects and displaces along. +std::vector texture_displacement_vertex_normals(const indexed_triangle_set &its); + +// The frame the Cylindrical and Spherical projections wrap around: `patch`'s triangle-corner centroid, +// the world axis *least* aligned with the average of `vertex_normals` over those corners (a cylinder's +// own axis is perpendicular to its outward radial normal), and that average normal itself. +// +// Results come out in whatever frame `patch` is given in. The bake calls this with the patch already in +// the bake frame (see texture_displacement_bake_frame()), so a preview that wants to reproduce the +// bake's projection must too, or it wraps the texture around a different centre. Corners past the end +// of `vertex_normals` - the ones a brush stroke appended - contribute to the centroid but carry no +// normal, exactly as the bake's own loops skip them. +void texture_displacement_patch_frame(const indexed_triangle_set &patch, + const std::vector &vertex_normals, + Vec3f ¢er, Vec3f &axis, Vec3f &average_normal); + +// Convenience overload for main-thread callers: extracts the mesh/layers/paint data/options from +// `volume` and forwards to the overload above. +indexed_triangle_set build_texture_displacement(const ModelVolume &volume); + +// Laplacian relaxation of `mesh` in place, restricted to the vertices flagged in `movable` (sized to +// the mesh's vertex count; anything else is held exactly where it is and still acts as an anchor for +// its neighbours). Each of `iterations` passes moves a movable vertex a `strength` fraction of the +// way to the average of the vertices it shares an edge with, computed from the positions at the +// start of that pass so the result does not depend on vertex order. +// +// Topology-preserving like the bake itself, so it composes with it: this is what "smooth the relief +// after displacing it" runs, and it is also safe to run standalone on an already baked mesh. +// `strength` is clamped to [0, 1]; 0 iterations, an empty/mis-sized `movable`, or an all-false one +// leave the mesh untouched. +// `on_pass`, when set, is called with the 0-based index of each completed pass; returning false stops +// the relaxation there, leaving the passes already done in place. +void smooth_mesh_vertices(indexed_triangle_set &mesh, const std::vector &movable, float strength, + int iterations, const DisplacementProgressFn &on_pass = {}); + +// Returns a scalar height (in mm - a displacement magnitude) at a surface point, given that point's +// position and interpolated normal. This is what feature-adaptive subdivision samples to decide +// where the displaced surface has *curvature* worth spending triangles on. Called serially from the +// subdivider, so it only needs to be safe on the calling thread. +using HeightFieldSampler = std::function; + +// Builds a sampler of the *combined* (all-layers) displacement height in mm at an arbitrary surface +// point, for feature-adaptive subdivision. It mirrors build_texture_displacement()'s per-layer setup +// (decode, patch centroid, cylinder axis, blend order, "lowest layer folds additively") but evaluates +// per point instead of per vertex. Two deliberate simplifications, both erring toward *more* detail +// (safe - over-refinement is never a crack): every sampleable layer is evaluated at every point (no +// per-point paint-mask test, so a point sees all layers' textures, not only the ones painted there), +// and edge-smoothing's boundary falloff is ignored. LSCM layers have no per-point UV and are skipped. +// Returns a null sampler (bool false) when no layer can be sampled - the caller then falls back to +// uniform adaptive subdivision. +// Which filament the texture stack would put at a point, as a palette index (or -1 for "no colour +// here"). The colour analogue of HeightFieldSampler, and used the same way: to decide where the +// adaptive subdivision needs triangles. Colour lands per *facet*, so a colour boundary is a step the +// mesh can only draw if there are edges along it - the chord-error test that drives the height +// refinement is blind to it, exactly as it is blind to the paint's own border. +using ColorFieldSampler = std::function; + +// The colour counterpart of make_combined_displacement_sampler(), over the same layers, and skipping +// the same ones (LSCM has no per-point UV). Layers without color_enabled, and layers whose texture is +// grayscale, contribute nothing; a higher slot wins over a lower one where they overlap, matching the +// bake. Returns null when no layer can colour anything, in which case there is nothing to refine for. +ColorFieldSampler make_combined_color_sampler(const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data, + ColorQuantizeFn quantize, + ColorQuantizeFn quantize_pure = nullptr); + +HeightFieldSampler make_combined_displacement_sampler(const indexed_triangle_set &base_mesh, + const std::vector &layers, + const TextureDisplacementFacetsData &facets_data); + +// Uniformly subdivides `mesh` (every triangle recursively split into 4 via edge midpoints, using a +// shared cache so a midpoint is computed once and reused by both triangles on either side of that +// edge) until every edge is at or below max_edge_length_mm, or max_iterations passes have run, +// whichever comes first (bounding the worst-case triangle-count explosion on a very fine target). +// +// This exists so a low-poly input model can still get fine-grained texture displacement detail - +// build_texture_displacement() can only ever move existing vertices, so a patch with only a +// handful of vertices to begin with cannot show much detail no matter the texture's resolution. +// +// Deliberately whole-mesh and uniform, not limited to a painted patch: subdividing only part of a +// mesh while leaving the rest untouched creates a classic T-junction/cracking problem where the +// denser and sparser regions meet (the finer side has edge midpoints the coarser side doesn't +// know about). Uniform, whole-mesh subdivision has no such seam and stays manifold, at the cost of +// applying everywhere rather than just where texture detail is actually wanted - meant to be run +// once, deliberately, before painting (see the gizmo's "Subdivide model" button), not automatically +// during baking. +indexed_triangle_set subdivide_mesh_uniform(const indexed_triangle_set &mesh, float max_edge_length_mm, int max_iterations = 6); + +// Adaptive subdivision by Rivara longest-edge bisection, restricted to a region. +// +// Unlike subdivide_mesh_uniform() this only densifies where asked - `refine_region` (indexed by +// input-triangle index; empty or all-false => no-op) flags the triangles allowed to drive refinement +// - so a small painted patch on a large model does not quadruple the whole model's triangle count. +// It is nonetheless *conformal*: it never leaves a T-junction/crack at the boundary between the +// refined and coarse regions (the trap that made subdivide_mesh_uniform() deliberately whole-mesh). +// +// A triangle wants refining while it is over at least one of these, whichever applies: +// - length: its longest edge exceeds `target_edge_length_mm` (a *baseline* - it applies in feature +// mode too, and is what stops a coarse triangle from being declared flat merely because +// the four points the chord test samples happened to land at similar heights on a +// high-frequency texture: the classic aliasing stall); +// - feature: (only when `sampler` is set and `chord_tolerance_mm > 0`) the *displaced* surface +// departs from the flat triangle by more than `chord_tolerance_mm`, measured as the max +// over the three edge midpoints AND the centroid of |sampled displacement - the flat +// triangle's barycentric interpolation|. Sampling the interior, not just edge midpoints, +// is what catches a hill that sits inside a triangle. This is a *curvature* test: it is +// exactly zero on a plane or a linear ramp (barycentric interpolation is exact there, so +// those stay coarse - the case a gradient criterion would over-refine) and large on a +// hill/ridge/noise. +// `min_edge_length_mm` is a hard floor under both: no triangle whose longest edge is already at or +// below it is ever refined, which is also what guarantees termination across a sharp texture step +// (where the chord error never falls below the tolerance no matter how fine the mesh gets). +// +// Refinement runs to completion, not for a fixed number of passes: triangles are taken worst-first +// from a max-heap keyed by how many times over its criteria each one is, so a run that hits the +// `max_triangles` budget has spent it on the largest errors rather than wherever a sweep happened to +// reach. The budget is the only bound on a pathological height field; stopping on it leaves a +// perfectly valid, still-conformal mesh. +// +// How it stays crack-free: only "terminal" edges are ever bisected - an edge that is the longest edge +// of *both* triangles sharing it (or a boundary edge that is the longest of its one triangle). +// Bisecting such an edge splits both its triangles 1->2 around the same new midpoint, so a hanging +// node is never created. The edge to split for a triangle that wants refining is found by Rivara +// longest-edge propagation (LEPP): walk to the longest edge of ever-longer-edged neighbours until a +// terminal edge is reached, and bisect that. Edge length strictly increases along the path (ties +// broken by a mesh-vertex key, which both sides of an edge compute identically), so the walk cannot +// cycle, and Rivara's result is that repeating it refines the original triangle in a bounded number +// of bisections - closing the propagation gap a plain per-edge test leaves behind. The transition +// triangles this pulls in just outside the region are the graded band that makes the size change +// conformal; they are a bounded cost paid once, not a per-pass tax. +// +// If `out_source` is non-null it is resized to the output triangle count and out_source[i] receives +// the input triangle that output triangle i descends from (children inherit their parent's index), so +// a caller can carry per-triangle data - e.g. a paint mask - across the topology change without a +// geometric remap. +// +// `refine_region` is a **bitmask** per input triangle, not a plain flag: +// bit 0 (REFINE_PAINTED) - inside the painted area: refine by the length baseline and, in feature +// mode, by the chord-error test. +// bit 1 (REFINE_BORDER) - inside the band straddling the paint's edge: refine by +// `border_edge_length_mm` alone. +// A value of 1 therefore means exactly what a plain 1 always meant, and 0 still means "never touch +// this triangle except through the conformal closure". +// +// The border band exists because the chord-error test is blind to the one discontinuity the bake +// actually creates. `make_combined_displacement_sampler()` evaluates the height field everywhere, +// with no per-point paint test, so where the paint *stops* it keeps reporting full relief - smooth +// and low-curvature - while the baked surface steps from full displacement to zero. The test sees no +// error there and leaves the transition at whatever density the input had, which is what turns the +// rim of an unpainted island into a ring of large, steeply tilted triangles. Refining that band by +// plain edge length is bounded (it is a thin ring, and a length target always terminates) and needs +// no paint-aware sampler. +// +// `color`, with a positive `color_edge_length_mm`, adds a third criterion inside the painted area: a +// triangle whose corners, edge midpoints and centroid do not all map to the *same* filament straddles +// a colour boundary, and is refined by plain edge length down to that target. Length rather than any +// error measure, for the same reason the border band uses length - the thing being fixed is the size +// of the triangles spanning a step, not the curvature of anything - and because a step's error never +// falls however fine the mesh gets, so only a length target (floored by min_edge_length_mm) is +// guaranteed to terminate. Without this a colour boundary lands on whatever triangles the *height* +// happened to need, which on a flat surface is none at all. +// +// `progress`, when given, is called with a 0..100 percentage of the triangle budget spent; returning +// false stops the refinement early. What it hands back then is still a complete, conformal mesh - the +// loop only ever finishes whole bisections - so a caller that wants to discard it has to do so itself. +indexed_triangle_set subdivide_mesh_adaptive(const indexed_triangle_set &mesh, + const std::vector &refine_region, + float target_edge_length_mm, int max_triangles = 1000000, + std::vector *out_source = nullptr, + const HeightFieldSampler &sampler = nullptr, + float chord_tolerance_mm = 0.f, float min_edge_length_mm = 0.f, + float border_edge_length_mm = 0.f, + const DisplacementProgressFn &progress = nullptr, + const ColorFieldSampler &color = nullptr, + float color_edge_length_mm = 0.f, + // Step mode, for a mesh that cut_mesh_at_steps() will cut + // next: a triangle one of whose edges crosses a *sharp* + // step of the height field (a jump of 40 % of the relief + // between two samples at the sample spacing, across the + // mid-level) gets a chord error of zero, since the step is + // the cutter's to reproduce and refining it only carpets + // the edge of the pattern. Features that no edge crosses + // yet still refine until one does. No effect outside + // feature mode. + bool split_multi_crossings = false); + +// Cuts `mesh` along the height field's mid-level contour wherever the field steps sharply across it, +// and doubles the seam, so that displacing the result produces a vertical wall at the step instead of +// a ramp across whichever triangle the step happened to fall in. +// +// This is what a binary height map - a grid, stripes, a knurl, wood grain as black-and-white bands - +// needs, and what refinement alone cannot give it. Refining a triangle that straddles a step never +// brings the chord error under any tolerance: the surface has a discontinuity, and a finer triangle only +// makes the ramp narrower. Every refinement level then leaves a band of its own size along every step, +// and the triangle budget ends up spent on carpeting the edges of the pattern, one to two orders of +// magnitude more triangles than the pattern needs, while the ramps are still visible. +// +// What it does, in order: +// - Samples the field at the vertices along the bake's normals and takes the mid-level as the contour. +// A vertex that sits inside a step's blend is nudged along the surface, down its own side's slope, +// until it samples a pure value, so no vertex bakes to a half height. +// - Marches every painted edge for crossings of the mid-level (sampled at half `step_width_mm`, then +// bisected). Both triangles at an edge see the same crossings, which keeps the result conformal. A +// crossing is *sharp* when the field changes by half its range within `step_width_mm`. +// - Traces the contour inside each triangle on a local lattice (marching triangles) and keeps the +// polylines that join one crossing to another; a closed loop inside a triangle is left to +// refinement. Each polyline is simplified and kept clear of its neighbours. +// - Doubles the seam: every polyline vertex and every crossing gets a copy on each side, moved +// `seam_gap_mm` apart across the contour to where each samples a pure value of its own side. The +// regions between the seams are ear-clipped; the strip between the two copies is triangulated flat +// and becomes the wall once the high side is displaced. A triangle whose contour could not be traced +// is split at its crossings without a seam, so the neighbours still meet it without a T-junction. +// +// Nothing is cut unless the texture is a step texture: most vertex heights sit at one of two levels, +// most crossings are sharp, and the features are wider than a couple of step widths (a noisy or a +// smooth relief is passed through unchanged, as is a mesh with nothing painted). If the cut would leave +// more than a trace of inverted triangles the input is returned unchanged as well. +// +// `region` flags the triangles that may be cut (the painted ones, same encoding as +// subdivide_mesh_adaptive(), any non-zero value). An edge may carry any number of crossings; two closer +// than `max(min_feature_mm, seam_gap_mm)` are a feature too thin to carry a seam and are dropped as a +// pair, leaving the surface flat there. `out_source` receives the input triangle each output triangle +// descends from, so paint carries over; `out_cut_count` the number of input triangles that were cut +// (0 means the mesh came back unchanged). +indexed_triangle_set cut_mesh_at_steps(const indexed_triangle_set &mesh, const std::vector ®ion, + const HeightFieldSampler &sampler, float step_width_mm, + float seam_gap_mm, float min_feature_mm = 0.f, + std::vector *out_source = nullptr, size_t *out_cut_count = nullptr); + +// The cutter's verdict alone: whether cut_mesh_at_steps() with the same arguments would cut anything, +// judged the same way (two levels, sharp crossings, features wider than the step) but without the +// vertex nudge or any tracing, so it is cheap enough to ask on the coarse mesh. The prepare path asks +// it *before* refining: a subdivision run in step mode leaves the steps alone for the cutter, which is +// only right if the cutter is then going to cut them. +bool texture_has_steps_to_cut(const indexed_triangle_set &mesh, const std::vector ®ion, + const HeightFieldSampler &sampler, float step_width_mm, float seam_gap_mm, + float min_feature_mm = 0.f); + +// The recipe for getting a mesh ready to receive displacement: even out the triangle density, then +// refine it where the texture bends. Either stage is skipped when its target is <= 0. Pure data, and +// the whole of it, so the preparation can be handed to a background job instead of running on the UI +// thread - see GLGizmoTextureDisplacement::prepare_mesh(). +struct TextureDisplacementPrepareParams +{ + // Isotropic remesh (CGAL). The target is clamped against the part's own surface area before it is + // used, so a value that would produce millions of triangles cannot be asked for by accident. + float remesh_edge_mm = 0.f; + float remesh_sharp_deg = 0.f; // 0 = do not protect sharp edges + + // Adaptive (Rivara) subdivision of the painted area. See subdivide_mesh_adaptive(). + float subdiv_target_mm = 0.f; // "Max edge": the length baseline, and the only criterion when + // subdiv_feature is off + float subdiv_detail_mm = 0.f; // "Detail": chord tolerance, feature mode only + float subdiv_min_edge_mm = 0.f; // "Min edge": the floor under both, feature mode only + float subdiv_border_mm = 0.f; // "Edge detail": the band straddling the paint's edge, 0 = off + bool subdiv_feature = false; // follow texture curvature, not just edge length + int subdiv_added_triangles = 0; // budget, *added* to the mesh's own count + // Edge length triangles straddling a *colour* boundary are refined to, 0 = do not look at colour. + // Separate from the height criteria because colour lands per facet: a flat surface carrying a + // sharp colour edge needs triangles along that edge even though its height is perfectly smooth. + float subdiv_color_edge_mm = 0.f; + // Cut the mesh along sharp steps in the texture after refining, so they bake as walls rather than + // ramps. See cut_mesh_at_steps(). Off leaves the old ramp behaviour. + bool cut_steps = false; +}; + +// What a preparation run produced. An empty `mesh` means there was nothing to do and the caller must +// commit nothing - which is not a failure: a mesh that is already even needs no remesh, and one that +// is already fine enough for the texture needs no subdivision. +struct TextureDisplacementPrepareResult +{ + indexed_triangle_set mesh; + TextureDisplacementFacetsData masks; + // The remesh landed but no layer's paint survived being carried onto it. Nothing is committed: + // everything downstream is driven by that paint, so baking on would bake a flat mesh. + bool paint_lost = false; +}; + +} // namespace Slic3r + +#endif // slic3r_TextureDisplacement_hpp_ diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index b47004fca5..4d6007530f 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -1519,9 +1519,11 @@ void TriangleSelector::get_facets(std::vector& facets_per_ } } -indexed_triangle_set TriangleSelector::get_facets_strict(EnforcerBlockerType state) const +indexed_triangle_set TriangleSelector::get_facets_strict(EnforcerBlockerType state, std::vector *out_source) const { indexed_triangle_set out; + if (out_source) + out_source->clear(); size_t num_vertices = 0; for (const Vertex &v : m_vertices) @@ -1535,8 +1537,13 @@ indexed_triangle_set TriangleSelector::get_facets_strict(EnforcerBlockerType sta out.vertices.emplace_back(v.v); } - for (int itriangle = 0; itriangle < m_orig_size_indices; ++ itriangle) + for (int itriangle = 0; itriangle < m_orig_size_indices; ++ itriangle) { this->get_facets_strict_recursive(m_triangles[itriangle], m_neighbors[itriangle], state, out.indices); + // Everything the recursion just appended came from this original triangle, whatever depth it + // was split to. Recording it here keeps the recursive helpers untouched. + if (out_source) + out_source->resize(out.indices.size(), itriangle); + } for (auto &triangle : out.indices) for (int i = 0; i < 3; ++ i) @@ -1778,6 +1785,13 @@ TriangleSelector::TriangleSplittingData TriangleSelector::serialize() const { return out.data; } +// A split code keeps the split side (one split) or the kept side (two splits) in its upper two +// bits, where 3 is not a side. The value is ignored for a three-side split. +static bool split_code_valid(int code) +{ + return (code & 0b11) == 3 || (code >> 2) != 3; +} + void TriangleSelector::deserialize(const TriangleSplittingData &data, bool needs_reset, EnforcerBlockerType max_ebt, @@ -1812,11 +1826,12 @@ void TriangleSelector::deserialize(const TriangleSplittingData &data, for (auto [triangle_id, ibit] : data.triangles_to_split) { assert(triangle_id < int(m_triangles.size())); - assert(ibit < int(data.bitstream.size())); - auto next_nibble = [&data, &ibit = ibit]() { + // Set when the bitstream runs out or holds an impossible split before this triangle's tree is complete. + bool corrupt = false; + auto next_nibble = [&data, &ibit = ibit, &corrupt]() { int n = 0; - for (int i = 0; i < 4; ++ i) - n |= data.bitstream[ibit ++] << i; + if (! data.read_nibble(ibit, n)) + corrupt = true; return n; }; // Decode a leaf state stored behind the "11" prefix: one nibble of (state-3) for states @@ -1835,6 +1850,10 @@ void TriangleSelector::deserialize(const TriangleSplittingData &data, bool is_split = num_of_children != 0; // Only valid if not is_split. auto state = is_split ? EnforcerBlockerType::NONE : ((code & 0b1100) == 0b1100 ? decode_leaf_state() : EnforcerBlockerType(code >> 2)); + if (is_split && ! split_code_valid(code)) + corrupt = true; + if (corrupt) + break; // BBS if (state == to_delete_filament) @@ -1849,7 +1868,7 @@ void TriangleSelector::deserialize(const TriangleSplittingData &data, } // Only valid if is_split. - int special_side = code >> 2; + int special_side = num_of_split_sides == 3 ? 0 : code >> 2; // Take care of the first iteration separately, so handling of the others is simpler. if (parents.empty()) { @@ -1904,47 +1923,55 @@ void TriangleSelector::deserialize(const TriangleSplittingData &data, if (parents.empty()) break; } + + if (corrupt) { + // Every split above allocated all of its children, so the partial tree unwinds cleanly. + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": malformed paint data, dropping paint of triangle " << triangle_id; + undivide_triangle(triangle_id); + m_triangles[triangle_id].set_state(EnforcerBlockerType::NONE); + } } } -void TriangleSelector::TriangleSplittingData::update_used_states(const size_t bitstream_start_idx) { - assert(bitstream_start_idx < this->bitstream.size()); - assert(!this->bitstream.empty() && this->bitstream.size() != bitstream_start_idx); - assert((this->bitstream.size() - bitstream_start_idx) % 4 == 0); +bool TriangleSelector::TriangleSplittingData::update_used_states(const size_t bitstream_start_idx) { + int ibit = static_cast(bitstream_start_idx); + uint64_t states = 0; + do { + // Walk one triangle's tree depth-first, counting the nodes still to be read; a split node adds its children. + for (int pending_nodes = 1; pending_nodes > 0; --pending_nodes) { + int code; + if (!this->read_nibble(ibit, code)) + return false; - if (this->bitstream.empty() || this->bitstream.size() == bitstream_start_idx) - return; + if (const int num_of_split_sides = code & 0b11; num_of_split_sides != 0) { + if (!split_code_valid(code)) + return false; + pending_nodes += num_of_split_sides + 1; + continue; + } - size_t nibble_idx = bitstream_start_idx; - - auto read_next_nibble = [&data_bitstream = std::as_const(this->bitstream), &nibble_idx]() -> uint8_t { - assert(nibble_idx + 3 < data_bitstream.size()); - uint8_t code = 0; - for (size_t bit_idx = 0; bit_idx < 4; ++bit_idx) - code |= data_bitstream[nibble_idx++] << bit_idx; - return code; - }; - - while (nibble_idx < this->bitstream.size()) { - const uint8_t code = read_next_nibble(); - - if (const bool is_split = (code & 0b11) != 0; is_split) - continue; - - uint8_t facet_state; - if ((code & 0b1100) == 0b1100) { - // Leaf behind the "11" prefix: one nibble of (state-3), or 0b1111 + (state-18). - const uint8_t nibble = read_next_nibble(); - facet_state = nibble == 0b1111 ? uint8_t(read_next_nibble() + 18) : uint8_t(nibble + 3); - } else { - facet_state = code >> 2; + int facet_state = code >> 2; + if (facet_state == 0b11) { + // Leaf behind the "11" prefix: one nibble of (state-3), or 0b1111 + (state-18). + int nibble; + if (!this->read_nibble(ibit, nibble)) + return false; + facet_state = nibble + 3; + if (nibble == 0b1111) { + if (!this->read_nibble(ibit, nibble)) + return false; + facet_state = nibble + 18; + } + } + states |= uint64_t(1) << facet_state; } - assert(facet_state < this->used_states.size()); - if (facet_state >= this->used_states.size()) - continue; + } while (static_cast(ibit) < this->bitstream.size()); - this->used_states[facet_state] = true; - } + // The leaf encoding tops out at state 33, so every state fits the 64-bit mask. + for (size_t state_idx = 0; state_idx < std::min(this->used_states.size(), 64); ++state_idx) + if (states & (uint64_t(1) << state_idx)) + this->used_states[state_idx] = true; + return true; } // Lightweight variant of deserialization, which only tests whether a face of test_state exists. @@ -1956,11 +1983,12 @@ bool TriangleSelector::has_facets(const TriangleSplittingData &data, const Enfor for (const TriangleBitStreamMapping &triangle_id_and_ibit : data.triangles_to_split) { int ibit = triangle_id_and_ibit.bitstream_start_idx; - assert(ibit < int(data.bitstream.size())); - auto next_nibble = [&data, &ibit = ibit]() { + // Stop reading a triangle whose stream is truncated. + bool truncated = false; + auto next_nibble = [&data, &ibit = ibit, &truncated]() { int n = 0; - for (int i = 0; i < 4; ++ i) - n |= data.bitstream[ibit ++] << i; + if (! data.read_nibble(ibit, n)) + truncated = true; return n; }; // < 0 -> negative of a number of children @@ -1978,6 +2006,8 @@ bool TriangleSelector::has_facets(const TriangleSplittingData &data, const Enfor }; int state = num_children_or_state(); + if (truncated) + continue; if (state < 0) { // Root is split. parents_children.clear(); @@ -1985,6 +2015,8 @@ bool TriangleSelector::has_facets(const TriangleSplittingData &data, const Enfor do { if (-- parents_children.back() >= 0) { int state = num_children_or_state(); + if (truncated) + break; if (state < 0) // Child is split. parents_children.emplace_back(- state); diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index 594f710e45..344e88cb99 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -297,8 +297,20 @@ public: std::fill(used_states.begin(), used_states.end(), false); } - // Update used states based on the bitstream. It just iterated over the bitstream from the bitstream_start_idx till the end. - void update_used_states(size_t bitstream_start_idx); + // Update used states from the triangle trees stored between bitstream_start_idx and the end of the bitstream. + // Returns false and leaves used states untouched if a tree is truncated or malformed. + bool update_used_states(size_t bitstream_start_idx); + + // Read the 4-bit code at bit index ibit (LSB first) and advance ibit past it. + // Returns false without advancing when fewer than 4 bits remain. + bool read_nibble(int &ibit, int &nibble) const { + if (ibit < 0 || static_cast(ibit) + 4 > bitstream.size()) + return false; + nibble = 0; + for (int i = 0; i < 4; ++i) + nibble |= static_cast(bitstream[ibit++]) << i; + return true; + } private: friend class cereal::access; @@ -350,7 +362,14 @@ public: // Get facets at a given state. Don't triangulate T-joints. indexed_triangle_set get_facets(EnforcerBlockerType state) const; // Get facets at a given state. Triangulate T-joints. - indexed_triangle_set get_facets_strict(EnforcerBlockerType state) const; + // Sub-triangles in `state`, with the *whole* mesh's referenced vertex array (only .indices is + // filtered by state, so two calls with different states share one indexing). + // + // `out_source`, when given, is filled parallel to the returned .indices with the index of the + // original mesh triangle each sub-triangle came from. That is what lets a caller carry partial + // paint - the pieces of a triangle a brush stroke only partly covered - across a refinement of + // the same surface, instead of having to round each source triangle to wholly painted or not. + indexed_triangle_set get_facets_strict(EnforcerBlockerType state, std::vector *out_source = nullptr) const; // Get edges around the selected area by seed fill. std::vector get_seed_fill_contour() const; diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index b21da72fc8..c85d33eed2 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -256,10 +256,19 @@ extern bool is_gallery_file(const std::string& path, char const* type); extern bool is_shapes_dir(const std::string& dir); //BBS: add json support extern bool is_json_file(const std::string& path); -// True if rel_path is relative, has no ".." component and, joined to root, still resolves inside it. +// True if rel_path is relative, has no ".." component or embedded NUL and, joined to root, still resolves inside it. // Both '/' and '\\' are treated as separators on every platform, so an archive rejected on one OS // is rejected on all of them. extern bool is_path_within_root(const std::string &rel_path, const boost::filesystem::path &root); +// True if a symlink stored at link_rel_path (relative to root) with this target stays inside root: the target +// must be relative, and joined to the link's directory it must pass is_path_within_root. +extern bool is_symlink_target_within_root(const std::string &link_rel_path, const std::string &target, const boost::filesystem::path &root); +// True if path names an entry strictly inside root: it must be spelled with root as its prefix, +// and must still resolve inside root once symlinks are followed. +extern bool is_absolute_path_within_root(const boost::filesystem::path &path, const boost::filesystem::path &root); +// True if a file with this name is of a type that the desktop opens as plain content, so it cannot run code. +// Anything unknown is not safe. +extern bool is_safe_to_open_file_name(const std::string &file_name); // Orca: custom protocal support utils inline bool is_orca_open(const std::string& url) { return boost::starts_with(url, "orcaslicer://open"); } @@ -285,6 +294,21 @@ inline std::string sanitize_filename(const std::string &filename){ const std::regex special_chars("[/\\\\:*?\"<>|]"); return std::regex_replace(filename, special_chars, "_"); } +// Reduce an untrusted, possibly path-qualified name to a single sanitized file name. +// Returns an empty string when nothing usable remains. +inline std::string sanitize_file_basename(const std::string &name){ + const size_t sep = name.find_last_of("/\\"); + const std::string base = sanitize_filename(sep == std::string::npos ? name : name.substr(sep + 1)); + // Names made only of dots and spaces refer to the folder or its parent, or are stripped to nothing on Windows. + return base.find_first_not_of(". ") == std::string::npos ? std::string() : base; +} +// Marker file a download of this process writes to before it is renamed to filename. +boost::filesystem::path download_marker_path(const boost::filesystem::path &dest_folder, const std::string &filename); +// Finds a sanitized variant of filename, "name(N).ext" if needed, that neither an entry of dest_folder +// nor the download marker of another download uses. The marker at ignored_marker does not count. +// Returns true and the name in result, or false and the last name tried. +bool find_unused_filename(const boost::filesystem::path &dest_folder, const std::string &filename, + const boost::filesystem::path &ignored_marker, std::string &result); // File path / name / extension splitting utilities, working with UTF-8, // to be published to Perl. namespace PerlUtils { diff --git a/src/libslic3r/miniz_extension.cpp b/src/libslic3r/miniz_extension.cpp index 53a4a8e9de..4d9b528267 100644 --- a/src/libslic3r/miniz_extension.cpp +++ b/src/libslic3r/miniz_extension.cpp @@ -4,6 +4,9 @@ #include "miniz_extension.hpp" #include "Utils.hpp" +#include +#include + #if defined(_MSC_VER) || defined(__MINGW64__) #include "boost/nowide/cstdio.hpp" #endif @@ -115,6 +118,66 @@ std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_ return decode_zip_unicode_path_extra_field(extra.substr(0, extra_size > 0 ? extra_size - 1 : 0), stat.m_filename); } +bool extract_archive_confined(const std::string &zip_path_utf8, const std::string &dest_dir) +{ + mz_zip_archive archive; + mz_zip_zero_struct(&archive); + + if (!open_zip_reader(&archive, zip_path_utf8)) { + BOOST_LOG_TRIVIAL(error) << "Unable to open zip reader for " << zip_path_utf8; + return false; + } + + const mz_uint num_entries = mz_zip_reader_get_num_files(&archive); + mz_zip_archive_file_stat stat; + + // Validate every entry first so an archive with a single escaping entry leaves no partial output behind. + const boost::filesystem::path root(dest_dir); + for (mz_uint i = 0; i < num_entries; ++i) { + if (mz_zip_reader_file_stat(&archive, i, &stat) && !is_path_within_root(stat.m_filename, root)) { + BOOST_LOG_TRIVIAL(error) << "Unzip: rejecting " << zip_path_utf8 << ", entry " << stat.m_filename << " resolves outside " << dest_dir; + close_zip_reader(&archive); + return false; + } + } + + for (mz_uint i = 0; i < num_entries; ++i) { + if (!mz_zip_reader_file_stat(&archive, i, &stat)) { + BOOST_LOG_TRIVIAL(warning) << "Unzip: read file stat failed"; + continue; + } + const std::string dest_file = dest_dir + "/" + stat.m_filename; + try { + if (stat.m_is_directory) { + const boost::filesystem::path dest_path(dest_file); + if (!boost::filesystem::exists(dest_path)) + boost::filesystem::create_directories(dest_path); + continue; + } + if (stat.m_uncomp_size == 0) { + BOOST_LOG_TRIVIAL(warning) << "Unzip: invalid size for file " << stat.m_filename; + continue; + } + // Replace a symlink at the destination rather than writing through it. + const boost::filesystem::path dest_path(dest_file); + if (boost::filesystem::is_symlink(boost::filesystem::symlink_status(dest_path))) + boost::filesystem::remove(dest_path); + if (!mz_zip_reader_extract_to_file(&archive, stat.m_file_index, dest_file.c_str(), 0)) { + BOOST_LOG_TRIVIAL(error) << "Unzip: extract file " << stat.m_filename << " to dest " << dest_file << " failed"; + close_zip_reader(&archive); + return false; + } + BOOST_LOG_TRIVIAL(info) << "Unzip: successfully extract file " << stat.m_file_index << " to " << dest_file; + } catch (const std::exception &e) { + close_zip_reader(&archive); + BOOST_LOG_TRIVIAL(error) << "Unzip: archive read exception: " << e.what(); + return false; + } + } + close_zip_reader(&archive); + return true; +} + MZ_Archive::MZ_Archive() { mz_zip_zero_struct(&arch); diff --git a/src/libslic3r/miniz_extension.hpp b/src/libslic3r/miniz_extension.hpp index 1a1c96689f..97aa91b93f 100644 --- a/src/libslic3r/miniz_extension.hpp +++ b/src/libslic3r/miniz_extension.hpp @@ -11,6 +11,8 @@ bool open_zip_writer(mz_zip_archive *zip, const std::string &fname_utf8); bool close_zip_reader(mz_zip_archive *zip); bool close_zip_writer(mz_zip_archive *zip); std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_file_stat &stat); +// Extracts every entry of the archive under dest_dir. Nothing is written if any entry would resolve outside dest_dir. +bool extract_archive_confined(const std::string &zip_path_utf8, const std::string &dest_dir); class MZ_Archive { public: diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 9def5dad17..f56ce6a7af 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -70,6 +70,7 @@ #include #include +#include #include #include #include @@ -1093,6 +1094,9 @@ bool is_path_within_root(const std::string &rel_path, const boost::filesystem::p auto is_separator = [](char c) { return c == '/' || c == '\\'; }; if (rel_path.empty() || is_separator(rel_path.front()) || (rel_path.size() > 1 && rel_path[1] == ':')) return false; + // The filesystem calls stop at a NUL, so they would act on a shorter path than the one checked here. + if (rel_path.find('\0') != std::string::npos) + return false; for (size_t start = 0; start <= rel_path.size();) { size_t end = start; while (end < rel_path.size() && !is_separator(rel_path[end])) @@ -1103,7 +1107,10 @@ bool is_path_within_root(const std::string &rel_path, const boost::filesystem::p } // Resolve against the canonical root so a symlink inside it cannot lead back out. try { - const std::string root_str = boost::filesystem::weakly_canonical(root).string(); + std::string root_str = boost::filesystem::weakly_canonical(root).string(); + // A trailing separator on root would otherwise fail the prefix match below for every path. + while (!root_str.empty() && (root_str.back() == '/' || root_str.back() == boost::filesystem::path::preferred_separator)) + root_str.pop_back(); const std::string full_str = boost::filesystem::weakly_canonical(root / rel_path).string(); return full_str.compare(0, root_str.size(), root_str) == 0 && (full_str.size() == root_str.size() || full_str[root_str.size()] == boost::filesystem::path::preferred_separator); @@ -1112,6 +1119,37 @@ bool is_path_within_root(const std::string &rel_path, const boost::filesystem::p } } +bool is_symlink_target_within_root(const std::string &link_rel_path, const std::string &target, const boost::filesystem::path &root) +{ + if (target.empty() || target.front() == '/' || target.front() == '\\' || (target.size() > 1 && target[1] == ':')) + return false; + // A relative target without ".." only descends from the link's directory, so no chain of such links can leave root. + const size_t sep = link_rel_path.find_last_of("/\\"); + return is_path_within_root((sep == std::string::npos ? std::string() : link_rel_path.substr(0, sep + 1)) + target, root); +} + +bool is_absolute_path_within_root(const boost::filesystem::path &path, const boost::filesystem::path &root) +{ + const boost::filesystem::path rel = path.lexically_relative(root); + return !rel.empty() && rel != "." && is_path_within_root(rel.string(), root); +} + +bool is_safe_to_open_file_name(const std::string &file_name) +{ + // Formats that cannot carry macros or scripts. Legacy and OpenDocument office files, HTML and SVG are left out on purpose. + static const std::vector safe_extensions = { + "jpg", "jpeg", "jfif", "pjpeg", "pjp", "png", "gif", "bmp", "webp", "tif", "tiff", + "pdf", "txt", "md", "csv", "docx", "xlsx", "pptx", + "stl", "obj", "3mf", "amf", "ply", "step", "stp", "iges", "igs", "dxf", + "mp4", "mov", "webm"}; + // The name must end in the extension itself: Windows drops trailing dots and spaces and reads ':' as a stream separator. + const size_t dot = file_name.find_last_of('.'); + if (dot == std::string::npos || file_name.find_first_of("/\\:") != std::string::npos) + return false; + const std::string extension = boost::algorithm::to_lower_copy(file_name.substr(dot + 1)); + return std::find(safe_extensions.begin(), safe_extensions.end(), extension) != safe_extensions.end(); +} + bool is_img_file(const std::string &path) { return boost::iends_with(path, ".png") || boost::iends_with(path, ".svg"); @@ -1321,6 +1359,31 @@ unsigned get_current_pid() #endif } +boost::filesystem::path download_marker_path(const boost::filesystem::path &dest_folder, const std::string &filename) +{ + return dest_folder / (filename + "." + std::to_string(get_current_pid()) + ".download"); +} + +bool find_unused_filename(const boost::filesystem::path &dest_folder, const std::string &filename, + const boost::filesystem::path &ignored_marker, std::string &result) +{ + // Probe the name that will be written, so a name the sanitizing maps onto an existing file is versioned too. + const std::string sanitized = sanitize_filename(filename); + const std::string extension = boost::filesystem::path(sanitized).extension().string(); + const std::string stem = sanitized.substr(0, sanitized.size() - extension.size()); + auto is_used = [&](const std::string &name) { + const boost::filesystem::path marker = download_marker_path(dest_folder, name); + return boost::filesystem::exists(dest_folder / name) || (marker != ignored_marker && boost::filesystem::exists(marker)); + }; + result = sanitized; + for (size_t version = 1; is_used(result); ++version) { + if (version > 999) + return false; + result = stem + "(" + std::to_string(version) + ")" + extension; + } + return true; +} + std::string per_user_temp_id() { #ifdef WIN32 diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 464f8e5bd5..b1557244b6 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -214,6 +214,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmosManager.hpp GUI/Gizmos/GLGizmoSVG.cpp GUI/Gizmos/GLGizmoSVG.hpp + GUI/Gizmos/GLGizmoTextureDisplacement.cpp + GUI/Gizmos/GLGizmoTextureDisplacement.hpp GUI/Gizmos/GLGizmoUtils.cpp GUI/Gizmos/GLGizmoUtils.hpp #GUI/Gizmos/GLGizmoText.cpp @@ -342,6 +344,14 @@ set(SLIC3R_GUI_SOURCES GUI/Jobs/SLAImportDialog.hpp GUI/Jobs/SLAImportJob.cpp GUI/Jobs/SLAImportJob.hpp + GUI/Jobs/TextureDisplacementBakeJob.cpp + GUI/Jobs/TextureDisplacementBakeJob.hpp + GUI/Jobs/TextureDisplacementPrepareJob.cpp + GUI/Jobs/TextureDisplacementPrepareJob.hpp + GUI/Jobs/TextureDisplacementDebugJob.cpp + GUI/Jobs/TextureDisplacementDebugJob.hpp + GUI/Jobs/TextureDisplacementPreviewJob.cpp + GUI/Jobs/TextureDisplacementPreviewJob.hpp GUI/Jobs/ThreadSafeQueue.hpp GUI/Jobs/UpgradeNetworkJob.cpp GUI/Jobs/UpgradeNetworkJob.hpp @@ -539,6 +549,10 @@ set(SLIC3R_GUI_SOURCES GUI/TaskManager.hpp GUI/TextLines.cpp GUI/TextLines.hpp + GUI/TextureLibrary.cpp + GUI/TextureLibrary.hpp + GUI/TextureProjectorFrame.cpp + GUI/TextureProjectorFrame.hpp GUI/TickCode.cpp GUI/TickCode.hpp GUI/TroubleshootDialog.cpp @@ -555,6 +569,8 @@ set(SLIC3R_GUI_SOURCES GUI/UserManager.hpp GUI/UserNotification.cpp GUI/UserNotification.hpp + GUI/UVEditorCanvas.cpp + GUI/UVEditorCanvas.hpp GUI/WebDownPluginDlg.cpp GUI/WebDownPluginDlg.hpp GUI/WebGuideDialog.cpp @@ -1032,14 +1048,9 @@ if (UNIX AND NOT APPLE) find_package(GTK${SLIC3R_GTK} REQUIRED) pkg_check_modules(LIBSECRET REQUIRED libsecret-1) pkg_check_modules(webkit2gtk REQUIRED webkit2gtk-4.1) - if (FLATPAK) - # I don't know why this is needed, but for whatever reason slic3r isn't - # linking to X11 and webkit2gtk. force it. - find_package(X11 REQUIRED) - target_link_libraries(libslic3r_gui ${X11_LIBRARIES} ${webkit2gtk_LIBRARIES}) - endif() + find_package(X11 REQUIRED) target_include_directories(libslic3r_gui SYSTEM PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS} ${LIBSECRET_INCLUDE_DIRS} ${webkit2gtk_INCLUDE_DIRS}) - target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES} fontconfig ${LIBSECRET_LIBRARIES}) + target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES} fontconfig ${LIBSECRET_LIBRARIES} ${webkit2gtk_LIBRARIES} ${X11_LIBRARIES}) # Propagate GDK backend detection results as compile definitions so that # LinuxDisplayBackend.cpp can include the right GDK headers. diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index bf3cdc5303..d72407a77e 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -162,6 +162,14 @@ ColorRGBA GLVolume::SUPPORT_BLOCKER_COL = {1.0f, 0.3f, 0.3f, 0.4f}; ColorRGBA GLVolume::MODEL_HIDDEN_COL = {0.f, 0.f, 0.f, 0.3f}; +// Precise Seam modifier colors +ColorRGBA GLVolume::PRECISE_SEAM_CENTER_COL = {1.0f, 0.627f, 0.082f, 0.6f}; // FFA015 - orange +ColorRGBA GLVolume::PRECISE_SEAM_LEFT_COL = {1.0f, 0.753f, 0.0f, 0.6f}; // FFC000 - golden +ColorRGBA GLVolume::PRECISE_SEAM_RIGHT_COL = {1.0f, 0.514f, 0.0f, 0.6f}; // FF8300 - dark orange +ColorRGBA GLVolume::PRECISE_SEAM_ENFORCED_COL = {0.412f, 0.820f, 0.412f, 0.6f}; // 69D169 - green +ColorRGBA GLVolume::PRECISE_SEAM_NEUTRAL_COL = {0.655f, 0.655f, 0.655f, 0.6f}; // A7A7A7 - gray +ColorRGBA GLVolume::PRECISE_SEAM_BLOCKED_COL = {0.820f, 0.412f, 0.412f, 0.6f}; // D16969 - red + std::array GLVolume::MODEL_COLOR = { { { 1.0f, 1.0f, 0.0f, 1.f }, { 1.0f, 0.5f, 0.5f, 1.f }, @@ -363,6 +371,28 @@ ColorRGBA color_from_model_volume(const ModelVolume& model_volume) ColorRGBA color; if (model_volume.is_negative_volume()) return GLVolume::MODEL_NEGTIVE_COL; + else if (model_volume.is_precise_seam()) { + // Return color based on Precise Seam subtype. + // Exhaustive switch (no default) so -Wswitch flags any future PRECISE_SEAM_* additions. + switch (model_volume.type()) { + case ModelVolumeType::PRECISE_SEAM_CENTER: return GLVolume::PRECISE_SEAM_CENTER_COL; + case ModelVolumeType::PRECISE_SEAM_LEFT: return GLVolume::PRECISE_SEAM_LEFT_COL; + case ModelVolumeType::PRECISE_SEAM_RIGHT: return GLVolume::PRECISE_SEAM_RIGHT_COL; + case ModelVolumeType::PRECISE_SEAM_ENFORCED: return GLVolume::PRECISE_SEAM_ENFORCED_COL; + case ModelVolumeType::PRECISE_SEAM_NEUTRAL: return GLVolume::PRECISE_SEAM_NEUTRAL_COL; + case ModelVolumeType::PRECISE_SEAM_BLOCKED: return GLVolume::PRECISE_SEAM_BLOCKED_COL; + // Non-seam types are unreachable due to the outer is_precise_seam() guard; + // listed explicitly so this switch stays exhaustive over ModelVolumeType. + case ModelVolumeType::INVALID: + case ModelVolumeType::MODEL_PART: + case ModelVolumeType::NEGATIVE_VOLUME: + case ModelVolumeType::PARAMETER_MODIFIER: + case ModelVolumeType::SUPPORT_BLOCKER: + case ModelVolumeType::SUPPORT_ENFORCER: + break; + } + return GLVolume::MODEL_MIDIFIER_COL; // unreachable fallback + } else if (model_volume.is_modifier()) #if ENABLE_MODIFIERS_ALWAYS_TRANSPARENT return GLVolume::MODEL_MIDIFIER_COL; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 1217d32182..b70cb4f565 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -93,6 +93,13 @@ public: static ColorRGBA SUPPORT_ENFORCER_COL; static ColorRGBA SUPPORT_BLOCKER_COL; static ColorRGBA MODEL_HIDDEN_COL; + // Precise Seam modifier colors + static ColorRGBA PRECISE_SEAM_CENTER_COL; + static ColorRGBA PRECISE_SEAM_LEFT_COL; + static ColorRGBA PRECISE_SEAM_RIGHT_COL; + static ColorRGBA PRECISE_SEAM_ENFORCED_COL; + static ColorRGBA PRECISE_SEAM_NEUTRAL_COL; + static ColorRGBA PRECISE_SEAM_BLOCKED_COL; static void update_render_colors(); static void load_render_colors(); diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index 61818deda9..dd2fef8be4 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -1018,11 +1018,12 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi // update if nozzle_temperature_range is found + const int variant_index = get_filament_variant_index(*filament_it, nozzle_diameter_str); ConfigOption *opt_min = filament_it->config.option("nozzle_temperature_range_low"); if (opt_min) { ConfigOptionInts *opt_min_ints = dynamic_cast(opt_min); if (opt_min_ints) { - wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0)); + wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(variant_index)); m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min); } } @@ -1030,7 +1031,7 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi if (opt_max) { ConfigOptionInts *opt_max_ints = dynamic_cast(opt_max); if (opt_max_ints) { - wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0)); + wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(variant_index)); m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max); } } @@ -1244,6 +1245,21 @@ void AMSMaterialsSetting::on_select_cali_result(wxCommandEvent &evt) } } +int AMSMaterialsSetting::get_filament_variant_index(const Preset &filament, const std::string &nozzle_diameter_str) +{ + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + if (!obj || !preset_bundle) + return 0; + const std::set printer_names = + preset_bundle->get_printer_names_by_printer_type_and_nozzle(DevPrinterConfigUtil::get_printer_display_name(obj->printer_type), nozzle_diameter_str); + const Preset *printer = printer_names.empty() ? nullptr : preset_bundle->printers.find_preset(*printer_names.begin()); + if (!printer) + return 0; + const int extruder_id = obj->get_extruder_id_by_ams_id(std::to_string(ams_id)); + return PresetBundle::get_filament_variant_index(filament.config, printer->config, obj->get_preset_extruder_index(extruder_id), + DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(extruder_id))); +} + void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) { // True for the popup's own initial selection: the dialog pre-filled the tray's @@ -1277,11 +1293,12 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) continue; if (!initial_printer_selection) { // ) if nozzle_temperature_range is found + const int variant_index = get_filament_variant_index(*it, nozzle_diameter_str); ConfigOption* opt_min = it->config.option("nozzle_temperature_range_low"); if (opt_min) { ConfigOptionInts* opt_min_ints = dynamic_cast(opt_min); if (opt_min_ints) { - wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0)); + wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(variant_index)); m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min); } } @@ -1289,7 +1306,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt) if (opt_max) { ConfigOptionInts* opt_max_ints = dynamic_cast(opt_max); if (opt_max_ints) { - wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0)); + wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(variant_index)); m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max); } } diff --git a/src/slic3r/GUI/AMSMaterialsSetting.hpp b/src/slic3r/GUI/AMSMaterialsSetting.hpp index 96118d706d..c9c0ffe7a2 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.hpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.hpp @@ -150,6 +150,8 @@ protected: void update_widgets(); void update_filament_editing(bool is_printing); + // Orca: the variant index of the filament's per-variant options on the nozzle this tray feeds + int get_filament_variant_index(const Preset &filament, const std::string &nozzle_diameter_str); protected: StateColor m_btn_bg_green; diff --git a/src/slic3r/GUI/Auxiliary.cpp b/src/slic3r/GUI/Auxiliary.cpp index 444daa4f91..67998b59d9 100644 --- a/src/slic3r/GUI/Auxiliary.cpp +++ b/src/slic3r/GUI/Auxiliary.cpp @@ -428,7 +428,7 @@ void AuFile::on_dclick(wxMouseEvent &evt) if (m_type == AddFileButton) return; else - wxLaunchDefaultApplication(m_file_path.wstring(), 0); + desktop_open_project_attachment(this, m_file_path); } void AuFile::on_mouse_left_up(wxMouseEvent &evt) diff --git a/src/slic3r/GUI/CAD/DesignOffer.hpp b/src/slic3r/GUI/CAD/DesignOffer.hpp index ad1998d5c5..fd15f537d3 100644 --- a/src/slic3r/GUI/CAD/DesignOffer.hpp +++ b/src/slic3r/GUI/CAD/DesignOffer.hpp @@ -1,5 +1,5 @@ // GENERATED FILE — DO NOT EDIT. -// Source: docs/ux/tool_atlas.json Generator: docs/ux/mockups/gen_offer_table.py +// Source: scripts/CAD/tool_atlas.json Generator: scripts/CAD/gen_offer_table.py // // The object-driven tool offer (charter 4.1): every verb has ONE row index, that index // is the same in every selection it appears in, and verbs that do not apply are shown diff --git a/src/slic3r/GUI/CAD/DesignPanel.cpp b/src/slic3r/GUI/CAD/DesignPanel.cpp index d247ddfd26..5f64025f2b 100644 --- a/src/slic3r/GUI/CAD/DesignPanel.cpp +++ b/src/slic3r/GUI/CAD/DesignPanel.cpp @@ -1,7 +1,7 @@ #include "slic3r/GUI/CAD/DesignPanel.hpp" #include "slic3r/GUI/CAD/DesignCanvas.hpp" #include "slic3r/GUI/CAD/DesignSketchTool.hpp" -#include "slic3r/GUI/CAD/DesignOffer.hpp" // generated offer table — see docs/ux/tool_atlas.json +#include "slic3r/GUI/CAD/DesignOffer.hpp" // generated offer table — see scripts/CAD/tool_atlas.json #include "libslic3r/CAD/GeometryEngine.hpp" // face_by_index for face-extrude gizmo anchor #include "libslic3r/TriangleMesh.hpp" // mesh import: STL/OBJ -> indexed_triangle_set #include "libslic3r/Format/OBJ.hpp" @@ -6067,7 +6067,7 @@ bool DesignPanel::sketch_plane_target(wxString& what) const // --------------------------------------------------------------------------------------------- // The object-driven offer (charter §4.1). Right-click the geometry and get a vertical list in the // ratified row order, with the verbs that do not apply DISABLED IN PLACE carrying their reason. -// The rows come from DesignOffer.hpp, generated from docs/ux/tool_atlas.json — the same file the +// The rows come from DesignOffer.hpp, generated from scripts/CAD/tool_atlas.json — the same file the // mockups are drawn from, so a drawing and the product cannot drift apart. // --------------------------------------------------------------------------------------------- diff --git a/src/slic3r/GUI/CAD/DesignSketchTool.cpp b/src/slic3r/GUI/CAD/DesignSketchTool.cpp index 716df658ed..c195d6a877 100644 --- a/src/slic3r/GUI/CAD/DesignSketchTool.cpp +++ b/src/slic3r/GUI/CAD/DesignSketchTool.cpp @@ -4034,7 +4034,7 @@ void DesignSketchTool::render_mate_connectors() // the information. The same bear rendered flat vs in relief gives 164 vs 210 lit pixels at 16 // degrees and 66 vs 120 at 6. So the glyph is a small shaded solid, not an outline. // -// The geometry is EMITTED from the real part by doc/design/mate-connectors/emit_glyph_table.py, +// The geometry is EMITTED from the real part by scripts/CAD/mate-glyph/emit_glyph_table.py, // not hand-drawn, so the glyph and the printed connector cannot drift apart. Two vertices stand // above the 3 mm plate in the actual B-rep, which is why the snout here is a tent with one crest // edge and four flanks drafted at 20 degrees rather than anything more elaborate. @@ -4042,7 +4042,7 @@ void DesignSketchTool::render_mate_connectors() // The cheek dot is the handedness mark. Without it the glyph differs from its own mirror by only // 5-9 % of its lit pixels, which is not enough to read; the dot roughly doubles that and, unlike // making the eyes uneven, identifies the side from that cheek alone instead of by comparison. -// Emitted by doc/design/mate-connectors/emit_glyph_table.py from bear.step — do not hand-edit. +// Emitted by scripts/CAD/mate-glyph/emit_glyph_table.py from bear.step — do not hand-edit. // Normalised to the part's bounding span and centred: the renderer scales by one radius. static const Vec2d kBearOutline[] = { // 12 verts, RDP eps 0.030, CCW {+0.3842, +0.3294}, {+0.3156, +0.4002}, {+0.2424, +0.3294}, diff --git a/src/slic3r/GUI/CaliHistoryDialog.cpp b/src/slic3r/GUI/CaliHistoryDialog.cpp index c3fc1af721..ba7f6e268b 100644 --- a/src/slic3r/GUI/CaliHistoryDialog.cpp +++ b/src/slic3r/GUI/CaliHistoryDialog.cpp @@ -824,12 +824,14 @@ NewCalibrationHistoryDialog::NewCalibrationHistoryDialog(wxWindow *parent, const if (support_nozzle_volume(curr_obj)) { Label *nozzle_name_title = new Label(top_panel, _L("Nozzle")); m_comboBox_nozzle_type = new ::ComboBox(top_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, NEW_HISTORY_DIALOG_INPUT_SIZE, 0, nullptr, wxCB_READONLY); - wxArrayString nozzle_items; + // The labels are in display order, not enum order (E3D High Flow is 5 but the fifth label), so each + // item carries its NozzleVolumeType as client data. const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type"); if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) { - for (auto item : nozzle_volume_type_def->enum_labels) { nozzle_items.push_back(_L(item)); } + for (size_t i = 0; i < nozzle_volume_type_def->enum_labels.size(); ++i) + m_comboBox_nozzle_type->Append(_L(nozzle_volume_type_def->enum_labels[i]), wxNullBitmap, + (void *) (intptr_t) nozzle_volume_type_def->enum_keys_map->at(nozzle_volume_type_def->enum_values[i])); } - m_comboBox_nozzle_type->Set(nozzle_items); m_comboBox_nozzle_type->SetSelection(-1); flex_sizer->Add(nozzle_name_title); flex_sizer->Add(m_comboBox_nozzle_type); @@ -897,7 +899,7 @@ int NewCalibrationHistoryDialog::get_nozzle_combo_id_code() const void NewCalibrationHistoryDialog::on_select_nozzle_pos(wxCommandEvent &event) { - // Mirror the picked hotend's flow onto the (Orca index-based) nozzle-type combo. + // Mirror the picked hotend's flow onto the nozzle-type combo. if (!curr_obj || !m_comboBox_nozzle_id || !m_comboBox_nozzle_type || !curr_obj->GetNozzleSystem()) return; @@ -908,7 +910,9 @@ void NewCalibrationHistoryDialog::on_select_nozzle_pos(wxCommandEvent &event) DevNozzle nozzle = curr_obj->GetNozzleSystem()->GetNozzleByPosId(pos); if (nozzle.IsNormal()) { NozzleVolumeType volume_type = DevNozzle::ToNozzleVolumeType(nozzle.GetNozzleFlowType()); - m_comboBox_nozzle_type->SetSelection(static_cast(volume_type)); + for (unsigned int i = 0; i < m_comboBox_nozzle_type->GetCount(); ++i) + if (NozzleVolumeType(intptr_t(m_comboBox_nozzle_type->GetClientData(i))) == volume_type) + m_comboBox_nozzle_type->SetSelection(i); } } @@ -955,7 +959,7 @@ void NewCalibrationHistoryDialog::on_ok(wxCommandEvent &event) msg_dlg.ShowModal(); return; } - m_new_result.nozzle_volume_type = NozzleVolumeType(m_comboBox_nozzle_type->GetSelection()); + m_new_result.nozzle_volume_type = NozzleVolumeType(intptr_t(m_comboBox_nozzle_type->GetClientData(m_comboBox_nozzle_type->GetSelection()))); } auto filament_item = map_filament_items[m_comboBox_filament->GetValue().ToStdString()]; diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp index 84554dcfb0..01c9843305 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp @@ -805,6 +805,29 @@ void CalibrationPresetPage::create_selection_panel(wxWindow* parent) #define NOZZLE_LIST_DEFAULT 1 float nozzle_diameter_list[NOZZLE_LIST_COUNT] = {0.2, 0.4, 0.6, 0.8 }; +// The nozzle_volume_type labels are in display order, not enum order (E3D High Flow is 5 but the fifth +// label), so each item carries its NozzleVolumeType as client data and is selected by that value. +static void select_nozzle_volume(ComboBox *combo, NozzleVolumeType volume_type) +{ + for (unsigned int i = 0; i < combo->GetCount(); ++i) + if (NozzleVolumeType(intptr_t(combo->GetClientData(i))) == volume_type) { + combo->SetSelection(i); + return; + } +} + +static void fill_nozzle_volume_combo(ComboBox *combo) +{ + combo->Clear(); + const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type"); + if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) { + for (size_t i = 0; i < nozzle_volume_type_def->enum_labels.size(); ++i) + combo->Append(_L(nozzle_volume_type_def->enum_labels[i]), wxNullBitmap, + (void *) (intptr_t) nozzle_volume_type_def->enum_keys_map->at(nozzle_volume_type_def->enum_values[i])); + } + select_nozzle_volume(combo, NozzleVolumeType::nvtStandard); +} + void CalibrationPresetPage::init_selection_values() { // init nozzle diameter and nozzle volume @@ -815,15 +838,7 @@ void CalibrationPresetPage::init_selection_values() } m_comboBox_nozzle_dia->SetSelection(NOZZLE_LIST_DEFAULT); - m_comboBox_nozzle_volume->Clear(); - const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type"); - if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) { - for (auto item : nozzle_volume_type_def->enum_labels) { - m_comboBox_nozzle_volume->AppendString(_L(item)); - } - } - - m_comboBox_nozzle_volume->SetSelection(int(NozzleVolumeType::nvtStandard)); + fill_nozzle_volume_combo(m_comboBox_nozzle_volume); } Preset* cur_printer_preset = get_printer_preset(curr_obj, 0.4); @@ -868,15 +883,7 @@ void CalibrationPresetPage::init_selection_values() } m_left_comboBox_nozzle_dia->SetSelection(NOZZLE_LIST_DEFAULT); - m_left_comboBox_nozzle_volume->Clear(); - const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type"); - if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) { - for (auto item : nozzle_volume_type_def->enum_labels) { - m_left_comboBox_nozzle_volume->AppendString(_L(item)); - } - } - - m_left_comboBox_nozzle_volume->SetSelection(int(NozzleVolumeType::nvtStandard)); + fill_nozzle_volume_combo(m_left_comboBox_nozzle_volume); } // right @@ -887,15 +894,7 @@ void CalibrationPresetPage::init_selection_values() } m_right_comboBox_nozzle_dia->SetSelection(NOZZLE_LIST_DEFAULT); - m_right_comboBox_nozzle_volume->Clear(); - const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type"); - if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) { - for (auto item : nozzle_volume_type_def->enum_labels) { - m_right_comboBox_nozzle_volume->AppendString(_L(item)); - } - } - - m_right_comboBox_nozzle_volume->SetSelection(int(NozzleVolumeType::nvtStandard)); + fill_nozzle_volume_combo(m_right_comboBox_nozzle_volume); } } @@ -982,13 +981,13 @@ NozzleVolumeType CalibrationPresetPage::get_nozzle_volume_type(int extruder_id) if (curr_obj) { if (curr_obj->is_multi_extruders()) { if (extruder_id == LEFT_EXTRUDER_ID) { - return NozzleVolumeType(m_left_comboBox_nozzle_volume->GetSelection()); + return NozzleVolumeType(intptr_t(m_left_comboBox_nozzle_volume->GetClientData(m_left_comboBox_nozzle_volume->GetSelection()))); } else if (extruder_id == RIGHT_EXTRUDER_ID) { - return NozzleVolumeType(m_right_comboBox_nozzle_volume->GetSelection()); + return NozzleVolumeType(intptr_t(m_right_comboBox_nozzle_volume->GetClientData(m_right_comboBox_nozzle_volume->GetSelection()))); } } else - return NozzleVolumeType(m_comboBox_nozzle_volume->GetSelection()); + return NozzleVolumeType(intptr_t(m_comboBox_nozzle_volume->GetClientData(m_comboBox_nozzle_volume->GetSelection()))); } return NozzleVolumeType::nvtStandard; } @@ -2126,7 +2125,7 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj) } if (obj->GetExtderSystem()->GetNozzleFlowType(i) != NozzleFlowType::NONE_FLOWTYPE) { - m_left_comboBox_nozzle_volume->SetSelection(int(DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(i)))); + select_nozzle_volume(m_left_comboBox_nozzle_volume, DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(i))); } else { m_left_comboBox_nozzle_volume->SetSelection(0); } @@ -2146,7 +2145,7 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj) } if (obj->GetExtderSystem()->GetNozzleFlowType(i) != NozzleFlowType::NONE_FLOWTYPE) { - m_right_comboBox_nozzle_volume->SetSelection(int(DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(i)))); + select_nozzle_volume(m_right_comboBox_nozzle_volume, DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(i))); } else { m_right_comboBox_nozzle_volume->SetSelection(0); } @@ -2184,7 +2183,7 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj) else { if ((obj->GetExtderSystem()->GetTotalExtderCount() > 0) && (obj->GetExtderSystem()->GetNozzleFlowType(0) != NozzleFlowType::NONE_FLOWTYPE)) { - m_comboBox_nozzle_volume->SetSelection(int(DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(0)))); + select_nozzle_volume(m_comboBox_nozzle_volume, DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(0))); } else { m_comboBox_nozzle_volume->SetSelection(0); } diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.cpp b/src/slic3r/GUI/CalibrationWizardSavePage.cpp index 427f022d1c..fdff760078 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.cpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.cpp @@ -732,6 +732,7 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< case NozzleVolumeType::nvtStandard: nozzle_id_str += _L("Standard Flow"); break; case NozzleVolumeType::nvtHighFlow: nozzle_id_str += _L("High Flow"); break; case NozzleVolumeType::nvtTPUHighFlow: nozzle_id_str += _L("TPU High Flow"); break; + case NozzleVolumeType::nvtE3DHighFlow: nozzle_id_str += _L("E3D High Flow"); break; default: break; } nozzle_id_value->SetLabel(nozzle_id_str); diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 5a58ec7b6c..fa8e2e5f16 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -78,12 +78,12 @@ void ConfigManipulation::set_option_label(const std::string& opt_key, const wxSt cb_set_option_label(opt_key, label, opt_index); } -void ConfigManipulation::check_nozzle_recommended_temperature_range(DynamicPrintConfig *config) { +void ConfigManipulation::check_nozzle_recommended_temperature_range(DynamicPrintConfig *config, unsigned int variant_index) { if (is_msg_dlg_already_exist) return; int temperature_range_low, temperature_range_high; - if (!get_temperature_range(config, temperature_range_low, temperature_range_high)) return; + if (!get_temperature_range(config, temperature_range_low, temperature_range_high, variant_index)) return; // Get the selected filament type std::string filament_type = ""; @@ -123,16 +123,16 @@ void ConfigManipulation::check_nozzle_recommended_temperature_range(DynamicPrint } } -void ConfigManipulation::check_nozzle_temperature_range(DynamicPrintConfig *config) +void ConfigManipulation::check_nozzle_temperature_range(DynamicPrintConfig *config, unsigned int variant_index) { if (is_msg_dlg_already_exist) return; int temperature_range_low, temperature_range_high; - if (!get_temperature_range(config, temperature_range_low, temperature_range_high)) return; + if (!get_temperature_range(config, temperature_range_low, temperature_range_high, variant_index)) return; if (config->has("nozzle_temperature")) { - if (config->opt_int("nozzle_temperature", 0) < temperature_range_low || config->opt_int("nozzle_temperature", 0) > temperature_range_high) { + if (config->opt_int("nozzle_temperature", variant_index) < temperature_range_low || config->opt_int("nozzle_temperature", variant_index) > temperature_range_high) { wxString msg_text = _(L("The nozzle may become clogged when the temperature is out of the recommended range.\nPlease make sure whether to use this temperature to print.\n\n")); msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high); MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK); @@ -143,17 +143,17 @@ void ConfigManipulation::check_nozzle_temperature_range(DynamicPrintConfig *conf } } -void ConfigManipulation::check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config) +void ConfigManipulation::check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config, unsigned int variant_index) { if (is_msg_dlg_already_exist) return; int temperature_range_low, temperature_range_high; - if (!get_temperature_range(config, temperature_range_low, temperature_range_high)) return; + if (!get_temperature_range(config, temperature_range_low, temperature_range_high, variant_index)) return; if (config->has("nozzle_temperature_initial_layer")) { - if (config->opt_int("nozzle_temperature_initial_layer", 0) < temperature_range_low || - config->opt_int("nozzle_temperature_initial_layer", 0) > temperature_range_high) + if (config->opt_int("nozzle_temperature_initial_layer", variant_index) < temperature_range_low || + config->opt_int("nozzle_temperature_initial_layer", variant_index) > temperature_range_high) { wxString msg_text = _(L("The nozzle may become clogged when the temperature is out of the recommended range.\nPlease make sure whether to use this temperature to print.\n\n")); msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high); @@ -171,14 +171,16 @@ void ConfigManipulation::check_adaptive_pressure_advance_model(DynamicPrintConfi return; const auto* model = config->option("adaptive_pressure_advance_model"); - if (model == nullptr || model->values.empty()) + if (model == nullptr) return; - std::string raw_model; - for (const std::string& chunk : model->values) - raw_model += chunk; - - std::string error = AdaptivePAProcessor::validate_adaptive_pa_model(raw_model); + // Each extruder variant holds its own model. + std::string error; + for (const std::string& variant_model : model->values) { + error = AdaptivePAProcessor::validate_adaptive_pa_model(variant_model); + if (!error.empty()) + break; + } if (!error.empty()) { wxString msg_text = _L("Adaptive Pressure Advance model validation failed:\n"); msg_text += from_u8(error); @@ -1293,15 +1295,15 @@ int ConfigManipulation::show_spiral_mode_settings_dialog(bool is_object_config) return answer; } -bool ConfigManipulation::get_temperature_range(DynamicPrintConfig *config, int &range_low, int &range_high) +bool ConfigManipulation::get_temperature_range(DynamicPrintConfig *config, int &range_low, int &range_high, unsigned int variant_index) { bool range_low_exist = false, range_high_exist = false; if (config->has("nozzle_temperature_range_low")) { - range_low = config->opt_int("nozzle_temperature_range_low", (unsigned int) 0); + range_low = config->opt_int("nozzle_temperature_range_low", variant_index); range_low_exist = true; } if (config->has("nozzle_temperature_range_high")) { - range_high = config->opt_int("nozzle_temperature_range_high", (unsigned int) 0); + range_high = config->opt_int("nozzle_temperature_range_high", variant_index); range_high_exist = true; } return range_low_exist && range_high_exist; diff --git a/src/slic3r/GUI/ConfigManipulation.hpp b/src/slic3r/GUI/ConfigManipulation.hpp index ac53ffb4bb..a7a1a7ef77 100644 --- a/src/slic3r/GUI/ConfigManipulation.hpp +++ b/src/slic3r/GUI/ConfigManipulation.hpp @@ -79,9 +79,9 @@ public: void apply_null_fff_config(DynamicPrintConfig *config, std::vector const &keys, std::map const & configs); //BBS: FFF filament nozzle temperature range - void check_nozzle_recommended_temperature_range(DynamicPrintConfig *config); - void check_nozzle_temperature_range(DynamicPrintConfig* config); - void check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config); + void check_nozzle_recommended_temperature_range(DynamicPrintConfig *config, unsigned int variant_index); + void check_nozzle_temperature_range(DynamicPrintConfig* config, unsigned int variant_index); + void check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config, unsigned int variant_index); void check_adaptive_pressure_advance_model(DynamicPrintConfig* config); void check_filament_max_volumetric_speed(DynamicPrintConfig *config); void check_chamber_temperature(DynamicPrintConfig* config); @@ -104,7 +104,7 @@ public: int show_spiral_mode_settings_dialog(bool is_object_config = false); private: - bool get_temperature_range(DynamicPrintConfig *config, int &range_low, int &range_high); + bool get_temperature_range(DynamicPrintConfig *config, int &range_low, int &range_high, unsigned int variant_index); }; } // GUI diff --git a/src/slic3r/GUI/DeviceCore/DevCalib.cpp b/src/slic3r/GUI/DeviceCore/DevCalib.cpp index ddf71e0c62..6385fa77c6 100644 --- a/src/slic3r/GUI/DeviceCore/DevCalib.cpp +++ b/src/slic3r/GUI/DeviceCore/DevCalib.cpp @@ -36,7 +36,8 @@ static NozzleVolumeType convert_to_nozzle_type(const std::string &str) return NozzleVolumeType::nvtHighFlow; else if (str[1] == 'U') return NozzleVolumeType::nvtTPUHighFlow; - // Orca: no nvtE3DHighFlow in Orca's NozzleVolumeType; map 'B' to Standard + else if (str[1] == 'B') + return NozzleVolumeType::nvtE3DHighFlow; else return NozzleVolumeType::nvtStandard; } diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp index 578149b9d3..9f1b5311c2 100644 --- a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp @@ -13,7 +13,7 @@ namespace Slic3r { -// ---- DevNozzle: flow/volume conversions (Standard / High Flow / TPU High Flow) ---------------------- +// ---- DevNozzle: flow/volume conversions (Standard / High Flow / TPU High Flow / E3D High Flow) ------ // Device-reported U_FLOW nozzles map to nvtTPUHighFlow so a synced TPU-HF rack activates the H2C // change_filament_gcode TPU-kit branch. nvtHybrid is a slicer-only sentinel with no device // representation, so ToNozzleFlowType(nvtHybrid) falls through to NONE_FLOWTYPE. @@ -24,6 +24,7 @@ NozzleFlowType DevNozzle::ToNozzleFlowType(const NozzleVolumeType& type) case NozzleVolumeType::nvtStandard: return NozzleFlowType::S_FLOW; case NozzleVolumeType::nvtHighFlow: return NozzleFlowType::H_FLOW; case NozzleVolumeType::nvtTPUHighFlow: return NozzleFlowType::U_FLOW; + case NozzleVolumeType::nvtE3DHighFlow: return NozzleFlowType::E_FLOW; default: return NozzleFlowType::NONE_FLOWTYPE; } } @@ -34,6 +35,7 @@ NozzleVolumeType DevNozzle::ToNozzleVolumeType(const NozzleFlowType& type) case NozzleFlowType::S_FLOW: return NozzleVolumeType::nvtStandard; case NozzleFlowType::H_FLOW: return NozzleVolumeType::nvtHighFlow; case NozzleFlowType::U_FLOW: return NozzleVolumeType::nvtTPUHighFlow; + case NozzleFlowType::E_FLOW: return NozzleVolumeType::nvtE3DHighFlow; default: { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "nozzle flow type None convert to nozzle volume type Standard"; return NozzleVolumeType::nvtStandard; @@ -47,6 +49,7 @@ wxString DevNozzle::GetNozzleFlowTypeStr(NozzleFlowType type) case NozzleFlowType::H_FLOW: return _L("High Flow"); case NozzleFlowType::S_FLOW: return _L("Standard"); case NozzleFlowType::U_FLOW: return _L("TPU High Flow"); + case NozzleFlowType::E_FLOW: return _L("E3D High Flow"); default: break; } @@ -61,6 +64,7 @@ std::string DevNozzle::GetNozzleFlowTypeString(NozzleFlowType type) case NozzleFlowType::H_FLOW: return "High Flow"; case NozzleFlowType::S_FLOW: return "Standard"; case NozzleFlowType::U_FLOW: return "TPU High Flow"; + case NozzleFlowType::E_FLOW: return "E3D High Flow"; default: return "Unknown"; } } @@ -73,6 +77,7 @@ std::string DevNozzle::ToNozzleFlowString(const NozzleFlowType& type) case NozzleFlowType::S_FLOW: return "Standard"; case NozzleFlowType::H_FLOW: return "High Flow"; case NozzleFlowType::U_FLOW: return "TPU High Flow"; + case NozzleFlowType::E_FLOW: return "E3D High Flow"; default: return std::string(); } } @@ -408,6 +413,7 @@ static unordered_map _str2_nozzle_flow_type = { {"X", NozzleFlowType::S_FLOW}, {"E", NozzleFlowType::H_FLOW}, // E3D high-flow {"U", NozzleFlowType::U_FLOW}, // TPU 1.75 high-flow -> nvtTPUHighFlow + {"B", NozzleFlowType::E_FLOW}, // E3D High Flow -> nvtE3DHighFlow }; static unordered_map _str2_nozzle_type = { diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h index 8603baeaaf..168cb94116 100644 --- a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h +++ b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h @@ -12,8 +12,9 @@ // Device flow-type mapping note (nozzle rack): the device U_FLOW value maps to nvtTPUHighFlow // (TPU High Flow), so a device-synced TPU-HF rack resolves to nvtTPUHighFlow and the H2C -// change_filament_gcode TPU-kit branch can activate. nvtHybrid is a slicer-only sentinel with no -// device representation, so it stays out of these device flow-type conversions. +// change_filament_gcode TPU-kit branch can activate. E_FLOW maps to nvtE3DHighFlow. nvtHybrid is a +// slicer-only sentinel with no device representation, so it stays out of these device flow-type +// conversions. // // GetExtruderNozzleInfo (and its ExtruderNozzleInfos aggregate) is intentionally omitted here; // the SelectMachine slicing-vs-installed nozzle comparison collects its per-extruder NozzleDef @@ -36,13 +37,13 @@ namespace Slic3r float m_diameter = 0.0f;// unknown until reported by the printer public: - // flow/volume conversions (Standard / High Flow / TPU High Flow) + // flow/volume conversions (Standard / High Flow / TPU High Flow / E3D High Flow) static NozzleFlowType ToNozzleFlowType(const NozzleVolumeType& type); static NozzleVolumeType ToNozzleVolumeType(const NozzleFlowType& type); static wxString GetNozzleFlowTypeStr(NozzleFlowType type); - static std::string GetNozzleFlowTypeString(NozzleFlowType type);// untranslated literal ("High Flow"/"Standard"/"TPU High Flow") — the filament blacklist JSON matches these raw strings, so it must NOT use the translated GetNozzleFlowTypeStr (would break non-English locales) - static std::string ToNozzleFlowString(const NozzleFlowType& type);// untranslated "Standard"/"High Flow"/"TPU High Flow" ("" for none) — the raw literal serialized into the get_auto_nozzle_mapping payload + static std::string GetNozzleFlowTypeString(NozzleFlowType type);// untranslated literal ("High Flow"/"Standard"/"TPU High Flow"/"E3D High Flow") — the filament blacklist JSON matches these raw strings, so it must NOT use the translated GetNozzleFlowTypeStr (would break non-English locales) + static std::string ToNozzleFlowString(const NozzleFlowType& type);// untranslated "Standard"/"High Flow"/"TPU High Flow"/"E3D High Flow" ("" for none) — the raw literal serialized into the get_auto_nozzle_mapping payload static wxString GetNozzleTypeStr(NozzleType type); public: diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 18d5e7f14b..ffcfbcc68b 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -350,6 +350,10 @@ static wxString _generate_nozzle_id(NozzleVolumeType nozzle_type, const std::str nozzle_id += "H"; break; } + case NozzleVolumeType::nvtE3DHighFlow: { + nozzle_id += "B"; + break; + } default: nozzle_id += "H"; break; @@ -371,6 +375,8 @@ NozzleVolumeType convert_to_nozzle_type(const std::string &str) res = NozzleVolumeType::nvtStandard; else if (str[1] == 'H') res = NozzleVolumeType::nvtHighFlow; + else if (str[1] == 'B') + res = NozzleVolumeType::nvtE3DHighFlow; return res; } @@ -5014,7 +5020,8 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil std::string subtask_json; unsigned http_code = 0; std::string http_body; - if (m_agent->get_subtask_info(subtask_id, &subtask_json, &http_code, &http_body) == 0) { + if (m_agent->get_subtask_info(subtask_id, &subtask_json, &http_code, &http_body, + Slic3r::GUI::wxGetApp().get_printer_cloud_provider()) == 0) { try { if (!subtask_json.empty()) { @@ -5786,7 +5793,7 @@ void MachineObject::update_filament_list() PresetBundle *preset_bundle = Slic3r::GUI::wxGetApp().preset_bundle; // custom filament - typedef std::map> map_pair; + typedef std::map, std::vector>> map_pair; std::map map_list; for (auto &pair : m_nozzle_filament_data) { map_list[pair.second.printer_preset_name] = map_pair{}; @@ -5798,19 +5805,13 @@ void MachineObject::update_filament_list() for (const std::string &printer_str : printer_strs->values) { if (map_list.find(printer_str) != map_list.end()) { auto & filament_list = map_list[printer_str]; - ConfigOption *opt_min = const_cast(preset).config.option("nozzle_temperature_range_low"); - int min_temp = -1; - if (opt_min) { - ConfigOptionInts *opt_min_ints = dynamic_cast(opt_min); - min_temp = opt_min_ints->get_at(0); - } - ConfigOption *opt_max = const_cast(preset).config.option("nozzle_temperature_range_high"); - int max_temp = -1; - if (opt_max) { - ConfigOptionInts *opt_max_ints = dynamic_cast(opt_max); - max_temp = opt_max_ints->get_at(0); - } - filament_list[preset.filament_id] = std::make_pair(min_temp, max_temp); + // Every variant's range, so a change to any of them rechecks the trays + std::vector min_temps{-1}, max_temps{-1}; + if (auto *opt_min = preset.config.option("nozzle_temperature_range_low")) + min_temps = opt_min->values; + if (auto *opt_max = preset.config.option("nozzle_temperature_range_high")) + max_temps = opt_max->values; + filament_list[preset.filament_id] = std::make_pair(min_temps, max_temps); break; } } @@ -5946,10 +5947,13 @@ void MachineObject::check_ams_filament_valid() need_checked_filament_id[nozzle_diameter_str].insert(curr_tray->setting_id); try { std::string preset_setting_id; + const int extruder_id = ams->GetExtruderId(); bool is_equation = preset_bundle->check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray(printer_model, nozzle_diameter_str, curr_tray->setting_id, curr_tray->tag_uid, curr_tray->nozzle_temp_min, - curr_tray->nozzle_temp_max, preset_setting_id); + curr_tray->nozzle_temp_max, preset_setting_id, + get_preset_extruder_index(extruder_id), + DevNozzle::ToNozzleVolumeType(m_extder_system->GetNozzleFlowType(extruder_id))); if (!is_equation) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << __LINE__ << " ams filament is not match min max temp and reset, ams_id: " << ams_id << " tray_id" << slot_id << "filament_id: " << curr_tray->setting_id; @@ -6014,7 +6018,9 @@ void MachineObject::check_ams_filament_valid() this->printer_type), nozzle_diameter_str, vt_tray.setting_id, vt_tray.tag_uid, vt_tray.nozzle_temp_min, - vt_tray.nozzle_temp_max, preset_setting_id); + vt_tray.nozzle_temp_max, preset_setting_id, + get_preset_extruder_index(index), + DevNozzle::ToNozzleVolumeType(m_extder_system->GetNozzleFlowType(index))); if (!is_equation) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << __LINE__ << " vt_tray filament is not match min max temp and reset, filament_id: " << vt_tray.setting_id; diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index d7595bff03..20047c6eba 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -314,7 +314,7 @@ public: bool ams_support_virtual_tray { true }; time_t ams_user_setting_start = 0; time_t ams_switch_filament_start = 0; - AmsStatusMain ams_status_main; + AmsStatusMain ams_status_main = AmsStatusMain::AMS_STATUS_MAIN_IDLE; int ams_status_sub; int ams_version = 0; @@ -348,6 +348,8 @@ public: bool is_main_extruder_on_left() const { return false; } // only means the extruder is on the left hand when extruder id is 0 bool is_multi_extruders() const; int get_extruder_id_by_ams_id(const std::string& ams_id); + // Orca: the printer preset's extruder index of device extruder extder_id + int get_preset_extruder_index(int extder_id) const { return is_multi_extruders() ? (is_main_extruder_on_left() ? extder_id : 1 - extder_id) : 0; } /* E3D has extra nozzle flow type info */ bool has_extra_flow_type{false}; @@ -971,7 +973,8 @@ public: { std::set checked_filament; std::string printer_preset_name; - std::map> filament_list; // filament_id, pair + // filament_id, pair, one per filament variant + std::map, std::vector>> filament_list; }; std::map m_nozzle_filament_data; void update_filament_list(); diff --git a/src/slic3r/GUI/DownloaderFileGet.cpp b/src/slic3r/GUI/DownloaderFileGet.cpp index 6ad07c43d2..4a7269affa 100644 --- a/src/slic3r/GUI/DownloaderFileGet.cpp +++ b/src/slic3r/GUI/DownloaderFileGet.cpp @@ -71,17 +71,6 @@ bool FileGet::is_subdomain(const std::string& url, const std::string& domain) return false; } -namespace { -unsigned get_current_pid() -{ -#ifdef WIN32 - return GetCurrentProcessId(); -#else - return ::getpid(); -#endif -} -} - // int = DOWNLOAD ID; string = file path wxDEFINE_EVENT(EVT_DWNLDR_FILE_COMPLETE, wxCommandEvent); // int = DOWNLOAD ID; string = error msg @@ -144,25 +133,10 @@ void FileGet::priv::get_perform() std::string extension; if (m_written == 0) { - boost::filesystem::path dest_path = m_dest_folder / m_filename; - extension = dest_path.extension().string(); - std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size()); - std::string final_filename = just_filename; - // Find unsed filename + std::string final_filename; + bool found = false; try { - size_t version = 0; - while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)) || boost::filesystem::exists(m_dest_folder / (final_filename + extension + "." + std::to_string(get_current_pid()) + ".download"))) - { - ++version; - if (version > 999) { - wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); - evt->SetString(GUI::format_wxstr(L"Failed to find suitable filename. Last name: %1%." , (m_dest_folder / (final_filename + extension)).string())); - evt->SetInt(m_id); - m_evt_handler->QueueEvent(evt); - return; - } - final_filename = GUI::format("%1%(%2%)", just_filename, std::to_string(version)); - } + found = find_unused_filename(m_dest_folder, m_filename, m_tmp_path, final_filename); } catch (const boost::filesystem::filesystem_error& e) { wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); @@ -171,10 +145,18 @@ void FileGet::priv::get_perform() m_evt_handler->QueueEvent(evt); return; } + if (!found) { + wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); + evt->SetString(GUI::format_wxstr(L"Failed to find suitable filename. Last name: %1%." , (m_dest_folder / final_filename).string())); + evt->SetInt(m_id); + m_evt_handler->QueueEvent(evt); + return; + } - m_filename = sanitize_filename(final_filename + extension); + m_filename = final_filename; + extension = boost::filesystem::path(m_filename).extension().string(); - m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download"); + m_tmp_path = download_marker_path(m_dest_folder, m_filename); wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE); evt->SetString(boost::nowide::widen(m_filename)); @@ -221,7 +203,32 @@ void FileGet::priv::get_perform() if(dest_path.empty()) { std::string filename = extract_remote_filename(header); if (!filename.empty()) { - m_filename = filename; + // The name comes from the server: keep it inside the destination folder and never + // replace an existing file. Keep the current name if nothing usable remains. + filename = sanitize_file_basename(filename); + std::string unused; + try { + if (filename.empty() || !find_unused_filename(m_dest_folder, filename, m_tmp_path, unused)) + unused.clear(); + } catch (const boost::filesystem::filesystem_error&) { + unused.clear(); + } + const boost::filesystem::path tmp_path = unused.empty() ? m_tmp_path : download_marker_path(m_dest_folder, unused); + if (tmp_path != m_tmp_path) { + // Move the marker to the adopted name so that other downloads see the name as taken. + // Only before anything is written, so that no downloaded data has to be carried over. + FILE* tmp_file = m_written == 0 ? fopen(wxString(tmp_path.wstring()).c_str(), "wb") : nullptr; + if (tmp_file != nullptr) { + fclose(file); + boost::system::error_code ec; + boost::filesystem::remove(m_tmp_path, ec); + file = tmp_file; + m_tmp_path = tmp_path; + } else + unused.clear(); + } + if (!unused.empty()) + m_filename = unused; dest_path = m_dest_folder / m_filename; wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE); evt->SetString(boost::nowide::widen(m_filename)); @@ -327,6 +334,18 @@ void FileGet::priv::get_perform() m_evt_handler->QueueEvent(evt); } fclose(file); + // Another file may have taken the name while downloading. + if (!dest_path.empty() && boost::filesystem::exists(dest_path)) { + std::string unused; + if (!find_unused_filename(m_dest_folder, m_filename, m_tmp_path, unused)) + throw std::runtime_error("No unused file name."); + m_filename = unused; + dest_path = m_dest_folder / m_filename; + wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE); + evt->SetString(boost::nowide::widen(m_filename)); + evt->SetInt(m_id); + m_evt_handler->QueueEvent(evt); + } boost::filesystem::rename(m_tmp_path, dest_path); } catch (const std::exception& /*e*/) diff --git a/src/slic3r/GUI/DragDropPanel.cpp b/src/slic3r/GUI/DragDropPanel.cpp index 0c1371c307..41c31d927b 100644 --- a/src/slic3r/GUI/DragDropPanel.cpp +++ b/src/slic3r/GUI/DragDropPanel.cpp @@ -566,7 +566,8 @@ std::vector SeparatedDragDropPanel::GetHighFlowFilaments() const const int right_eid = 1; if (nozzle_volumes->values.size() > right_eid) { int volume_type = nozzle_volumes->values[right_eid]; - if (volume_type == static_cast(NozzleVolumeType::nvtHighFlow)) { + if (volume_type == static_cast(NozzleVolumeType::nvtHighFlow) || + volume_type == static_cast(NozzleVolumeType::nvtE3DHighFlow)) { return m_unified_panel->GetAllFilaments(); } } diff --git a/src/slic3r/GUI/FilamentMapPanel.cpp b/src/slic3r/GUI/FilamentMapPanel.cpp index 0f3cc7217d..bd7d42333b 100644 --- a/src/slic3r/GUI/FilamentMapPanel.cpp +++ b/src/slic3r/GUI/FilamentMapPanel.cpp @@ -185,6 +185,12 @@ std::vector FilamentMapManualPanel::GetFilamentVolumeMaps() const auto preset_bundle = wxGetApp().preset_bundle; auto proj_config = preset_bundle->project_config; auto nozzle_volume_values = proj_config.option("nozzle_volume_type")->values; + // The high-flow panel of the right extruder also holds an E3D High Flow nozzle; keep that type + // instead of writing plain High Flow, which the extruder does not have. + const int right_extruder_id = 1; + const bool right_e3d_high_flow = nozzle_volume_values.size() > right_extruder_id && + nozzle_volume_values[right_extruder_id] == static_cast(NozzleVolumeType::nvtE3DHighFlow); + const int right_high_flow_volume = static_cast(right_e3d_high_flow ? NozzleVolumeType::nvtE3DHighFlow : NozzleVolumeType::nvtHighFlow); for (int i = 0; i < (int) volume_map.size(); ++i) { int filament_id = i + 1; @@ -199,7 +205,7 @@ std::vector FilamentMapManualPanel::GetFilamentVolumeMaps() const } } else if (std::find(right_high_flow_filaments.begin(), right_high_flow_filaments.end(), filament_id) != right_high_flow_filaments.end()) { - volume_map[i] = static_cast(NozzleVolumeType::nvtHighFlow); + volume_map[i] = right_high_flow_volume; } else if (std::find(right_standard_filaments.begin(), right_standard_filaments.end(), filament_id) != right_standard_filaments.end()) { volume_map[i] = static_cast(NozzleVolumeType::nvtStandard); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ffa067308c..01ff6de714 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6546,8 +6546,11 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const // glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f)); BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail: finished"); - // Puts the canvas viewport back in place of the thumbnail one set above. - wxGetApp().plater()->get_camera().apply_viewport(); + // Puts the canvas viewport back in place of the thumbnail one set above. The CLI renders + // thumbnails with no application and no plater, so there is no canvas viewport to restore. + if (wxTheApp != nullptr) + if (Plater *plater = wxGetApp().plater(); plater != nullptr) + plater->get_camera().apply_viewport(); } void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index b35d598829..be0c57c658 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -106,6 +106,11 @@ std::pair GLShadersManager::init() valid &= append_shader("mm_gouraud", { prefix + "mm_gouraud.vs", prefix + "mm_gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv }); else valid &= append_shader("mm_gouraud", { prefix + "mm_gouraud.vs", prefix + "mm_gouraud.fs" }); + // Fast shaded preview for the texture displacement gizmo (see libslic3r/TextureDisplacement.hpp). + valid &= append_shader("texture_displacement_shaded", { prefix + "texture_displacement_shaded.vs", prefix + "texture_displacement_shaded.fs" }); + // UV-check overlay for the same gizmo: a procedural checker or a distortion heatmap over the + // painted patch, to sanity-check the unwrap. + valid &= append_shader("texture_displacement_uvcheck", { prefix + "texture_displacement_uvcheck.vs", prefix + "texture_displacement_uvcheck.fs" }); return { valid, error }; } diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 3df368de3f..1e8f253ea9 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -173,7 +173,8 @@ bool GLTexture::load_from_svg_file(const std::string& filename, bool use_mipmaps return false; } -bool GLTexture::load_from_raw_data(std::vector data, unsigned int w, unsigned int h, bool apply_anisotropy) +bool GLTexture::load_from_raw_data(std::vector data, unsigned int w, unsigned int h, bool apply_anisotropy, + bool use_mipmaps) { m_width = w; m_height = h; @@ -197,18 +198,51 @@ bool GLTexture::load_from_raw_data(std::vector data, unsigned int glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data())); - bool use_mipmaps = true; if (use_mipmaps) { - // we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards - int lod_w = m_width; - int lod_h = m_height; + // We generate the mipmap chain ourselves rather than calling glGenerateMipmap(), which this + // codebase has historically considered unreliable on some graphics cards. + // + // Each level is a 2x2 box filter of the level above it. Note this used to re-upload the + // *level-0* buffer at every level instead, which does not downscale anything - it just + // reinterprets the image's first lod_w * lod_h texels as the whole smaller level, i.e. every + // level below 0 held a crop of the top-left corner. It went unnoticed for as long as every + // caller drew these textures at roughly their native size (where only level 0 is ever + // sampled); it shows up the moment one is drawn small enough to select a lower level, as a + // texture that visibly turns into something else as it shrinks. + std::vector scratch; + const std::vector *src = &data; + int src_w = m_width; + int src_h = m_height; GLint level = 0; - while (lod_w > 1 || lod_h > 1) { + while (src_w > 1 || src_h > 1) { ++level; - lod_w = std::max(lod_w / 2, 1); - lod_h = std::max(lod_h / 2, 1); - n_pixels = lod_w * lod_h; - glsafe(::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)lod_w, (GLsizei)lod_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data())); + const int lod_w = std::max(src_w / 2, 1); + const int lod_h = std::max(src_h / 2, 1); + + std::vector lod(size_t(lod_w) * size_t(lod_h) * 4); + for (int y = 0; y < lod_h; ++y) { + // min() rather than a plain 2*y+1: an odd source extent leaves the last output texel + // with only one source row/column to average, not two. + const int y0 = std::min(2 * y, src_h - 1); + const int y1 = std::min(2 * y + 1, src_h - 1); + for (int x = 0; x < lod_w; ++x) { + const int x0 = std::min(2 * x, src_w - 1); + const int x1 = std::min(2 * x + 1, src_w - 1); + for (int c = 0; c < 4; ++c) { + const unsigned int sum = (*src)[(size_t(y0) * size_t(src_w) + size_t(x0)) * 4 + size_t(c)] + + (*src)[(size_t(y0) * size_t(src_w) + size_t(x1)) * 4 + size_t(c)] + + (*src)[(size_t(y1) * size_t(src_w) + size_t(x0)) * 4 + size_t(c)] + + (*src)[(size_t(y1) * size_t(src_w) + size_t(x1)) * 4 + size_t(c)]; + lod[(size_t(y) * size_t(lod_w) + size_t(x)) * 4 + size_t(c)] = (unsigned char)(sum / 4); + } + } + } + glsafe(::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)lod_w, (GLsizei)lod_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)lod.data())); + + scratch = std::move(lod); + src = &scratch; + src_w = lod_w; + src_h = lod_h; } glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level)); diff --git a/src/slic3r/GUI/GLTexture.hpp b/src/slic3r/GUI/GLTexture.hpp index 5e3d11984d..cf6f0f1d71 100644 --- a/src/slic3r/GUI/GLTexture.hpp +++ b/src/slic3r/GUI/GLTexture.hpp @@ -101,7 +101,10 @@ namespace GUI { bool load_from_file(const std::string& filename, bool use_mipmaps, ECompressionType compression_type, bool apply_anisotropy); bool load_from_svg_file(const std::string& filename, bool use_mipmaps, bool compress, bool apply_anisotropy, unsigned int max_size_px); //BBS load GLTexture from raw pixel data - bool load_from_raw_data(std::vector data, unsigned int w, unsigned int h, bool apply_anisotropy = false); + // `data` is RGBA, w * h * 4 bytes. With use_mipmaps, a real box-filtered mipmap chain is + // built, so the texture may safely be drawn smaller than its pixel size. + bool load_from_raw_data(std::vector data, unsigned int w, unsigned int h, bool apply_anisotropy = false, + bool use_mipmaps = true); // meanings of states: (std::pair) // first field (int): // 0 -> no changes diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 78a511c90c..d7bd96f178 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -14,6 +14,9 @@ #include #include +#include +#include + #if __APPLE__ #import #elif _WIN32 @@ -27,11 +30,13 @@ #include "AboutDialog.hpp" #include "MsgDialog.hpp" +#include "Plater.hpp" #include "format.hpp" #include "WebUserLoginDialog.hpp" #include "libslic3r/Print.hpp" +#include "libslic3r/Utils.hpp" namespace Slic3r { @@ -531,6 +536,11 @@ boost::filesystem::path into_path(const wxString &str) return boost::filesystem::path(str.wx_str()); } +wxString file_url_from_path(const boost::filesystem::path &path) +{ + return wxFileSystem::FileNameToURL(wxFileName(from_path(path))); +} + void about() { AboutDialog dlg; @@ -635,4 +645,26 @@ void desktop_open_any_folder( const std::string& path ) } +bool desktop_open_project_attachment(wxWindow *parent, const boost::filesystem::path &path) +{ + // The auxiliary path is UTF-8, which is what boost::filesystem reads a narrow string as. + const boost::filesystem::path aux_root(wxGetApp().plater()->model().get_auxiliary_file_temp_path()); + boost::system::error_code ec; + if (!is_absolute_path_within_root(path, aux_root) || !boost::filesystem::is_regular_file(path, ec)) + return false; + + // Attachments come with the project and carry no download mark, so the desktop would open them without a warning. + if (!is_safe_to_open_file_name(path.filename().string())) { + MessageDialog dlg(parent, + wxString::Format(_L("\"%s\" is not a plain document, image or model file. Opening it may run it as a " + "program or script on this computer.\n\n" + "Only open attachments from projects you trust. Open it anyway?"), + from_path(path.filename())), + _L("Open attachment"), wxICON_WARNING | wxYES_NO); + if (dlg.ShowModal() != wxID_YES) + return false; + } + return wxLaunchDefaultApplication(from_path(path), 0); +} + } } diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index db882b79cf..a5bbb35f6f 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -76,6 +76,9 @@ std::string into_u8(const wxString &str); wxString from_path(const boost::filesystem::path &path); // boost path from wxString boost::filesystem::path into_path(const wxString &str); +// file:// URL of a local path, percent-encoded so characters such as '#', '%' and '?' stay part of the path. +// Append any query or fragment to the result. +wxString file_url_from_path(const boost::filesystem::path &path); // Display an About dialog extern void about(); @@ -83,6 +86,9 @@ extern void about(); extern void desktop_open_datadir_folder(); // Ask the destop to open one folder extern void desktop_open_any_folder(const std::string& path); +// Ask the desktop to open a file from the project's auxiliary directory, after a confirmation +// unless its type is known to be plain content. Returns false if the file was not opened. +extern bool desktop_open_project_attachment(wxWindow *parent, const boost::filesystem::path &path); } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index da3dae78da..da0be9228d 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1509,11 +1509,33 @@ int GUI_App::install_plugin(std::string name, std::string package_name, InstallP size_t n = mz_zip_reader_get_extra(&archive, stat.m_file_index, extra.data(), extra.size()); dest_file = decode(extra.substr(0, n), stat.m_filename); } + if (!is_path_within_root(dest_file, plugin_folder)) { + BOOST_LOG_TRIVIAL(error) << "[install_plugin] entry " << dest_file << " resolves outside " << plugin_folder.string(); + close_zip_reader(&archive); + if (pro_fn) { pro_fn(InstallStatusUnzipFailed, 0, cancel); } + return InstallStatusUnzipFailed; + } auto dest_path = plugin_folder / dest_file; - boost::filesystem::create_directories(dest_path.parent_path()); std::string dest_zip_file = encode_path(dest_path.string().c_str()); +#ifndef WIN32 + // Validate a symlink's target before anything at the destination is replaced. + const bool is_link = S_ISLNK(stat.m_external_attr >> 16); + std::string link; + if (is_link) { + link.assign(stat.m_uncomp_size, 0); + if (!mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, link.data(), stat.m_uncomp_size, 0) || + !is_symlink_target_within_root(dest_file, link, plugin_folder)) { + BOOST_LOG_TRIVIAL(error) << "[install_plugin] link " << dest_file << " -> " << link << " is unreadable or resolves outside " << plugin_folder.string(); + close_zip_reader(&archive); + if (pro_fn) { pro_fn(InstallStatusUnzipFailed, 0, cancel); } + return InstallStatusUnzipFailed; + } + } +#endif try { - if (fs::exists(dest_path)) { + boost::filesystem::create_directories(dest_path.parent_path()); + // symlink_status so that an existing symlink, dangling or not, is replaced rather than written through. + if (fs::exists(fs::symlink_status(dest_path))) { boost::system::error_code ec; fs::remove(dest_path, ec); if (ec) { @@ -1541,9 +1563,8 @@ int GUI_App::install_plugin(std::string name, std::string package_name, InstallP } mz_bool res = 0; #ifndef WIN32 - if (S_ISLNK(stat.m_external_attr >> 16)) { - std::string link(stat.m_uncomp_size + 1, 0); - res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, link.data(), stat.m_uncomp_size, 0); + if (is_link) { + res = 1; try { boost::filesystem::create_symlink(link, dest_path); } catch (const std::exception &e) { @@ -8861,6 +8882,11 @@ void GUI_App::load_current_presets(bool active_preset_combox/*= false*/, bool ch if (active_preset_combox) tab->reactive_preset_combo_box(); } + // Preset loading can resize the filament list without an extruder-count change event. + // Refresh the controls even when the list already matches the printer's nozzle count. + if (printer_technology == ptFFF) + this->plater()->on_filament_count_change(preset_bundle->filament_presets.size()); + // BBS: model config for (Tab *tab : model_tabs_list) if (tab->supports_printer_technology(printer_technology)) { diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index ecca540aa9..8bc899bb3d 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -336,13 +336,20 @@ wxBitmap SettingsFactory::get_category_bitmap(const std::string& category_name, //------------------------------------- // Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important -static const constexpr std::array, 5> ADD_VOLUME_MENU_ITEMS = {{ +static const constexpr std::array, 11> ADD_VOLUME_MENU_ITEMS = {{ // menu_item Name menu_item bitmap name {L("Add Part"), "menu_add_part" }, // ~ModelVolumeType::MODEL_PART {L("Add Negative Part"), "menu_add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME {L("Add Modifier"), "menu_add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER {L("Add Support Blocker"), "menu_support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER {L("Add Support Enforcer"), "menu_support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER + // Precise Seam modifiers (all 6 subtypes - only first one shown in menu, others used for tree icons) + {L("Add Precise Seam"), "menu_precise_seam_center"}, // ~ModelVolumeType::PRECISE_SEAM_CENTER + {L("Add Precise Seam"), "menu_precise_seam_left"}, // ~ModelVolumeType::PRECISE_SEAM_LEFT + {L("Add Precise Seam"), "menu_precise_seam_right"}, // ~ModelVolumeType::PRECISE_SEAM_RIGHT + {L("Add Precise Seam"), "menu_precise_seam_enforced"}, // ~ModelVolumeType::PRECISE_SEAM_ENFORCED + {L("Add Precise Seam"), "menu_precise_seam_blocked"}, // ~ModelVolumeType::PRECISE_SEAM_BLOCKED + {L("Add Precise Seam"), "menu_precise_seam_neutral"}, // ~ModelVolumeType::PRECISE_SEAM_NEUTRAL }}; // Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important @@ -740,10 +747,20 @@ void MenuFactory::append_menu_items_add_volume(wxMenu* menu) for (size_t type = 0; type < ADD_VOLUME_MENU_ITEMS.size(); type++) { + // Skip Precise Seam subtypes except the first one (CENTER) - they are only used for tree icons + if (type >= int(ModelVolumeType::PRECISE_SEAM_LEFT) && + type <= int(ModelVolumeType::PRECISE_SEAM_NEUTRAL)) + continue; + auto& item = ADD_VOLUME_MENU_ITEMS[type]; + // Use special icon for "Add Precise Seam" menu (different from tree icon) + std::string icon_name = item.second; + if (type == int(ModelVolumeType::PRECISE_SEAM_CENTER)) + icon_name = "menu_precise_seam_add"; + wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType(type)); - append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second, + append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", icon_name, []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); } @@ -843,11 +860,16 @@ wxMenuItem* MenuFactory::append_menu_item_change_type(wxMenu* menu) }; std::vector types = { - { ModelVolumeType::MODEL_PART, _L("Part") }, - { ModelVolumeType::NEGATIVE_VOLUME, _L("Negative Part") }, - { ModelVolumeType::PARAMETER_MODIFIER, _L("Modifier") }, - { ModelVolumeType::SUPPORT_BLOCKER, _L("Support Blocker") }, - { ModelVolumeType::SUPPORT_ENFORCER, _L("Support Enforcer") } + { ModelVolumeType::MODEL_PART, _L("Part") }, + { ModelVolumeType::NEGATIVE_VOLUME, _L("Negative Part") }, + { ModelVolumeType::PARAMETER_MODIFIER, _L("Modifier") }, + { ModelVolumeType::SUPPORT_BLOCKER, _L("Support Blocker") }, + { ModelVolumeType::SUPPORT_ENFORCER, _L("Support Enforcer") }, + // Single "Precise Seam" entry that maps to PRECISE_SEAM_CENTER as the default subtype. + // set_volume_type() preserves the existing subtype (LEFT/RIGHT/etc.) for volumes that + // are already Precise Seam; subtype picking is done via the separate + // "Precise Seam Type" submenu (see append_menu_item_precise_seam_submenu). + { ModelVolumeType::PRECISE_SEAM_CENTER, _L("Precise Seam") } }; for (const auto& info : types) { @@ -863,7 +885,13 @@ wxMenuItem* MenuFactory::append_menu_item_change_type(wxMenu* menu) obj_list()->GetSelections(sels); for (auto item : sels) { ModelVolumeType vol_type = model->GetVolumeType(item); - if (vol_type == type) { + // The "Precise Seam" entry represents all six PS subtypes, so any subtype + // among selected volumes counts as a match (keeps the checkbox ticked when + // user has PS_LEFT/RIGHT/etc. selected, not only plain CENTER). + const bool match = (type == ModelVolumeType::PRECISE_SEAM_CENTER) + ? is_precise_seam(vol_type) + : (vol_type == type); + if (match) { has_type = true; break; } @@ -871,6 +899,7 @@ wxMenuItem* MenuFactory::append_menu_item_change_type(wxMenu* menu) evt.Check(has_type); // ORCA Fix crash caused by SVG/TEXT volumes cant be Support Enforcer/Blocker type + // The same applies to Precise Seam subtypes. for (auto item : sels) { if (model->GetItemType(item) == itVolume){ auto vol_idx = model->GetVolumeIdByItem(item); @@ -881,7 +910,8 @@ wxMenuItem* MenuFactory::append_menu_item_change_type(wxMenu* menu) auto vol = (*objs)[obj_idx]->volumes[vol_idx]; // disable Support Enforcer/Blocker if selection contains svg or text - if (vol != nullptr && (vol->is_svg() || vol->is_text()) && (type == ModelVolumeType::SUPPORT_BLOCKER || type == ModelVolumeType::SUPPORT_ENFORCER)){ + // (same applies to Precise Seam) + if (vol != nullptr && (vol->is_svg() || vol->is_text()) && (type == ModelVolumeType::SUPPORT_BLOCKER || type == ModelVolumeType::SUPPORT_ENFORCER || is_precise_seam(type))){ evt.Enable(false); break; } @@ -1309,6 +1339,131 @@ void MenuFactory::append_menu_items_mirror(wxMenu* menu) []() { return plater()->can_mirror(); }, m_parent); } +void MenuFactory::append_menu_item_precise_seam_submenu(wxMenu* menu) +{ + wxString submenu_name = _L("Precise Seam Type"); + + // Remove existing submenu if present (menu is rebuilt on every right-click) + const int menu_item_id = menu->FindItem(submenu_name); + if (menu_item_id != wxNOT_FOUND) + menu->Destroy(menu_item_id); + + // --- Precondition: ALL selected volumes must be Precise Seam --- + // Mixed selections (PS + non-PS) are ambiguous for subtype switching: applying a subtype + // would implicitly convert the non-PS volumes to PS, which is not what the user expects + // from a subtype picker. For mixed selections the user should first use + // "Change type → Precise Seam" to unify them, then come back to this submenu. + wxDataViewItemArray sels; + obj_list()->GetSelections(sels); + if (sels.IsEmpty()) + return; + + // A right-click on a volume in the 3D view routes through Plater::show_context_menu + // → ObjectList::update_selections(), which intentionally preserves a pre-existing + // settings-row selection alongside the clicked volume. As a result GetSelections() + // may return settings-row items that are children of a volume. Treat each settings + // row as selecting its parent volume (same pattern used by set_volume_type() + // internally). Without this resolution, GetVolumeType(settings_row) returns INVALID + // and the submenu would hide even when a valid PS volume is in the selection. + // + // Precomputing the resolved PS types once here also lets the checkmark loop below + // display checks correctly for selections that contain settings rows. + std::vector selected_ps_types; + selected_ps_types.reserve(sels.size()); + + auto* model = obj_list()->GetModel(); + for (const auto& sel_item : sels) { + wxDataViewItem vol_item = sel_item; + const ItemType type_mask = model->GetItemType(sel_item); + if (!(type_mask & itVolume)) { + // Only settings rows whose parent is a volume map to "selecting that volume". + // Any other non-volume item (object, instance, etc.) means the selection is + // not purely PS-volume-based — hide the submenu. + if ((type_mask & itSettings) && (model->GetItemType(model->GetParent(sel_item)) & itVolume)) + vol_item = model->GetParent(sel_item); + else + return; + } + const ModelVolumeType vol_type = model->GetVolumeType(vol_item); + if (!is_precise_seam(vol_type)) + return; + selected_ps_types.push_back(vol_type); + } + + // Match the label used by append_menu_item_change_type, including its translation. + int insert_pos = wxNOT_FOUND; + int change_type_id = menu->FindItem(_L("Change Type")); + if (change_type_id != wxNOT_FOUND) { + for (size_t i = 0; i < menu->GetMenuItemCount(); i++) { + wxMenuItem* item = menu->FindItemByPosition(i); + if (item && item->GetId() == change_type_id) { + insert_pos = i + 1; // insert directly after the Change Type entry + break; + } + } + } + + // --- Build the subtype submenu --- + wxMenu* ps_menu = new wxMenu(); + + // Array of all 6 Precise Seam subtypes with labels. + // "Seam ..." prefix disambiguates from other i18n contexts (extruder Left/Right, "Center on bed", etc.) + static const std::array, 6> PS_TYPES = {{ + {L("Seam Center"), ModelVolumeType::PRECISE_SEAM_CENTER}, + {L("Seam Left"), ModelVolumeType::PRECISE_SEAM_LEFT}, + {L("Seam Right"), ModelVolumeType::PRECISE_SEAM_RIGHT}, + {L("Seam Enforced"), ModelVolumeType::PRECISE_SEAM_ENFORCED}, + {L("Seam Blocked"), ModelVolumeType::PRECISE_SEAM_BLOCKED}, + {L("Seam Neutral"), ModelVolumeType::PRECISE_SEAM_NEUTRAL}, + }}; + + for (const auto& ps_type : PS_TYPES) { + wxString label = _(ps_type.first); + + // Check-items (not radio): radio groups in wxWidgets auto-select the first item when + // no item is explicitly checked, which misleads the user into seeing "Seam Center" + // as the active subtype for mixed-subtype selections. With check-items we can leave + // every item unchecked in that case, and the menu matches the pattern of the + // neighbouring "Change type" submenu (see append_menu_item_change_type). + // + // Handler: delegate to set_volume_type() with preserve_ps_subtype=false. The user + // explicitly picked a subtype here, so "Seam Center" must set every selected PS + // volume to CENTER verbatim — preservation (the default for "Change type") would + // keep existing subtypes and make CENTER unreachable on mixed-subtype selections. + // set_volume_type() already handles multi-select iteration, the last-solid-part + // guard, and the PS group-change reordering via move_volume_to_end(). + wxMenuItem* item = append_menu_check_item(ps_menu, wxID_ANY, label, "", + [ps_type](wxCommandEvent&) { + obj_list()->set_volume_type(ps_type.second, /*preserve_ps_subtype=*/false); + }, + ps_menu); + + // Tick every subtype that is present in the current selection. Same pattern as the + // neighbouring "Change type" submenu (where selecting [Part + Modifier] ticks both + // "Part" and "Modifier" boxes). For homogeneous selections exactly one checkbox is + // ticked; for mixed subtype selections (e.g. PS_LEFT + PS_RIGHT) both "Seam Left" + // and "Seam Right" appear checked, so the user sees at a glance which subtypes are + // currently in the selection. + // + // Uses the precomputed selected_ps_types (which resolved settings rows to their + // parent volumes); iterating sels directly would miss subtypes for selections that + // arrive via settings rows from right-click-in-3D-view. + const bool is_present = std::find(selected_ps_types.begin(), selected_ps_types.end(), + ps_type.second) != selected_ps_types.end(); + if (is_present && item) + item->Check(true); + } + + // Add submenu to parent menu + append_submenu(menu, ps_menu, wxID_ANY, + submenu_name, + _L("Choose precise seam subtype"), + "menu_precise_seam_type", + []() { return true; }, + m_parent, + insert_pos); +} + void MenuFactory::append_menu_item_edit_text(wxMenu *menu) { wxString name = _L("Edit text"); @@ -1578,6 +1733,7 @@ void MenuFactory::create_part_menu() menu->AppendSeparator(); append_menu_item_change_type(menu); + append_menu_item_precise_seam_submenu(menu); append_menu_items_mirror(&m_part_menu); append_menu_item(&m_part_menu, wxID_ANY, _L("Split"), _L("Split the selected object into multiple parts"), [](wxCommandEvent&) { plater()->split_volume(); }, "split_parts", nullptr, @@ -1875,6 +2031,7 @@ wxMenu* MenuFactory::part_menu() { append_menu_items_convert_unit(&m_part_menu); append_menu_item_change_filament(&m_part_menu); + append_menu_item_precise_seam_submenu(&m_part_menu); append_menu_item_per_object_settings(&m_part_menu); return &m_part_menu; } @@ -1989,6 +2146,10 @@ wxMenu* MenuFactory::multi_selection_menu() append_menu_item_per_object_process(menu); menu->AppendSeparator(); append_menu_item_change_type(menu); + // Subtype picker for Precise Seam — shown only when all selected volumes are PS. + // Must be paired with Change Type here (as in single-volume part_menu), otherwise + // the user cannot switch PS subtypes (LEFT/RIGHT/etc.) on multi-selection. + append_menu_item_precise_seam_submenu(menu); append_menu_item_change_filament(menu); } return menu; diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp index ec7b0a0b03..ad694f15de 100644 --- a/src/slic3r/GUI/GUI_Factories.hpp +++ b/src/slic3r/GUI/GUI_Factories.hpp @@ -174,6 +174,7 @@ private: void append_menu_item_merge_to_single_object(wxMenu* menu); void append_menu_item_merge_parts_to_single_part(wxMenu *menu); void append_menu_items_mirror(wxMenu *menu); + void append_menu_item_precise_seam_submenu(wxMenu* menu); void append_menu_item_invalidate_cut_info(wxMenu *menu); void append_menu_item_edit_text(wxMenu *menu); void append_menu_item_edit_svg(wxMenu *menu); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 5220e026c7..99c023e4a1 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1944,6 +1944,12 @@ bool ObjectList::can_drop(const wxDataViewItem& item, int& src_obj_id, int& src_ if (dragged_item_v_type == item_v_type && dragged_item_v_type != ModelVolumeType::MODEL_PART) return true; + + // Use tree item types: hidden cut connectors make tree indices differ from volumes indices. + if (is_precise_seam(dragged_item_v_type) && is_precise_seam(item_v_type)) + // Allow reordering only within the strong or weak modifier group. + return is_precise_seam_strong(dragged_item_v_type) == is_precise_seam_strong(item_v_type); + if ((dragged_item_v_type != item_v_type) || // we can't reorder volumes outside of types item_v_type >= ModelVolumeType::SUPPORT_BLOCKER) // support blockers/enforcers can't change its place return false; @@ -2033,10 +2039,43 @@ void ObjectList::OnDrop(wxDataViewEvent &event) int to_volume_id = m_objects_model->GetVolumeIdByItem(item); int delta = to_volume_id < from_volume_id ? -1 : 1; - auto &volumes = (*m_objects)[m_dragged_data.obj_idx()]->volumes; + const int obj_idx = m_dragged_data.obj_idx(); + // Object-indexed UI maps may be stale after another object is removed or reordered. + if (obj_idx < 0 || size_t(obj_idx) >= m_objects->size()) { + event.Veto(); + m_dragged_data.clear(); + return; + } + const ModelObject *object = (*m_objects)[obj_idx]; + auto &volumes = (*m_objects)[obj_idx]->volumes; + std::vector visible_volume_indices; + visible_volume_indices.reserve(volumes.size()); + for (size_t idx = 0; idx < volumes.size(); ++idx) + // Match add_volumes_to_object_in_list: only connectors of cut objects are hidden. + if (!(object->is_cut() && volumes[idx]->is_cut_connector())) + visible_volume_indices.push_back(idx); - int cnt = 0; - for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id += delta, cnt++) std::swap(volumes[id], volumes[id + delta]); + // Validate the entire move before any swap; these checks must also protect Release builds. + if (from_volume_id < 0 || to_volume_id < 0 || + size_t(from_volume_id) >= visible_volume_indices.size() || size_t(to_volume_id) >= visible_volume_indices.size()) { + event.Veto(); + m_dragged_data.clear(); + return; + } + + // Move through visible slots only, keeping hidden cut connectors at their original indices. + // The local mapping stays valid because no hidden volume changes slots during the move. + for (int id = from_volume_id; id != to_volume_id; id += delta) { + const size_t current_idx = visible_volume_indices[id]; + const size_t next_idx = visible_volume_indices[id + delta]; + std::swap(volumes[current_idx], volumes[next_idx]); + } + + // Later selection/filament handlers use this cache; repair it for the moved object too. + auto &ui_to_model = m_objects_model->get_ui_and_3d_volume_map()[obj_idx]; + ui_to_model.clear(); + for (size_t idx = 0; idx < visible_volume_indices.size(); ++idx) + ui_to_model[int(idx)] = int(visible_volume_indices[idx]); select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, m_objects_model->GetParent(item))); @@ -3855,7 +3894,8 @@ wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const D const bool is_layer_settings = m_objects_model->GetItemType(parent_item) == itLayer; if (!is_object_settings) { ModelVolumeType volume_type = m_objects_model->GetVolumeType(parent_item); - if (volume_type == ModelVolumeType::NEGATIVE_VOLUME || volume_type == ModelVolumeType::SUPPORT_BLOCKER || volume_type == ModelVolumeType::SUPPORT_ENFORCER) + // Precise Seam is non-printing helper geometry — no per-volume settings + if (volume_type == ModelVolumeType::NEGATIVE_VOLUME || volume_type == ModelVolumeType::SUPPORT_BLOCKER || volume_type == ModelVolumeType::SUPPORT_ENFORCER || is_precise_seam(volume_type)) return ret; } @@ -5712,7 +5752,6 @@ void ObjectList::change_part_type() return; } #endif - ModelVolumeType ObjectList::get_selected_volume_type() { ModelVolume* volume = get_selected_model_volume(); @@ -5721,13 +5760,49 @@ ModelVolumeType ObjectList::get_selected_volume_type() return ModelVolumeType::INVALID; } -void ObjectList::set_volume_type(ModelVolumeType new_type) +// ---------------- Helpers for Precise Seam group-aware type changes ---------------- +// Used by set_volume_type() and the "Precise Seam Type" subtype submenu handler. + +// Detects whether a type change crosses a Precise Seam "group boundary" that requires +// manual repositioning inside ModelObject::volumes[]: +// - between any non-PS type and any PS subtype, or +// - between strong PS (CENTER/LEFT/RIGHT) and weak PS (ENFORCED/BLOCKED/NEUTRAL). +// sort_volumes() is stable and groups strong PS before weak PS. When a volume crosses +// a group, moving it to the end of volumes[] lets the subsequent stable sort place it +// at the end of its new group. Without this, a strong→weak transition would leave the +// volume stuck in the strong segment and break the modifier-application order. +static bool precise_seam_group_changed(ModelVolumeType old_type, ModelVolumeType new_type) +{ + const bool old_is_ps = is_precise_seam(old_type); + const bool new_is_ps = is_precise_seam(new_type); + if (old_is_ps != new_is_ps) + return true; // non-PS ↔ PS transition + if (!old_is_ps) + return false; // both non-PS — regular enum ordering is enough + return is_precise_seam_strong(old_type) != is_precise_seam_strong(new_type); +} + +// Moves a volume to the end of ModelObject::volumes[]. Combined with stable sort_volumes(), +// this places it at the end of its new group while preserving relative order of others. +static void move_volume_to_end(ModelObject* obj, ModelVolume* volume) +{ + if (obj == nullptr || volume == nullptr) + return; + auto it = std::find(obj->volumes.begin(), obj->volumes.end(), volume); + if (it != obj->volumes.end()) { + obj->volumes.erase(it); + obj->volumes.push_back(volume); + } +} + +void ObjectList::set_volume_type(ModelVolumeType new_type, bool preserve_ps_subtype) { struct VolumeSelection { int object_idx; ModelVolume* volume; }; + // --- Collect selected volumes from the object tree, falling back to the 3D canvas --- std::vector volumes; auto add_volume = [&volumes](int obj_idx, ModelVolume* volume) { if (volume == nullptr) @@ -5792,25 +5867,49 @@ void ObjectList::set_volume_type(ModelVolumeType new_type) // and historically crashed (originally fixed in the now-disabled change_part_type() by hiding // Support entries in the old choice dialog; the UI-side guard for the current submenu lives // in MenuFactory::append_menu_item_change_type, see #13120). + // The same rationale applies to any Precise Seam subtype. // This block must never be reachable under a healthy UI; if it ever logs, the UI guard has // been bypassed (new entry point, refactor, plugin, etc.) and should be investigated. - if (new_type == ModelVolumeType::SUPPORT_BLOCKER || new_type == ModelVolumeType::SUPPORT_ENFORCER) { + if (new_type == ModelVolumeType::SUPPORT_BLOCKER || new_type == ModelVolumeType::SUPPORT_ENFORCER + || is_precise_seam(new_type)) { const bool has_text_or_svg = std::any_of(volumes.begin(), volumes.end(), [](const VolumeSelection& sel) { return sel.volume->is_svg() || sel.volume->is_text(); }); if (has_text_or_svg) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ - << ": blocked attempt to set SUPPORT_BLOCKER/ENFORCER on SVG/text volume; " + << ": blocked attempt to set SUPPORT_BLOCKER/ENFORCER or Precise Seam on SVG/text volume; " << "UI guard should have prevented this -- possible regression in the Change Type menu"; return; } } + // --- Subtype preservation for the generic "Precise Seam" entry --- + // The Change Type submenu uses PRECISE_SEAM_CENTER as the single "Precise Seam" entry + // and calls with preserve_ps_subtype=true: volumes that are already Precise Seam keep + // their subtype (LEFT/RIGHT/etc.); only non-PS volumes get converted to the default + // CENTER subtype. + // + // The "Precise Seam Type" subtype submenu calls with preserve_ps_subtype=false: the + // user explicitly picked CENTER and all selected PS volumes must be set to CENTER + // verbatim (otherwise CENTER would become unreachable for mixed-subtype selections, + // since preservation would keep every volume at its current subtype and any_diff would + // be false — the reason for this two-parameter split). + auto effective_new_type = [new_type, preserve_ps_subtype](const ModelVolume* v) -> ModelVolumeType { + if (preserve_ps_subtype && new_type == ModelVolumeType::PRECISE_SEAM_CENTER && v->is_precise_seam()) + return v->type(); + return new_type; + }; + + // --- Any-change check using the effective target type --- const bool any_diff = std::any_of(volumes.begin(), volumes.end(), - [new_type](const VolumeSelection& sel) { return sel.volume->type() != new_type; }); + [&effective_new_type](const VolumeSelection& sel) { + return sel.volume->type() != effective_new_type(sel.volume); + }); if (!any_diff) return; + // --- Last-solid-part guard (pre-existing behavior) --- + // When converting away from MODEL_PART, ensure at least one solid part remains per object. if (new_type != ModelVolumeType::MODEL_PART) { std::map total_part_cnt; std::map selected_part_cnt; @@ -5838,14 +5937,36 @@ void ObjectList::set_volume_type(ModelVolumeType new_type) take_snapshot(_u8L("Change part type")); + // --- Apply type changes with Precise Seam group-aware repositioning --- + // Note: `changed_volumes` / `touched_objects` track every processed volume, including + // subtype-preservation no-ops. Tracking no-ops is intentional — it ensures such + // volumes remain selected after the post-apply rebuild. Without that, a cross-object + // mixed selection like [Part, PS_LEFT] clicking "Change type → Precise Seam" would + // silently deselect the preserved PS_LEFT: only the Part's object would enter + // touched_objects, and the final SetSelections(new_selection) would drop PS_LEFT. std::set changed_volumes; std::set touched_objects; for (const auto& sel : volumes) { - sel.volume->set_type(new_type); + const ModelVolumeType target = effective_new_type(sel.volume); + const ModelVolumeType old_type = sel.volume->type(); + + // Record the volume for reselection before the no-op short-circuit (see comment above). changed_volumes.insert(sel.volume); touched_objects.insert(sel.object_idx); + + if (old_type == target) + continue; // subtype-preservation no-op — nothing to write/move + + sel.volume->set_type(target); + + // If the change crosses a PS group boundary, move the volume to the end of volumes[] + // so the stable sort in reorder_volumes_and_get_selection() places it at the end of + // its new group (see precise_seam_group_changed() for details). + if (precise_seam_group_changed(old_type, target)) + move_volume_to_end((*m_objects)[sel.object_idx], sel.volume); } + // --- Rebuild selection to follow the changed volumes --- wxDataViewItemArray new_selection; for (int obj_idx : touched_objects) { wxDataViewItemArray sel_items = reorder_volumes_and_get_selection(obj_idx, [&changed_volumes](const ModelVolume* volume) { diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 5705aa2c8b..2700dbc5d8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -88,6 +88,7 @@ struct MeshErrorsInfo class ObjectList : public wxDataViewCtrl { public: + enum SELECTION_MODE { smUndef = 0, @@ -430,7 +431,12 @@ public: #if 0 // ORCA: disabled alongside definition in GUI_ObjectList.cpp (see #if 0 block there) void change_part_type(); #endif - void set_volume_type(ModelVolumeType new_type); + // preserve_ps_subtype = true: when new_type is PRECISE_SEAM_CENTER, volumes that are + // already Precise Seam keep their existing subtype (LEFT/RIGHT/etc.). Used by the + // generic "Change type → Precise Seam" entry where CENTER is a default fallback. + // preserve_ps_subtype = false: no preservation — target type is applied verbatim. Used + // by the "Precise Seam Type" subtype picker where the user explicitly wants CENTER. + void set_volume_type(ModelVolumeType new_type, bool preserve_ps_subtype = true); ModelVolumeType get_selected_volume_type(); void last_volume_is_deleted(const int obj_idx); diff --git a/src/slic3r/GUI/GUI_ObjectTable.cpp b/src/slic3r/GUI/GUI_ObjectTable.cpp index c3c3295800..a7c761a06f 100644 --- a/src/slic3r/GUI/GUI_ObjectTable.cpp +++ b/src/slic3r/GUI/GUI_ObjectTable.cpp @@ -348,7 +348,8 @@ void GridCellFilamentsRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &d if ((grid_row->model_volume_type != ModelVolumeType::NEGATIVE_VOLUME) && \ (grid_row->model_volume_type != ModelVolumeType::SUPPORT_BLOCKER) && \ (grid_row->model_volume_type != ModelVolumeType::SUPPORT_ENFORCER) && \ - (grid_row->model_volume_type != ModelVolumeType::PARAMETER_MODIFIER)) { + (grid_row->model_volume_type != ModelVolumeType::PARAMETER_MODIFIER) && \ + !is_precise_seam(grid_row->model_volume_type)) { // Precise Seam is non-printing helper geometry dc.DrawBitmap(*bitmap, wxPoint(rect.x + offset_x, rect.y + offset_y)); } else if (grid_row->model_volume_type == ModelVolumeType::PARAMETER_MODIFIER){ @@ -3011,7 +3012,8 @@ void ObjectTablePanel::load_data() if (col == ObjectGridTable::col_filaments) { if ((grid_row->model_volume_type != ModelVolumeType::NEGATIVE_VOLUME) && \ (grid_row->model_volume_type != ModelVolumeType::SUPPORT_BLOCKER) && \ - (grid_row->model_volume_type != ModelVolumeType::SUPPORT_ENFORCER)) { + (grid_row->model_volume_type != ModelVolumeType::SUPPORT_ENFORCER) && \ + !is_precise_seam(grid_row->model_volume_type)) { // Precise Seam is non-printing helper geometry GridCellFilamentsEditor* filament_editor = new GridCellFilamentsEditor(grid_col->choices, false, &m_color_bitmaps); m_object_grid->SetCellEditor(row, col, filament_editor); m_object_grid->SetCellRenderer(row, col, new GridCellFilamentsRenderer()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 1009a6e89b..da26353eb6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -2000,7 +2000,7 @@ void GLGizmoEmboss::draw_model_type() if ((is_volume_move_inside || is_volume_move_outside)) process(); - // inspiration in ObjectList::change_part_type() + // inspiration in ObjectList::set_volume_type() // how to view correct side panel with objects ObjectList *obj_list = app.obj_list(); wxDataViewItemArray sel = obj_list->reorder_volumes_and_get_selection( diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 9ba6065458..19856603fa 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -27,7 +27,8 @@ enum class PainterGizmoType { FDM_SUPPORTS, SEAM, MM_SEGMENTATION, - FUZZY_SKIN + FUZZY_SKIN, + TEXTURE_DISPLACEMENT }; class TriangleSelectorGUI : public TriangleSelector { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index b30d399f98..94373391fa 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -2052,7 +2052,7 @@ void GLGizmoSVG::draw_model_type() if ((is_volume_move_inside || is_volume_move_outside)) process(); - // inspiration in ObjectList::change_part_type() + // inspiration in ObjectList::set_volume_type() // how to view correct side panel with objects ObjectList *obj_list = app.obj_list(); wxDataViewItemArray sel = obj_list->reorder_volumes_and_get_selection( diff --git a/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp b/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp new file mode 100644 index 0000000000..5c322a1f81 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.cpp @@ -0,0 +1,6942 @@ +#include "GLGizmoTextureDisplacement.hpp" + +#include +#include + +#include "libslic3r/AABBTreeIndirect.hpp" +#include "libslic3r/Color.hpp" +#include "libslic3r/PresetBundle.hpp" +#include "libslic3r/MeshBoolean.hpp" +#include "libslic3r/Model.hpp" +#include "libslic3r/Utils.hpp" +#include "libslic3r/format.hpp" + +#include "slic3r/GUI/Camera.hpp" +#include "slic3r/GUI/CameraUtils.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GLToolbar.hpp" // GLToolbar::Default_Icons_Size, to match the toolbar's icon size +#include "slic3r/GUI/GUI.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/GUI_ObjectList.hpp" +#include "slic3r/GUI/GuiColor.hpp" +#include "slic3r/GUI/ImGuiWrapper.hpp" +#include "slic3r/GUI/MainFrame.hpp" // wxGetApp().mainframe, as the projector window's parent +#include "slic3r/GUI/MsgDialog.hpp" +#include "slic3r/GUI/OpenGLManager.hpp" +#include "slic3r/GUI/Plater.hpp" +#include "slic3r/GUI/TextureLibrary.hpp" +#include "slic3r/GUI/TextureProjectorFrame.hpp" +#include "slic3r/GUI/UVEditorCanvas.hpp" +#include "slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp" +#include "slic3r/GUI/Jobs/TextureDisplacementPrepareJob.hpp" +#include "slic3r/GUI/Jobs/TextureDisplacementDebugJob.hpp" +#include "slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp" +#include "slic3r/Utils/UndoRedo.hpp" +#include "GLGizmoUtils.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Slic3r::GUI { + +namespace { +// ImGuiWrapper::slider_float()'s trailing `power` parameter is forwarded straight into +// ImGui::SliderFloat()'s ImGuiSliderFlags argument - this ImGui (1.83) replaced the old float +// "power" curve API with a flags word but kept the parameter in the same position, and +// ImGuiWrapper never caught up with the rename. Passing the Logarithmic flag through it is +// therefore how a log-scaled slider gets requested here. +// +// Depth and tile size both want it: they span two to three orders of magnitude, and the values +// that need the most precision (a few hundredths of a millimetre of relief, a very fine tile) are +// all bunched into the very bottom of a linear range, where a single pixel of slider travel is a +// bigger jump than the whole useful region. +constexpr float ImGuiLogSlider = float(ImGuiSliderFlags_Logarithmic); + +// Uploads decoded 8-bit grayscale height data as an RGBA GPU texture for display in the panel. +// Shared by the per-layer thumbnail and the picker's library entries, which differ only in where +// their pixels came from. +// +// The source is downscaled to THUMBNAIL_MAX_PX first, with a box filter, and uploaded *without* +// mipmaps. Both halves of that matter, and together they are the fix for thumbnails rendering as +// garbage: +// - GLTexture's mipmap levels are not real downscales (see load_from_raw_data()'s header) - every +// level re-uploads the full-resolution buffer reinterpreted at a smaller size. A 512px texture +// drawn into a ~48px row is minified ~10x, which is exactly the regime where OpenGL picks those +// broken levels, so the thumbnail showed a scrambled crop of the image rather than the image. +// Turning mipmaps off makes it sample level 0, which is the real picture. +// - But level 0 at 512px sampled down to 48px with plain GL_LINEAR (a 2x2 tap) would alias badly +// on exactly the high-frequency patterns these textures are (knurl, hexagons, weave). Box- +// filtering down to roughly twice the displayed size first is what actually removes the +// frequencies that would alias, and it cuts the VRAM these hold by ~16x as a bonus. +constexpr int THUMBNAIL_MAX_PX = 128; + +// Everything above is about drawing a ~48 px panel row, and none of it applies to the height texture +// the fast-preview *shader* samples: that one is magnified across the model, not minified into a +// row, and every texel it loses is relief the preview cannot show. It gets its own upload at (up to) +// this size, so the shaded preview reads the same height field the bake does instead of a 128 px box +// blur of it - which is what made Fast look flatter and softer than the result it was previewing. +constexpr int HEIGHT_TEX_MAX_PX = 2048; + +// How many rings of vertex-adjacent triangles either side of the paint's edge join the border refine +// band (see collect_paint_region()). Two is enough to grade the size change without the band's own +// cost growing to matter: it is a ring around a perimeter, not an area. +constexpr int BORDER_BAND_RINGS = 2; + +// Is `p` inside triangle `t`, given that it already lies in the triangle's plane? Barycentric via the +// three sub-triangle cross products, compared against the whole triangle's normal. Used to carry a +// partly painted source triangle's coverage onto the children of a subdivision, which are coplanar +// with it by construction (subdivision only adds edge midpoints). +bool point_in_triangle_coplanar(const Vec3f &p, const std::array &t) +{ + const Vec3f n = (t[1] - t[0]).cross(t[2] - t[0]); + const float n2 = n.squaredNorm(); + if (n2 < 1e-20f) + return false; // degenerate: it covers no area, so nothing is inside it + // A small negative tolerance, scaled by the triangle, keeps a centroid sitting exactly on a shared + // edge from falling through the gap between two neighbouring pieces. + const float eps = -1e-4f * n2; + return (t[1] - t[0]).cross(p - t[0]).dot(n) >= eps && + (t[2] - t[1]).cross(p - t[1]).dot(n) >= eps && + (t[0] - t[2]).cross(p - t[2]).dot(n) >= eps; +} + +// Carries one texture-displacement paint mask from `src_mesh` onto `dst_mesh` - a different +// tessellation of the same surface (an isotropic remesh, in practice). +// +// TriangleSelector::remap_painting(), which ModelVolume::restore_painting() uses for the four +// standard paint channels, is not usable here. It runs one select_patch() flood fill per +// (painted sub-triangle x overlapping target facet) pair, and select_patch() splits the *target's* +// triangles down to a 0.02-0.05 mm edge limit along every cursor boundary, behind an +// O(target triangles) visited-set allocation per call. A coarse import painted with a fine brush +// carries tens of thousands of painted sub-triangles, so that is tens of millions of sub-triangles +// created on the target - which is what made Remesh, and Standard mode's Bake (which remeshes for +// you), appear to hang rather than finish. +// +// Each target triangle here asks one question instead: is the point on the source surface closest +// to my centroid inside a painted piece? One AABB-tree query per target triangle, whole facets +// only, no splitting - O(target log source). `src_tree` is built over `src_mesh.its` by the caller +// and shared across the layers; `dst_to_src` brings the target's vertices into the source's frame. +TriangleSelector::TriangleSplittingData remap_texture_paint_spatial( + const TriangleMesh &src_mesh, const TriangleSelector::TriangleSplittingData &src_data, + const AABBTreeIndirect::Tree3f &src_tree, const TriangleMesh &dst_mesh, const Vec3f &dst_to_src) +{ + const indexed_triangle_set &src = src_mesh.its; + const indexed_triangle_set &dst = dst_mesh.its; + const size_t ntri = src.indices.size(); + if (src_data.bitstream.empty() || ntri == 0 || dst.indices.empty() || src_tree.empty()) + return {}; + + // The painted patch, split into per-source-triangle pieces - the same shape + // collect_paint_region() builds, and for the same reason: a source triangle the brush only + // partly covered has to answer "is this point painted" geometrically rather than be rounded to + // painted-or-not, which leaves a ragged fringe along any curved brush boundary. + TriangleSelector src_sel(src_mesh); + src_sel.deserialize(src_data, false); + std::vector piece_src; + const indexed_triangle_set patch = src_sel.get_facets_strict(EnforcerBlockerType::ENFORCER, &piece_src); + if (patch.indices.empty()) + return {}; + + const auto tri_area2 = [](const Vec3f &a, const Vec3f &b, const Vec3f &c) { + return (b - a).cross(c - a).norm(); + }; + std::vector src_area2(ntri, 0.f), covered2(ntri, 0.f); + for (size_t i = 0; i < ntri; ++i) + src_area2[i] = tri_area2(src.vertices[size_t(src.indices[i][0])], src.vertices[size_t(src.indices[i][1])], + src.vertices[size_t(src.indices[i][2])]); + for (size_t j = 0; j < patch.indices.size() && j < piece_src.size(); ++j) { + if (size_t(piece_src[j]) >= ntri) + continue; + const stl_triangle_vertex_indices &t = patch.indices[j]; + covered2[size_t(piece_src[j])] += tri_area2(patch.vertices[size_t(t[0])], patch.vertices[size_t(t[1])], + patch.vertices[size_t(t[2])]); + } + std::vector full(ntri, 0); + for (size_t i = 0; i < ntri; ++i) + full[i] = (src_area2[i] > 0.f && covered2[i] >= 0.999f * src_area2[i]) ? 1 : 0; + + // CSR pieces, kept for partly covered sources only - a full one answers every query "painted". + std::vector part_start(ntri + 1, 0); + for (size_t j = 0; j < patch.indices.size() && j < piece_src.size(); ++j) + if (size_t(piece_src[j]) < ntri && !full[size_t(piece_src[j])]) + ++part_start[size_t(piece_src[j]) + 1]; + for (size_t i = 0; i < ntri; ++i) + part_start[i + 1] += part_start[i]; + std::vector> part; + part.resize(size_t(part_start[ntri])); // not a constructor call: `vector p(size_t(x[n]));` parses + // as a function declaration, and every use of `part` below + // then fails with something that does not mention the cause. + { + std::vector fill(part_start.begin(), part_start.begin() + ntri); + for (size_t j = 0; j < patch.indices.size() && j < piece_src.size(); ++j) { + const size_t S = size_t(piece_src[j]); + if (S >= ntri || full[S]) + continue; + const stl_triangle_vertex_indices &t = patch.indices[j]; + part[size_t(fill[S]++)] = { patch.vertices[size_t(t[0])], patch.vertices[size_t(t[1])], + patch.vertices[size_t(t[2])] }; + } + } + + // Classify in parallel, then write the mask serially - TriangleSelector is not thread safe. + std::vector painted(dst.indices.size(), 0); + tbb::parallel_for(tbb::blocked_range(0, dst.indices.size()), + [&](const tbb::blocked_range &range) { + for (size_t i = range.begin(); i < range.end(); ++i) { + const stl_triangle_vertex_indices &t = dst.indices[i]; + const Vec3f centroid = (dst.vertices[size_t(t[0])] + dst.vertices[size_t(t[1])] + + dst.vertices[size_t(t[2])]) / 3.f + dst_to_src; + size_t hit = 0; + Vec3f hit_pos = Vec3f::Zero(); + if (AABBTreeIndirect::squared_distance_to_indexed_triangle_set(src.vertices, src.indices, src_tree, + centroid, hit, hit_pos) < 0.f || + hit >= ntri) + continue; + if (full[hit]) { + painted[i] = 1; + continue; + } + for (int k = part_start[hit]; k < part_start[hit + 1]; ++k) + if (point_in_triangle_coplanar(hit_pos, part[size_t(k)])) { + painted[i] = 1; + break; + } + } + }); + + TriangleSelector dst_sel(dst_mesh); + for (size_t i = 0; i < painted.size(); ++i) + if (painted[i]) + dst_sel.set_facet(int(i), EnforcerBlockerType::ENFORCER); + return dst_sel.serialize(); +} + +// Edge of the RGB lookup cube make_palette_quantizer() builds. 24 gives 13824 cells - far finer than +// the difference between any two printable colours - and costs one DeltaE00 per cell per palette +// entry to fill. +constexpr int PALETTE_LUT_EDGE = 24; + +// Ceiling on the printable palette, which bounds that fill cost (and the shader's uniform array). +constexpr int PALETTE_MAX_ENTRIES = 64; +// Ceiling on the filaments the palette's entries can refer to (the shaded preview shader's filament_rgb[]); +// mmu segmentation stops at Extruder16 anyway. +constexpr int PALETTE_MAX_FILAMENTS = 16; + +// sRGB (0..1) <-> CIELAB, D65. Exactly what the preview shader's srgb_to_lab() computes, so the CPU +// quantizer, the mixed-palette entries and the per-fragment preview all match in the same space. +// Not slic3r/Utils/ColorSpaceConvert: its RGB2Lab wants 0..1 but its Lab2RGB hands back linear +// values on a 0..100 scale, and the earlier code fed the former 0..255 and divided the latter by 255 - +// self-consistent enough for the bake's nearest-entry search to rank sensibly, but the preview, which +// compares real Lab against those values, picked the darkest filament everywhere. +static Vec3f srgb_to_lab(const Vec3f &c) +{ + const auto lin = [](float v) { return v > 0.04045f ? std::pow((v + 0.055f) / 1.055f, 2.4f) : v / 12.92f; }; + const float r = lin(c.x()), g = lin(c.y()), b = lin(c.z()); + const float x = (0.4124f * r + 0.3576f * g + 0.1805f * b) / 0.95047f; + const float y = (0.2126f * r + 0.7152f * g + 0.0722f * b); + const float z = (0.0193f * r + 0.1192f * g + 0.9505f * b) / 1.08883f; + const auto f = [](float t) { return t > 0.008856f ? std::cbrt(t) : 7.787f * t + 16.f / 116.f; }; + const float fx = f(x), fy = f(y), fz = f(z); + return Vec3f(116.f * fy - 16.f, 500.f * (fx - fy), 200.f * (fy - fz)); +} + +static Vec3f lab_to_srgb(const Vec3f &lab) +{ + const float fy = (lab.x() + 16.f) / 116.f, fx = lab.y() / 500.f + fy, fz = fy - lab.z() / 200.f; + const auto finv = [](float t) { return t > 0.206893f ? t * t * t : (t - 16.f / 116.f) / 7.787f; }; + const float x = finv(fx) * 0.95047f, y = finv(fy), z = finv(fz) * 1.08883f; + const float r = 3.2406f * x - 1.5372f * y - 0.4986f * z; + const float g = -0.9689f * x + 1.8758f * y + 0.0415f * z; + const float b = 0.0557f * x - 0.2040f * y + 1.0570f * z; + const auto gam = [](float v) { + v = std::clamp(v, 0.f, 1.f); + return v > 0.0031308f ? 1.055f * std::pow(v, 1.f / 2.4f) - 0.055f : 12.92f * v; + }; + return Vec3f(gam(r), gam(g), gam(b)); +} + +std::unique_ptr upload_height_thumbnail(const DecodedHeightTexture &decoded, int max_px = THUMBNAIL_MAX_PX) +{ + if (decoded.empty()) + return nullptr; + + // Preserve aspect; never upscale a texture that is already small. + const int scale = std::max(1, (std::max(decoded.width, decoded.height) + max_px - 1) / max_px); + const int w = std::max(1, decoded.width / scale); + const int h = std::max(1, decoded.height / scale); + + // A colour texture is shown in colour, so it can be told apart from its grey neighbours in the picker; its + // height is the luminance of those same colours, so nothing about the relief is hidden by that. + const bool color = decoded.has_color(); + std::vector rgba(size_t(w) * size_t(h) * 4); + for (int y = 0; y < h; ++y) + for (int x = 0; x < w; ++x) { + // Average the source block this destination pixel covers. + const int x0 = x * decoded.width / w, x1 = std::max(x0 + 1, (x + 1) * decoded.width / w); + const int y0 = y * decoded.height / h, y1 = std::max(y0 + 1, (y + 1) * decoded.height / h); + unsigned int sum[3] = { 0, 0, 0 }; + unsigned int n = 0; + for (int sy = y0; sy < y1 && sy < decoded.height; ++sy) + for (int sx = x0; sx < x1 && sx < decoded.width; ++sx, ++n) { + const size_t si = size_t(sy) * size_t(decoded.width) + size_t(sx); + for (int c = 0; c < 3; ++c) + sum[c] += color ? decoded.rgb[si * 3 + size_t(c)] : decoded.pixels[si]; + } + + const size_t di = (size_t(y) * size_t(w) + size_t(x)) * 4; + for (int c = 0; c < 3; ++c) + rgba[di + size_t(c)] = (n > 0) ? static_cast(sum[c] / n) : 0; + rgba[di + 3] = 255; + } + + auto texture = std::make_unique(); + if (!texture->load_from_raw_data(std::move(rgba), (unsigned int) w, (unsigned int) h, false, /* use_mipmaps */ false)) + return nullptr; + return texture; +} + +// The same upload, of the texture's *colour* rather than its height, for the fast preview to quantize +// per fragment. Null for a grayscale texture - there is nothing to show. +// +// Box-filtered down like the height is, and for a sharper reason: the fast preview quantizes every +// fragment independently, so any texel-scale noise left in the image becomes a scatter of single-pixel +// colour flips on screen. Filtering on the way to the GPU is where that is cheapest to remove. +std::unique_ptr upload_color_texture(const DecodedHeightTexture &decoded, int max_px) +{ + if (!decoded.has_color()) + return nullptr; + + const int scale = std::max(1, (std::max(decoded.width, decoded.height) + max_px - 1) / max_px); + const int w = std::max(1, decoded.width / scale); + const int h = std::max(1, decoded.height / scale); + + std::vector rgba(size_t(w) * size_t(h) * 4); + for (int y = 0; y < h; ++y) + for (int x = 0; x < w; ++x) { + const int x0 = x * decoded.width / w, x1 = std::max(x0 + 1, (x + 1) * decoded.width / w); + const int y0 = y * decoded.height / h, y1 = std::max(y0 + 1, (y + 1) * decoded.height / h); + unsigned int sum[3] = { 0, 0, 0 }; + unsigned int n = 0; + for (int sy = y0; sy < y1 && sy < decoded.height; ++sy) + for (int sx = x0; sx < x1 && sx < decoded.width; ++sx, ++n) { + const size_t si = (size_t(sy) * size_t(decoded.width) + size_t(sx)) * 3; + for (int c = 0; c < 3; ++c) + sum[c] += decoded.rgb[si + size_t(c)]; + } + const size_t di = (size_t(y) * size_t(w) + size_t(x)) * 4; + for (int c = 0; c < 3; ++c) + rgba[di + size_t(c)] = (n > 0) ? static_cast(sum[size_t(c)] / n) : 0; + rgba[di + 3] = 255; + } + + auto texture = std::make_unique(); + if (!texture->load_from_raw_data(std::move(rgba), (unsigned int) w, (unsigned int) h, false, false)) + return nullptr; + return texture; +} + +// Intersects the camera ray through `mouse_pos` (screen coords) with the plane passing through +// `plane_point_local`/`plane_normal_local` (mesh-local coords, transformed to world by `trafo`). +// Returns false if the ray is parallel to the plane or the plane is behind the camera. +bool ray_plane_hit(const Camera &camera, const Vec2d &mouse_pos, const Transform3d &trafo, + const Vec3f &plane_point_local, const Vec3f &plane_normal_local, Vec3d &out_world_hit) +{ + Vec3d ray_origin, ray_dir; + CameraUtils::ray_from_screen_pos(camera, mouse_pos, ray_origin, ray_dir); + + const Vec3d plane_point_world = trafo * plane_point_local.cast(); + const Vec3d plane_normal_world = (trafo.matrix().block(0, 0, 3, 3).inverse().transpose() * plane_normal_local.cast()).normalized(); + + const double denom = ray_dir.dot(plane_normal_world); + if (std::abs(denom) < 1e-8) + return false; + + const double t = (plane_point_world - ray_origin).dot(plane_normal_world) / denom; + if (t < 0.0) + return false; + + out_world_hit = ray_origin + ray_dir * t; + return true; +} +} // namespace + +GLGizmoTextureDisplacement::GLGizmoTextureDisplacement(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoPainterBase(parent, icon_filename, sprite_id) +{ +} + +bool GLGizmoTextureDisplacement::on_init() +{ + m_desc["cursor_size"] = _L("Brush size"); + m_desc["circle"] = _L("Circle"); + m_desc["sphere"] = _L("Sphere"); + m_desc["remove_layer"] = _L("Remove"); + m_desc["bake"] = _L("Bake"); + return true; +} + +std::string GLGizmoTextureDisplacement::on_get_name() const +{ + return _u8L("Texture displacement"); +} + +void GLGizmoTextureDisplacement::on_shutdown() +{ + m_parent.toggle_model_objects_visibility(true); + m_preview_glmodel.reset(); + m_shaded_preview_glmodel.reset(); + m_paint_overlay_glmodel.reset(); + m_paint_overlay_dirty = false; + // Any preview still in flight is superseded: raising the shared counter makes it abort at its next + // progress poll, and its completion handler then finds nothing to do. + m_preview_generation->fetch_add(1); + m_preview_job_pending = false; + m_uvcheck_glmodel.reset(); + m_wireframe_overlay_glmodel.reset(); + m_wireframe_overlay_vcount = 0; + m_seam_glmodel.reset(); + m_seam_hover_glmodel.reset(); + m_seam_hover_edge = { -1, -1 }; + m_seam_hover_vertex = -1; + m_seam_anchor_glmodel.reset(); + m_seam_path_mode = false; + m_seam_path_anchor = -1; + m_subdivide_editing = false; + m_subdivide_preview_tris = -1; + m_subdivide_preview_glmodel.reset(); + m_shaded_active_chart = -1; + m_shaded_active_face.clear(); + m_shaded_island_delta = Eigen::Matrix::Identity(); + m_island_drag_active = false; + m_island_move_set.clear(); + m_adjust_texture_mode = false; + m_seam_edit_mode = false; + m_adjust_drag_handle = AdjustHandle::None; + m_adjust_anchor_valid = false; + // The pane is request-only: closing the gizmo drops the request, so reopening it later doesn't + // silently reopen the pane too. + m_show_uv_editor = false; + wxGetApp().plater()->show_uv_editor(false); + + // Destroyed, not just hidden: unlike the UV pane (owned by Plater), this frame is owned here, and + // it holds a callback capturing `this`. Leaving it alive past the gizmo would leave that callback + // pointing at a gizmo that is no longer driving anything. + if (m_projector_frame != nullptr) { + m_projector_frame->Destroy(); + m_projector_frame = nullptr; + } + m_projector_tex_source = nullptr; // a rebuilt frame starts with no texture in it + m_projector_tex_smoothing = -1.f; +} + +PainterGizmoType GLGizmoTextureDisplacement::get_painter_type() const +{ + return PainterGizmoType::TEXTURE_DISPLACEMENT; +} + +wxString GLGizmoTextureDisplacement::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const +{ + // Right button does the opposite of the toggle; Shift always erases. + const bool erasing = shift_down || (m_erase_mode != (button_down == GLGizmoPainterBase::Button::Right)); + return erasing ? _L("Erase texture displacement paint") : _L("Paint texture displacement"); +} + +void GLGizmoTextureDisplacement::render_painter_gizmo() +{ + const Selection &selection = m_parent.get_selection(); + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + // Once anything is painted, m_preview_glmodel holds the true displaced result (same algorithm + // Bake uses). The untouched original topology (what render_triangles() draws) coincides + // exactly with it everywhere except the painted/displaced area, so both are drawn: the real + // preview geometry first, then the usual selection-highlight overlay with a small depth bias + // so it wins the depth test on the coincident (unpainted) surface - keeping the familiar + // enforcer/blocker highlight for precise brush editing there. Where the surface has actually + // been displaced, the raised preview geometry legitimately occludes the flat overlay - that + // visible relief is itself the "this is painted" indicator in that area. + // + // The shaded preview is different: it never actually moves geometry (it only shades), so + // its depth is identical to the overlay's *everywhere*, not just in the unpainted area - the + // depth-biased opaque overlay would win the depth test across the whole surface and hide the relief + // shading entirely. So render_triangles() is skipped for it. What is *not* skipped is + // render_paint_overlay(): leaving the shading as the only paint feedback meant a stroke that + // erased paint, or added it with no texture picked, changed nothing on screen until the whole + // preview rebuilt at stroke end - and in the true-displacement view the opaque overlay is hidden + // by the raised surface for the same reason. The translucent tint covers both cases. + // Coalesced shaded-preview rebuild from an in-progress UV island drag (see on_island_edited): done here, at + // most once per drawn frame, rather than synchronously in the UV canvas's mouse-move handler. + if (m_use_shaded_preview && m_shaded_preview_dirty) { + rebuild_shaded_preview_mesh(); + m_shaded_preview_dirty = false; + } + // Same coalescing for the paint tint, but on its own flag: a stroke marks this every mouse move + // (see on_mouse()) and it only costs the painted patch + if (m_paint_overlay_dirty) { + rebuild_paint_overlay(); + m_paint_overlay_dirty = false; + } + rebuild_other_paint_overlay(); // a no-op unless another layer's paint, the active layer or the preview changed + // is_initialized() alone is not enough: render_shaded_preview_mesh() also needs an active layer + // with a decoded texture and a compiled shader, and bails silently without them. Hiding the real + // volume for a shaded pass that then draws nothing is what made the model vanish - most obviously + // with zero layers, but equally with a layer that has no texture picked yet. + const bool use_shaded = m_use_shaded_preview && m_shaded_preview_glmodel.is_initialized() && shaded_preview_ready(); + const bool use_true_preview = !use_shaded && m_preview_glmodel.is_initialized(); + // In Checker/Distortion mode the UV-check overlay *is* the surface visualization the user is + // looking at, so the opaque paint-selection highlight must not be drawn on top of it - same + // reasoning as skipping it for the shaded preview (see bug #12). Without this the painted area + // covers the checker/heatmap and it can't be seen. + const bool show_paint_overlay = m_uv_check_mode == UVCheckMode::None; + + // Hide the real volume only when something is actually going to be drawn in its place; otherwise + // put it back. Getting this wrong leaves an invisible model, so it is decided once, here, rather + // than per branch below. + m_parent.toggle_model_objects_visibility(true); + if (use_shaded || use_true_preview) { + if (ModelVolume *mv = texture_volume()) + m_parent.toggle_model_objects_visibility(false, m_c->selection_info()->model_object(), + m_c->selection_info()->get_active_instance(), mv); + } + + if (use_shaded) { + render_shaded_preview_mesh(); + } else if (use_true_preview) { + render_preview_mesh(); + + if (show_paint_overlay) { + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glPolygonOffset(-1.0f, -1.0f)); + render_triangles(selection); + glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); + } + } else if (show_paint_overlay) { + render_triangles(selection); + } + + // Every other layer's paint, in muted grey, so all layers stay visible while one of them is edited. Drawn + // before the active layer's tint so that one reads on top where the two overlap. + if (show_paint_overlay) + render_paint_overlay(m_other_paint_glmodel); + + // The translucent paint tint. Needed in the shaded view because the opaque highlight above is + // skipped there, and in the true-displacement view because the displaced surface rises *above* + // the undisplaced overlay geometry and hides it exactly where the relief is strongest - in both + // cases leaving an erase stroke with no visible effect until the next full preview rebuild. + if (show_paint_overlay && (use_shaded || use_true_preview)) + render_paint_overlay(m_paint_overlay_glmodel); + + // The UV editor's island selection, shown on the model. Polled here rather than pushed: the pane + // changes its selection in its own mouse handling, and a compare of a few ints per frame is free. + { + const TextureDisplacementLayer *al = active_layer(); + const UVEditorCanvas *uv_canvas = wxGetApp().plater()->get_uv_editor_canvas(); + if (m_show_uv_editor && al != nullptr && al->projection_method == TextureProjectionMethod::LSCM && + uv_canvas != nullptr && !m_uv_editor_unwrap.empty()) { + if (uv_canvas->selected_islands() != m_island_overlay_selection) + rebuild_island_overlay(uv_canvas->selected_islands()); + render_island_overlay(); + } else if (m_island_overlay_glmodel.is_initialized()) { + m_island_overlay_glmodel.reset(); + m_island_overlay_selection.clear(); + } + } + + // Diagnostic overlays, drawn on top of whatever preview is active (both pull toward the camera + // with a polygon offset so they win the depth test against the coincident surface). + if (m_uv_check_mode != UVCheckMode::None) + render_uvcheck_mesh(); + // While previewing a subdivision, its wireframe stands in for the mesh wireframe - it shows the + // density the model *would* have. The normal wireframe toggle is left untouched underneath, so it + // returns to whatever it was once the preview ends (which is what keeps an already-on wireframe on). + if (m_subdivide_editing) + render_subdivide_preview(); + else if (m_wireframe_overlay) + render_wireframe_overlay(); + // Marked seams are always shown for an LSCM layer, so existing cuts are visible before entering + // seam-edit mode - but they matter most while marking. + render_seam_overlay(); + + m_c->object_clipper()->render_cut(); + m_c->instances_hider()->render_cut(); + if (m_adjust_texture_mode) + render_adjust_texture_gizmo(); + else if (!m_seam_edit_mode) // the brush cursor is meaningless while marking seams + render_cursor(); + + glsafe(::glDisable(GL_BLEND)); +} + +bool GLGizmoTextureDisplacement::on_mouse(const wxMouseEvent &mouse_event) +{ + if (m_seam_edit_mode) + return on_mouse_seam(mouse_event); + if (m_adjust_texture_mode) + return on_mouse_adjust_texture(mouse_event); + + const bool handled = GLGizmoPainterBase::on_mouse(mouse_event); + // A consumed drag/click is a paint (or erase) event: the base class has already updated the live + // TriangleSelector, but nothing is flushed to the model - and so nothing rebuilds - until the + // stroke ends. Mark the tint stale so it follows the brush from the first frame instead. Only the + // flag is set here; the rebuild is coalesced to once per drawn frame in render_painter_gizmo(). + if (handled && (mouse_event.Dragging() || mouse_event.LeftDown() || mouse_event.RightDown() || + mouse_event.LeftUp() || mouse_event.RightUp())) + m_paint_overlay_dirty = true; + return handled; +} + +bool GLGizmoTextureDisplacement::on_mouse_seam(const wxMouseEvent &mouse_event) +{ + // Hold Ctrl to orbit/pan the camera while in seam mode, exactly as the base painter lets you do + // while painting: with Ctrl down we consume nothing, so the canvas gets the drag and moves the + // view. Without this, seam mode swallowed every left-drag and the camera couldn't be rotated. + if (mouse_event.CmdDown()) + return false; + + // Left-click marks/unmarks an edge; swallow the rest of the left-button stream so a drag doesn't + // paint, but let everything else through so the camera still orbits/pans/zooms normally. + if (mouse_event.LeftDown()) { + const Vec2d pos(mouse_event.GetX(), mouse_event.GetY()); + if (m_seam_path_mode) { + // Two-click shortest-path seam: first click sets the start vertex, the next seams the whole + // path to it and becomes the new start (so a seam line chains click by click). + const int v = seam_vertex_at(pos); + if (v >= 0) { + if (m_seam_path_anchor < 0) + m_seam_path_anchor = v; + else { + mark_seam_path(m_seam_path_anchor, v); + m_seam_path_anchor = v; + } + rebuild_seam_anchor_overlay(); + m_parent.set_as_dirty(); + } + } else { + toggle_seam_at(pos); + } + return true; + } + // Live hover: highlight what a click would pick, so the clickable target is obvious (the "I don't + // know how it works" the user hit). In normal mode that is an edge; in shortest-path mode it is a + // vertex. Don't swallow the motion - the camera still needs it. + if (mouse_event.Moving()) { + const Vec2d pos(mouse_event.GetX(), mouse_event.GetY()); + if (m_seam_path_mode) { + const int v = seam_vertex_at(pos); + if (v != m_seam_hover_vertex) { + m_seam_hover_vertex = v; + m_seam_hover_edge = { -1, -1 }; + rebuild_seam_hover_overlay(); + m_parent.set_as_dirty(); + } + } else { + const std::pair edge = seam_edge_at(pos); + if (edge != m_seam_hover_edge) { + m_seam_hover_edge = edge; + m_seam_hover_vertex = -1; + rebuild_seam_hover_overlay(); + m_parent.set_as_dirty(); + } + } + } + if (mouse_event.LeftUp() || (mouse_event.Dragging() && mouse_event.LeftIsDown())) + return true; + return false; +} + +int GLGizmoTextureDisplacement::texture_volume_raycaster_index() const +{ + const ModelVolume *mv = texture_volume(); + const ModelObject *mo = m_c->selection_info()->model_object(); + if (mv == nullptr || mo == nullptr) + return -1; + + int idx = -1, count = 0; + for (const ModelVolume *v : mo->volumes) { + if (!v->is_model_part()) + continue; + if (v == mv) { idx = count; break; } + ++count; + } + return (idx >= 0 && idx < int(m_c->raycaster()->raycasters().size())) ? idx : -1; +} + +std::pair GLGizmoTextureDisplacement::seam_edge_at(const Vec2d &mouse_pos) const +{ + const ModelVolume *mv = texture_volume(); + const ModelObject *mo = m_c->selection_info()->model_object(); + if (mv == nullptr || mo == nullptr) + return { -1, -1 }; + + const int idx = texture_volume_raycaster_index(); + if (idx < 0) + return { -1, -1 }; + const auto &raycasters = m_c->raycaster()->raycasters(); + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + Vec3f hit = Vec3f::Zero(), normal = Vec3f::Zero(); + size_t facet = 0; + if (!raycasters[size_t(idx)]->unproject_on_mesh(mouse_pos, trafo, camera, hit, normal, + m_c->object_clipper()->get_clipping_plane(), &facet)) + return { -1, -1 }; + + const indexed_triangle_set &its = mv->mesh().its; + if (facet >= its.indices.size()) + return { -1, -1 }; + const stl_triangle_vertex_indices &tri = its.indices[facet]; + + // The facet edge nearest the hit point (point-to-segment distance in mesh space). + const auto seg_dist = [](const Vec3f &p, const Vec3f &a, const Vec3f &b) { + const Vec3f ab = b - a; + const float l2 = ab.squaredNorm(); + const float t = (l2 > 1e-12f) ? std::clamp((p - a).dot(ab) / l2, 0.f, 1.f) : 0.f; + return (p - (a + ab * t)).norm(); + }; + int best_i = 0; + float best_d = std::numeric_limits::max(); + for (int i = 0; i < 3; ++i) { + const float d = seg_dist(hit, its.vertices[tri[i]], its.vertices[tri[(i + 1) % 3]]); + if (d < best_d) { best_d = d; best_i = i; } + } + const int a = tri[best_i], b = tri[(best_i + 1) % 3]; + return { std::min(a, b), std::max(a, b) }; +} + +void GLGizmoTextureDisplacement::toggle_seam_at(const Vec2d &mouse_pos) +{ + TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr) + return; + const std::pair edge = seam_edge_at(mouse_pos); + if (edge.first < 0) + return; + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Mark texture seam"), UndoRedo::SnapshotType::GizmoAction); + auto &seams = layer->lscm_seam_edges; + if (const auto it = std::find(seams.begin(), seams.end(), edge); it != seams.end()) + seams.erase(it); + else + seams.push_back(edge); + rebuild_preview(); +} + +int GLGizmoTextureDisplacement::seam_vertex_at(const Vec2d &mouse_pos) const +{ + const ModelVolume *mv = texture_volume(); + const ModelObject *mo = m_c->selection_info()->model_object(); + if (mv == nullptr || mo == nullptr) + return -1; + const int idx = texture_volume_raycaster_index(); + if (idx < 0) + return -1; + const auto &raycasters = m_c->raycaster()->raycasters(); + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + Vec3f hit = Vec3f::Zero(), normal = Vec3f::Zero(); + size_t facet = 0; + if (!raycasters[size_t(idx)]->unproject_on_mesh(mouse_pos, trafo, camera, hit, normal, + m_c->object_clipper()->get_clipping_plane(), &facet)) + return -1; + const indexed_triangle_set &its = mv->mesh().its; + if (facet >= its.indices.size()) + return -1; + const stl_triangle_vertex_indices &tri = its.indices[facet]; + int best = tri[0]; + float best_d = std::numeric_limits::max(); + for (int i = 0; i < 3; ++i) { + const float d = (hit - its.vertices[tri[i]]).squaredNorm(); + if (d < best_d) { best_d = d; best = tri[i]; } + } + return best; +} + +void GLGizmoTextureDisplacement::mark_seam_path(int v_from, int v_to) +{ + TextureDisplacementLayer *layer = active_layer(); + const ModelVolume *mv = texture_volume(); + if (layer == nullptr || mv == nullptr || v_from < 0 || v_to < 0 || v_from == v_to) + return; + const indexed_triangle_set &its = mv->mesh().its; + const size_t n = its.vertices.size(); + if (size_t(v_from) >= n || size_t(v_to) >= n) + return; + + // Shortest path over the mesh's edge graph (Dijkstra, edge weight = length). Built on demand; one + // pass per click is fine even on a dense mesh. + std::vector>> adj(n); + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) { + const int a = tri[i], b = tri[(i + 1) % 3]; + const float w = (its.vertices[size_t(a)] - its.vertices[size_t(b)]).norm(); + adj[size_t(a)].push_back({ b, w }); + adj[size_t(b)].push_back({ a, w }); + } + + std::vector dist(n, std::numeric_limits::infinity()); + std::vector prev(n, -1); + using QN = std::pair; + std::priority_queue, std::greater> pq; + dist[size_t(v_from)] = 0.f; + pq.push({ 0.f, v_from }); + while (!pq.empty()) { + const auto [d, u] = pq.top(); + pq.pop(); + if (d > dist[size_t(u)]) + continue; + if (u == v_to) + break; + for (const auto &[w, ew] : adj[size_t(u)]) { + const float nd = d + ew; + if (nd < dist[size_t(w)]) { + dist[size_t(w)] = nd; + prev[size_t(w)] = u; + pq.push({ nd, w }); + } + } + } + if (prev[size_t(v_to)] < 0) + return; // unreachable (disconnected components) + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Mark texture seam path"), UndoRedo::SnapshotType::GizmoAction); + auto &seams = layer->lscm_seam_edges; + for (int v = v_to; v != v_from && v >= 0; v = prev[size_t(v)]) { + const int p = prev[size_t(v)]; + if (p < 0) + break; + const std::pair e{ std::min(v, p), std::max(v, p) }; + if (std::find(seams.begin(), seams.end(), e) == seams.end()) + seams.push_back(e); + } + rebuild_preview(); +} + +void GLGizmoTextureDisplacement::rebuild_seam_anchor_overlay() +{ + m_seam_anchor_glmodel.reset(); + const ModelVolume *mv = texture_volume(); + if (!m_seam_edit_mode || !m_seam_path_mode || mv == nullptr || m_seam_path_anchor < 0) + return; + const indexed_triangle_set &its = mv->mesh().its; + if (size_t(m_seam_path_anchor) >= its.vertices.size()) + return; + + // The anchor's incident edges, so the path's start vertex is visible on the model. + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + unsigned nn = 0; + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) { + const int a = tri[i], b = tri[(i + 1) % 3]; + if (a == m_seam_path_anchor || b == m_seam_path_anchor) { + init_data.add_vertex(its.vertices[size_t(a)]); + init_data.add_vertex(its.vertices[size_t(b)]); + init_data.add_line(nn, nn + 1); + nn += 2; + } + } + if (!init_data.is_empty()) + m_seam_anchor_glmodel.init_from(std::move(init_data)); +} + +void GLGizmoTextureDisplacement::rebuild_seam_hover_overlay() +{ + m_seam_hover_glmodel.reset(); + const ModelVolume *mv = texture_volume(); + if (!m_seam_edit_mode || mv == nullptr) + return; + const indexed_triangle_set &its = mv->mesh().its; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + + if (m_seam_path_mode) { + // Highlight the hovered vertex as its ring of incident edges, so the click target is legible on + // a dense mesh (matching the green anchor's style, in the hover yellow render_seam_overlay uses). + if (m_seam_hover_vertex < 0 || size_t(m_seam_hover_vertex) >= its.vertices.size()) + return; + unsigned nn = 0; + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) { + const int a = tri[i], b = tri[(i + 1) % 3]; + if (a == m_seam_hover_vertex || b == m_seam_hover_vertex) { + init_data.add_vertex(its.vertices[size_t(a)]); + init_data.add_vertex(its.vertices[size_t(b)]); + init_data.add_line(nn, nn + 1); + nn += 2; + } + } + if (!init_data.is_empty()) + m_seam_hover_glmodel.init_from(std::move(init_data)); + return; + } + + if (m_seam_hover_edge.first < 0 || size_t(m_seam_hover_edge.first) >= its.vertices.size() || + size_t(m_seam_hover_edge.second) >= its.vertices.size()) + return; + init_data.reserve_vertices(2); + init_data.reserve_indices(2); + init_data.add_vertex(its.vertices[size_t(m_seam_hover_edge.first)]); + init_data.add_vertex(its.vertices[size_t(m_seam_hover_edge.second)]); + init_data.add_line(0, 1); + m_seam_hover_glmodel.init_from(std::move(init_data)); +} + +void GLGizmoTextureDisplacement::rebuild_seam_overlay() +{ + m_seam_glmodel.reset(); + const ModelVolume *mv = texture_volume(); + const TextureDisplacementLayer *layer = active_layer(); + if (mv == nullptr || layer == nullptr || layer->lscm_seam_edges.empty()) + return; + const indexed_triangle_set &its = mv->mesh().its; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + init_data.reserve_vertices(layer->lscm_seam_edges.size() * 2); + init_data.reserve_indices(layer->lscm_seam_edges.size() * 2); + unsigned n = 0; + for (const auto &[a, b] : layer->lscm_seam_edges) { + if (a < 0 || b < 0 || size_t(a) >= its.vertices.size() || size_t(b) >= its.vertices.size()) + continue; + init_data.add_vertex(its.vertices[size_t(a)]); + init_data.add_vertex(its.vertices[size_t(b)]); + init_data.add_line(n, n + 1); + n += 2; + } + if (!init_data.is_empty()) + m_seam_glmodel.init_from(std::move(init_data)); +} + +void GLGizmoTextureDisplacement::render_seam_overlay() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + const bool have_marked = m_seam_glmodel.is_initialized(); + const bool have_hover = m_seam_edit_mode && m_seam_hover_glmodel.is_initialized(); + const bool have_anchor = m_seam_edit_mode && m_seam_anchor_glmodel.is_initialized(); + if (mo == nullptr || mv == nullptr || (!have_marked && !have_hover && !have_anchor)) + return; + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + glsafe(::glEnable(GL_POLYGON_OFFSET_LINE)); + glsafe(::glPolygonOffset(-2.0f, -2.0f)); // pull further forward than the wireframe so seams read on top + // A seam edge is geometrically the same line as a wireframe edge, so a mere polygon offset is a + // fragile way to make the red seam beat the white wireframe - drivers apply GL_POLYGON_OFFSET_LINE + // inconsistently, and the two lines then z-fight and the wireframe wins. When the wireframe is on, + // or while actively marking, just draw the seams with depth testing off so they are unconditionally + // on top - being visible is the one thing this overlay has to guarantee. + const bool seams_on_top = m_wireframe_overlay || m_seam_edit_mode; + if (seams_on_top) + glsafe(::glDisable(GL_DEPTH_TEST)); +#if !SLIC3R_OPENGL_ES + const bool wide = !OpenGLManager::get_gl_info().is_core_profile(); + if (wide) + glsafe(::glLineWidth(4.0f)); +#endif // !SLIC3R_OPENGL_ES + if (have_marked) { + m_seam_glmodel.set_color(ColorRGBA(1.0f, 0.15f, 0.15f, 1.0f)); // Blender's seam red + m_seam_glmodel.render(); + } + // The edge a click would toggle, in yellow and pulled the furthest forward, so it is unmistakable + // which edge is being targeted while marking seams. + if (have_hover) { + glsafe(::glPolygonOffset(-3.0f, -3.0f)); + m_seam_hover_glmodel.set_color(ColorRGBA(1.0f, 0.9f, 0.15f, 1.0f)); + m_seam_hover_glmodel.render(); + } + // The shortest-path start vertex, shown as its ring of incident edges in green. + if (have_anchor) { + glsafe(::glPolygonOffset(-3.0f, -3.0f)); + m_seam_anchor_glmodel.set_color(ColorRGBA(0.2f, 1.0f, 0.4f, 1.0f)); + m_seam_anchor_glmodel.render(); + } +#if !SLIC3R_OPENGL_ES + if (wide) + glsafe(::glLineWidth(1.0f)); +#endif // !SLIC3R_OPENGL_ES + glsafe(::glDisable(GL_POLYGON_OFFSET_LINE)); + if (seams_on_top) + glsafe(::glEnable(GL_DEPTH_TEST)); + shader->stop_using(); +} + +void GLGizmoTextureDisplacement::render_preview_mesh() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + + auto *shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + shader->start_using(); + const Camera &camera = wxGetApp().plater()->get_camera(); + const Transform3d &view_matrix = camera.get_view_matrix(); + shader->set_uniform("view_model_matrix", view_matrix * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); + shader->set_uniform("view_normal_matrix", view_normal_matrix); + if (m_preview_color_runs.empty()) { + m_preview_glmodel.render(); + } else { + // set_color() writes the uniform the shader reads, so one call per group is all the + // per-triangle colour this needs. + for (const PreviewColorRun &run : m_preview_color_runs) { + m_preview_glmodel.set_color(run.color); + m_preview_glmodel.render(run.range, shader); + } + } + shader->stop_using(); +} + +float GLGizmoTextureDisplacement::layer_texture_aspect(const TextureDisplacementLayer &layer) +{ + // decode_height_texture() is cached on the image_data allocation, so this is a hash lookup rather + // than a PNG decode - cheap enough to call per rebuild. + const DecodedHeightTexture tex = decode_height_texture(layer); + return (tex.width > 0 && tex.height > 0) ? float(tex.width) / float(tex.height) : 1.f; +} + +indexed_triangle_set GLGizmoTextureDisplacement::patch_in_world(const indexed_triangle_set &patch) const +{ + const ModelVolume *mv = texture_volume(); + if (mv == nullptr) + return patch; + // The bake's own frame, so the projection this feeds agrees with what bakes. + const Transform3d to_world = texture_displacement_bake_frame(texture_displacement_volume_to_world(*mv)); + if (to_world.matrix().isApprox(Transform3d::Identity().matrix())) + return patch; + + indexed_triangle_set world = patch; + for (Vec3f &v : world.vertices) + v = (to_world * v.cast()).cast(); + return world; +} + +std::vector GLGizmoTextureDisplacement::compute_layer_vertex_uvs(const indexed_triangle_set &local_patch, + const TextureDisplacementLayer &layer) const +{ + // The bake maps the texture in world millimetres, so "Tile size (mm)" means the same thing on a + // scaled instance as it does on an untouched one (see build_texture_displacement()). Everything + // that has to agree with the bake - the fast preview's uvs, the checker/distortion overlays - + // therefore has to project from the same world positions, not from the volume's own. + const indexed_triangle_set patch = patch_in_world(local_patch); + const float aspect = layer_texture_aspect(layer); + if (layer.projection_method == TextureProjectionMethod::LSCM) { + // compute_lscm_uvs() returns the unwrap's own (raw, mm) coordinates with the island placement + // folded in - it does *not* apply the layer's tiling/rotation/offset. The bake applies those + // on top (sample_layer_height()'s lscm branch runs the result through sample_at()), so the + // shader's precomputed-uv path has to as well, or the fast preview samples millimetre-valued + // coordinates as if they were uv and shows the texture at a wildly wrong scale. + std::vector uv = compute_lscm_uvs(patch, layer); + for (Vec2f &p : uv) + p = apply_uv_transform(p, layer, aspect); + return uv; + } + if (layer.projection_method == TextureProjectionMethod::ViewProjected) { + std::vector uv(patch.vertices.size()); + for (size_t vi = 0; vi < patch.vertices.size(); ++vi) { + if (layer.view_project_projective) { + // Matches sample_layer_height()'s projective branch, including skipping + // apply_uv_transform(). A vertex behind the projector gets a uv far outside [0,1] so + // it samples as nothing, rather than the mirrored coordinate a blind divide gives. + if (!project_uv_projective(layer.view_project_matrix, patch.vertices[vi], uv[vi])) + uv[vi] = Vec2f(-1e6f, -1e6f); + continue; + } + const Vec2f planar(patch.vertices[vi].dot(layer.view_project_right), + patch.vertices[vi].dot(layer.view_project_up)); + uv[vi] = apply_uv_transform(planar, layer, aspect); + } + return uv; + } + return {}; // Triplanar / Cylindrical / Spherical: the shader projects on its own +} + +int GLGizmoTextureDisplacement::layer_projection_frame(const indexed_triangle_set &local_patch, + const TextureDisplacementLayer &layer, + Vec3f ¢er, Vec3f &axis) const +{ + center = Vec3f::Zero(); + axis = Vec3f::UnitZ(); + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || (layer.projection_method != TextureProjectionMethod::Cylindrical && + layer.projection_method != TextureProjectionMethod::Spherical)) + return 0; + // The bake averages the *whole mesh's* vertex normals over the patch's corners, so this has to as + // well: a patch-only average would sometimes quantize to a different world axis and wrap the + // texture the other way round. Both meshes go through patch_in_world() first, which is the frame + // the shaders' tex_pos lives in. + Vec3f average_normal; + texture_displacement_patch_frame(patch_in_world(local_patch), + texture_displacement_vertex_normals(patch_in_world(mv->mesh().its)), + center, axis, average_normal); + return layer.projection_method == TextureProjectionMethod::Cylindrical ? 1 : 2; +} + +std::vector GLGizmoTextureDisplacement::compute_layer_corner_uvs(const indexed_triangle_set &local_patch, + const TextureDisplacementLayer &layer) const +{ + if (layer.projection_method == TextureProjectionMethod::LSCM) { + const indexed_triangle_set patch = patch_in_world(local_patch); + const float aspect = layer_texture_aspect(layer); + std::vector uv = compute_lscm_corner_uvs(patch, layer); + for (Vec2f &p : uv) + p = apply_uv_transform(p, layer, aspect); + return uv; + } + // Single-valued per point: fan the per-vertex result out over the corners. + const std::vector per_vertex = compute_layer_vertex_uvs(local_patch, layer); + if (per_vertex.size() != local_patch.vertices.size()) + return {}; + std::vector corner(local_patch.indices.size() * 3); + for (size_t f = 0; f < local_patch.indices.size(); ++f) + for (int k = 0; k < 3; ++k) + corner[f * 3 + size_t(k)] = per_vertex[size_t(local_patch.indices[f][k])]; + return corner; +} + +void GLGizmoTextureDisplacement::rebuild_shaded_preview_mesh() +{ + m_shaded_preview_glmodel.reset(); + + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_triangle_selectors.empty()) + return; + + // Uses the *live* selector (not the flushed model facet data), so this reflects an in-progress + // stroke immediately rather than only once it ends - the point of this preview mode is to be + // the fast, no-CPU-meshing one. + const indexed_triangle_set patch = m_triangle_selectors[0]->get_facets_strict(EnforcerBlockerType::ENFORCER); + if (patch.indices.empty()) + return; + + // No "patch.vertices.size() == mesh vertex count" check here, and that is the point: a *brush* + // stroke splits triangles, so the selector appends split vertices and the patch array is longer + // than the mesh's. An earlier version bailed out on that as "shouldn't happen", which meant the + // shaded model was never built while brushing and render_painter_gizmo() silently fell back to the + // Normal (true-displacement) preview - Fast looked broken for brush and fine for Face/Connected + // area, because only the brush splits. Everything below indexes the patch's own vertex array, so + // the extra vertices are simply carried through. + + // Unpainted triangles, so the surrounding surface still renders (the render path hides the real + // model in shaded mode). get_facets_strict() returns the same vertex array whatever state is asked. + const indexed_triangle_set rest = m_triangle_selectors[0]->get_facets_strict(EnforcerBlockerType::NONE); + + // For LSCM we hand the shader the finished per-vertex texture uv (island placement + tiling/ + // rotation/offset already folded in, exactly what the bake samples), because it cannot be + // reconstructed in the fragment shader the way a triplanar projection can. This is also what + // makes the fast preview follow the UV editor: the uvs move when an island is dragged, so this + // mesh rebuilds (on drag end) with them. The other projections keep projecting in-shader. + // Per *corner*, not per vertex: the mesh below is flat (unshared) anyway, so each triangle can + // carry its own chart's UVs - see compute_layer_corner_uvs(). + const TextureDisplacementLayer *active = active_layer(); + std::vector corner_uv = active != nullptr ? compute_layer_corner_uvs(patch, *active) : std::vector{}; + m_shaded_preview_uses_vertex_uv = corner_uv.size() == patch.indices.size() * 3; + if (!m_shaded_preview_uses_vertex_uv) + corner_uv.clear(); + m_shaded_projection_mode = (active != nullptr && !m_shaded_preview_uses_vertex_uv) ? + layer_projection_frame(patch, *active, m_shaded_patch_center, m_shaded_patch_axis) : 0; + + // Which triangles the in-flight UV drag moves. Computed here, against the very patch this mesh is + // built from, so the flags can never be indexed by a different triangle count than they were sized + // for (the drag starts from the flushed facet data, a brush stroke changes the live selector). + compute_shaded_active_faces(m_shaded_active_chart >= 0 ? m_island_move_set : std::vector{}, patch.indices.size()); + + // Colour is quantized per *fragment* in the shader now (see the .fs), so this mesh carries no + // colour of its own - the palette and the colour texture are uniforms, and every pixel matches the + // image rather than the facet it landed on. What the *bake* will produce, at facet resolution, is + // what the Normal view shows. + m_shaded_preview_palette = (active != nullptr && active->color_enabled) ? cached_palette() + : std::vector{}; + + GLModel::Geometry init_data; + // P3N3T2: normal.x carries the paint weight, tex_coord the precomputed uv (see the vertex shader). + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3T2 }; + + // Per-triangle weighting via a *flat* (unshared-vertex) mesh: every corner of a painted triangle + // gets weight 1, every corner of an unpainted one weight 0. This is what a coarse mesh needs - one + // painted face of a raw cube has no strictly-interior vertex (all 8 are shared), so per-vertex + // weighting would either bleed onto the neighbours (boundary weight 1) or vanish outright (boundary + // weight 0, which is what made a single face show nothing). Duplicating vertices costs no shading + // quality here because the preview shader takes its surface normal from screen-space derivatives of + // position (dFdx/dFdy), not from a per-vertex normal. normal.y flags the UV-editor island being + // dragged so the shader can move just that island via the island_delta uniform. + const size_t tri_total = patch.indices.size() + rest.indices.size(); + init_data.reserve_vertices(tri_total * 3); + init_data.reserve_indices(tri_total * 3); + unsigned vcount = 0; + const auto emit_triangles = [&](const indexed_triangle_set &its, float weight, bool painted) { + for (size_t f = 0; f < its.indices.size(); ++f) { + const stl_triangle_vertex_indices &tri = its.indices[f]; + // One value for the whole triangle: island_active is an interpolated varying, so the three + // corners have to agree or the shader moves part of a triangle and not the rest. + const float act = (painted && f < m_shaded_active_face.size() && m_shaded_active_face[f]) ? 1.f : 0.f; + for (int i = 0; i < 3; ++i) { + const int idx = tri[i]; + const Vec2f uv = (painted && m_shaded_preview_uses_vertex_uv) ? corner_uv[f * 3 + size_t(i)] + : Vec2f::Zero(); + init_data.add_vertex(its.vertices[size_t(idx)], Vec3f(weight, act, 0.f), uv); + } + init_data.add_triangle(vcount, vcount + 1, vcount + 2); + vcount += 3; + } + }; + emit_triangles(patch, 1.f, true); // painted -> shaded as relief, and coloured by the shader + // Untouched surface: flat, so it still shows but carries no relief - and uncoloured, which is what the + // bake leaves it as (EnforcerBlockerType::NONE, i.e. the volume's own filament). + emit_triangles(rest, 0.f, false); + + m_shaded_preview_glmodel.init_from(std::move(init_data)); + // GLModel::render() unconditionally re-sets the shader's "uniform_color" from this internal + // color field right before drawing (see GLModel.cpp) - setting the uniform manually in + // render_shaded_preview_mesh() would just get overwritten by it, so it must be set here instead. + // GLModel::Geometry defaults to BLACK, which is exactly what showed up before this was added. + m_shaded_preview_glmodel.set_color(GLVolume::NEUTRAL_COLOR); + + // The mesh now reflects the islands' current placement, so any live drag delta is measured from + // here: reset it to identity and record the dragged island's baked transform. + m_shaded_island_delta = Eigen::Matrix::Identity(); + const TextureDisplacementLayer *al = active_layer(); + if (m_shaded_active_chart >= 0 && al != nullptr) { + const std::vector> xf = uv_editor_island_transforms(*al); + m_shaded_baked_active_xf = (size_t(m_shaded_active_chart) < xf.size()) ? xf[size_t(m_shaded_active_chart)] + : Eigen::Matrix::Identity(); + } else { + m_shaded_baked_active_xf = Eigen::Matrix::Identity(); + } +} + +void GLGizmoTextureDisplacement::compute_shaded_active_faces(const std::vector &charts, size_t patch_face_count) +{ + m_shaded_active_face.clear(); + if (charts.empty() || patch_face_count == 0) + return; + const PatchUnwrap &u = m_uv_editor_unwrap; + if (u.source_face.size() != u.indices.size()) + return; + m_shaded_active_face.assign(patch_face_count, 0); + // Flag every triangle of every chart being moved. For a group/multi move that is more than one + // chart, but since such a move is a pure translation the shader applies the same delta to them all + // (see on_island_edited) - exactly the "joined islands move together" behaviour. + for (size_t t = 0; t < u.indices.size(); ++t) { + const int f = u.source_face[t]; + const int v0 = u.indices[t][0]; // a triangle lies in one chart, so any corner names it + if (f < 0 || size_t(f) >= m_shaded_active_face.size() || v0 < 0 || size_t(v0) >= u.vertex_chart.size()) + continue; + if (std::find(charts.begin(), charts.end(), u.vertex_chart[size_t(v0)]) != charts.end()) + m_shaded_active_face[size_t(f)] = 1; + } +} + +int GLGizmoTextureDisplacement::island_group_of(const std::vector &groups, int c) +{ + return (c >= 0 && size_t(c) < groups.size() && groups[size_t(c)] >= 0) ? groups[size_t(c)] : c; +} + +void GLGizmoTextureDisplacement::join_island_groups(std::vector &groups, int a, int b, int chart_count) +{ + if (a < 0 || b < 0 || chart_count <= 0) + return; + // Materialise to a full explicit table first, so singletons (which were implicit) get a concrete id + // that the relabel loop below can match on. + if (int(groups.size()) < chart_count) { + const size_t old = groups.size(); + groups.resize(size_t(chart_count)); + for (size_t i = old; i < groups.size(); ++i) + groups[i] = int(i); + } + for (size_t i = 0; i < groups.size(); ++i) + if (groups[i] < 0) + groups[i] = int(i); + const int ga = groups[size_t(a)], gb = groups[size_t(b)]; + if (ga == gb) + return; + const int g = std::min(ga, gb); + for (int &x : groups) + if (x == ga || x == gb) + x = g; +} + +std::vector GLGizmoTextureDisplacement::build_island_move_set(const TextureDisplacementLayer &layer, int primary) const +{ + std::vector set; + const int chart_count = std::max(m_uv_editor_unwrap.chart_count, 0); + + // Seed with the pane's multi-selection (falling back to just the primary if the canvas has none). + std::vector seeds; + if (const UVEditorCanvas *canvas = wxGetApp().plater()->get_uv_editor_canvas()) + seeds = canvas->selected_islands(); + if (seeds.empty() && primary >= 0) + seeds.push_back(primary); + + const auto add = [&set](int c) { + if (c >= 0 && std::find(set.begin(), set.end(), c) == set.end()) + set.push_back(c); + }; + for (int s : seeds) { + add(s); + // Pull in every chart sharing s's join group, so a joined pair moves as one. + const int gs = island_group_of(layer.island_groups, s); + for (int c = 0; c < chart_count; ++c) + if (island_group_of(layer.island_groups, c) == gs) + add(c); + } + add(primary); // never leave the primary out, whatever the selection state + return set; +} + +void GLGizmoTextureDisplacement::render_shaded_preview_mesh() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr || !m_shaded_preview_glmodel.is_initialized()) + return; + + const TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr || layer->empty()) + return; + + // Full-resolution height upload (smoothing-aware), whose grayscale value lives in the R channel + // exactly as the shader samples it. Deliberately *not* the layer-list panel's thumbnail: that one + // is box-filtered down to 128 px for a ~48 px row, and feeding it to the shader cost the preview + // three quarters of the height map's detail - and, since height_tex_texel is derived from it, also + // flattened the shading gradient and made the parallax march skip itself at angles where it should + // run. Cached on the image_data pointer + smoothing, so no PNG is decoded per frame. + GLTexture *tex = get_layer_height_texture(*layer); + if (tex == nullptr || tex->get_width() <= 0 || tex->get_height() <= 0) + return; + + GLShaderProgram *shader = wxGetApp().get_shader("texture_displacement_shaded"); + if (shader == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("volume_world_matrix", trafo_matrix); + const ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); + shader->set_uniform("clipping_plane", clp_data.clp_dataf); + shader->set_uniform("z_range", clp_data.z_range); + // The shader works on world-space normals (it projects the texture in world millimetres, as the + // bake does), so the normal matrix is the view rotation alone - no model part. + const Matrix3d view_normal_matrix = camera.get_view_matrix().matrix().block(0, 0, 3, 3); + shader->set_uniform("view_normal_matrix", view_normal_matrix); + shader->set_uniform("volume_mirrored", trafo_matrix.matrix().determinant() < 0.0); + glsafe(::glActiveTexture(GL_TEXTURE0)); + glsafe(::glBindTexture(GL_TEXTURE_2D, tex->get_id())); + // Match DecodedHeightTexture::sample()'s tiling. The sampler's wrap mode is the only place the + // GPU path can express this, and nothing ever set it - so it sat at GL_REPEAT no matter what the + // layer said: a MirroredRepeat layer previewed as a plain repeat, and a layer with tiling *off* + // previewed as an endless tiling where the bake produces one placement and nothing around it. + // CLAMP_TO_BORDER with a zero border is the exact analogue of sample()'s "outside [0,1) is 0". + // GL_CLAMP_TO_BORDER is desktop-GL only; on ES the nearest thing is CLAMP_TO_EDGE, which smears + // the border row instead of vanishing - still much closer to the bake than an endless repeat. +#if SLIC3R_OPENGL_ES + const GLint no_tile_wrap = GL_CLAMP_TO_EDGE; +#else + const GLint no_tile_wrap = GL_CLAMP_TO_BORDER; +#endif + const GLint wrap = !layer->tile_enabled ? no_tile_wrap : + (layer->tile_method == TextureTileMethod::MirroredRepeat) ? GL_MIRRORED_REPEAT : + GL_REPEAT; + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap)); +#if !SLIC3R_OPENGL_ES + if (wrap == GL_CLAMP_TO_BORDER) { + static const GLfloat border[4] = { 0.f, 0.f, 0.f, 0.f }; + glsafe(::glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border)); + } +#endif // !SLIC3R_OPENGL_ES + shader->set_uniform("height_tex", 0); + shader->set_uniform("height_tex_texel", Vec2f(1.f / float(tex->get_width()), 1.f / float(tex->get_height()))); + shader->set_uniform("depth_mm", layer->depth_mm); + shader->set_uniform("tiling_scale", layer->tiling_scale); + // Read off the uploaded texture rather than the decoded one: they are the same image, and this is + // the aspect the sampler will actually see. + shader->set_uniform("tex_aspect", float(tex->get_width()) / float(tex->get_height())); + shader->set_uniform("rotation_rad", layer->rotation_deg * float(M_PI) / 180.f); + shader->set_uniform("uv_offset", layer->offset); + shader->set_uniform("invert", layer->invert); + // The parallax step in the triplanar path needs the real height, not just its gradient, so it + // needs the midlevel the bake subtracts - and the camera position in the volume's own local space, + // to build the view ray it walks along. Without the parallax the pattern is welded to the base + // surface: it does not slide as the camera orbits and does not deepen with depth_mm, which is + // exactly when the fast preview stops looking like geometry. + shader->set_uniform("midlevel", layer->midlevel); + // The texture frame is world space anchored at the volume's origin (texture_displacement_bake_frame()): + // the shader subtracts the anchor from the world position, and the eye is handed over the same way. + const Vec3d tex_anchor = trafo_matrix.translation(); + shader->set_uniform("tex_anchor", Vec3f(tex_anchor.cast())); + shader->set_uniform("eye_model_pos", Vec3f((camera.get_position() - tex_anchor).cast())); + // When set, the shader samples at the per-vertex uv baked into the mesh (LSCM) rather than + // projecting; see rebuild_shaded_preview_mesh(). + shader->set_uniform("use_vertex_uv", m_shaded_preview_uses_vertex_uv); + // Cylindrical/Spherical wrap around the painted patch's own centre, which no fragment can derive: + // captured with the mesh (see rebuild_shaded_preview_mesh()) and handed over here. 0 is the planar + // projection every other in-shader path uses. + shader->set_uniform("projection_mode", m_shaded_projection_mode); + shader->set_uniform("patch_center", m_shaded_patch_center); + shader->set_uniform("patch_axis", m_shaded_patch_axis); + + // The filament palette the mesh's per-triangle indices refer to. Count 0 means "no layer is + // colouring", and the shader keeps the model's own colour for every fragment. + // The printable palette, in RGB for display and in Lab for the match. Uploaded rather than + // matched on the CPU because the quantization is per fragment here. + const GLTexture *color_tex = get_layer_color_texture(*layer); + const int palette_count = + (color_tex != nullptr) ? int(std::min(m_shaded_preview_palette.size(), size_t(PALETTE_MAX_ENTRIES))) : 0; + shader->set_uniform("palette_count", palette_count); + shader->set_uniform("has_color_tex", color_tex != nullptr); + // A flat-colour image is matched against single filaments only, as the bake does. + shader->set_uniform("pure_only", color_tex != nullptr && analyze_texture_detail(*layer).flat_colors); + for (int i = 0; i < palette_count; ++i) { + const PaletteEntry &e = m_shaded_preview_palette[size_t(i)]; + const std::string idx = "[" + std::to_string(i) + "]"; + shader->set_uniform(("palette_rgb" + idx).c_str(), e.rgb); + shader->set_uniform(("palette_lab" + idx).c_str(), srgb_to_lab(e.rgb)); + // How the entry prints: its filament, or for a mix the two it interleaves and in what ratio. + shader->set_uniform(("palette_a" + idx).c_str(), e.a); + shader->set_uniform(("palette_b" + idx).c_str(), e.b); + shader->set_uniform(("palette_num" + idx).c_str(), e.num); + shader->set_uniform(("palette_den" + idx).c_str(), e.den); + } + // The filaments those indices refer to, and the interleave the shader resolves a mix with - the + // same inputs make_mix_resolver() gets, so the preview shows the pattern that prints rather than + // the mix's smooth average colour. m_palette_filaments is what m_shaded_preview_palette was built from. + const int filament_count = + (palette_count > 0) ? int(std::min(m_palette_filaments.size(), size_t(PALETTE_MAX_FILAMENTS))) : 0; + shader->set_uniform("filament_count", filament_count); + for (int i = 0; i < filament_count; ++i) { + const ColorRGBA &c = m_palette_filaments[size_t(i)]; + shader->set_uniform(("filament_rgb[" + std::to_string(i) + "]").c_str(), Vec3f(c.r(), c.g(), c.b())); + } + shader->set_uniform("mix_mode", int(mv->texture_displacement_options.color_mix_mode)); + shader->set_uniform("layer_height", color_band_mm(*mv)); // as color_settings_for() + shader->set_uniform("dither_cell", std::max(m_subdivide_color_mm, 0.05f) * 2.f); // as color_settings_for() + if (color_tex != nullptr) { + shader->set_uniform("color_tex", 1); + glsafe(::glActiveTexture(GL_TEXTURE1)); + glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint) color_tex->get_id())); + glsafe(::glActiveTexture(GL_TEXTURE0)); + } + // The live UV-editor island drag rides this 2x3 affine (identity except mid-drag); only the flagged + // island's vertices apply it, so a drag is a uniform update rather than a mesh rebuild. + const Eigen::Matrix &d = m_shaded_island_delta; + shader->set_uniform("island_delta_lin", std::array{ d(0, 0), d(0, 1), d(1, 0), d(1, 1) }); + shader->set_uniform("island_delta_tr", Vec2f(d(0, 2), d(1, 2))); + m_shaded_preview_glmodel.render(); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); + shader->stop_using(); +} + +bool GLGizmoTextureDisplacement::shaded_preview_ready() const +{ + // Mirrors render_shaded_preview_mesh()'s own preconditions. Kept as a separate query because the + // caller has to know whether the shaded pass will draw *before* it hides the real volume for it. + if (m_c->selection_info() == nullptr || m_c->selection_info()->model_object() == nullptr) + return false; + if (texture_volume() == nullptr) + return false; + const TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr || layer->empty()) + return false; + // The same texture render_shaded_preview_mesh() will bind, not the panel thumbnail - the two are + // separate caches and either can fail on its own. + const GLTexture *tex = const_cast(this)->get_layer_height_texture(*layer); + if (tex == nullptr || tex->get_width() <= 0 || tex->get_height() <= 0) + return false; + return wxGetApp().get_shader("texture_displacement_shaded") != nullptr; +} + +// Appends a painted patch to an overlay, lifted onto the displaced surface where that has the base mesh's +// topology (see rebuild_paint_overlay()). +static void append_paint_patch(GLModel::Geometry &out, const indexed_triangle_set &patch, const std::vector *displaced) +{ + unsigned n = unsigned(out.vertices_count()); + for (const stl_triangle_vertex_indices &tri : patch.indices) { + for (int i = 0; i < 3; ++i) { + const size_t idx = size_t(tri[i]); + out.add_vertex((displaced != nullptr && idx < displaced->size()) ? (*displaced)[idx] : patch.vertices[idx]); + } + out.add_triangle(n, n + 1, n + 2); + n += 3; + } +} + +void GLGizmoTextureDisplacement::rebuild_other_paint_overlay() +{ + const ModelVolume *mv = texture_volume(); + // What it depends on: the volume, which layer is active, every other layer's paint (by its timestamp) and the + // displaced positions it is lifted onto. Compared every frame, rebuilt only when it differs. + std::string key; + if (mv != nullptr) { + key = std::to_string(mv->id().id) + ":" + std::to_string(m_active_layer_slot) + (m_use_shaded_preview ? ":b:" : ":t:") + + std::to_string(reinterpret_cast(m_preview_its.vertices.data())) + ":" + + std::to_string(m_preview_its.vertices.size()); + for (const TextureDisplacementLayer &l : mv->texture_displacement_layers) + if (l.slot != m_active_layer_slot && l.slot >= 0 && l.slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS)) + key += "|" + std::to_string(l.slot) + "@" + std::to_string(mv->texture_displacement_facet(l.slot).timestamp()); + } + if (key == m_other_paint_key) + return; + m_other_paint_key = std::move(key); + m_other_paint_glmodel.reset(); + if (mv == nullptr) + return; + + const std::vector *displaced = nullptr; + if (!m_use_shaded_preview && m_preview_its.vertices.size() == mv->mesh().its.vertices.size() && + !m_preview_its.vertices.empty()) + displaced = &m_preview_its.vertices; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + for (const TextureDisplacementLayer &l : mv->texture_displacement_layers) { + if (l.slot == m_active_layer_slot || l.slot < 0 || l.slot >= int(TEXTURE_DISPLACEMENT_MAX_LAYERS) || + mv->texture_displacement_facet(l.slot).empty()) + continue; + TriangleSelector selector(mv->mesh()); + selector.deserialize(mv->texture_displacement_facet(l.slot).get_data(), false); + append_paint_patch(init_data, selector.get_facets_strict(EnforcerBlockerType::ENFORCER), displaced); + } + if (init_data.is_empty()) + return; + m_other_paint_glmodel.init_from(std::move(init_data)); + // Neutral grey: painted, but not the layer the brush is working on. + m_other_paint_glmodel.set_color(ColorRGBA(0.55f, 0.58f, 0.60f, 0.35f)); +} + +void GLGizmoTextureDisplacement::rebuild_paint_overlay() +{ + m_paint_overlay_glmodel.reset(); + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_triangle_selectors.empty()) + return; + + // The *live* selector, so an in-progress stroke shows immediately - which is the whole point: + // this is the only feedback that a brush actually added or erased anything until the (much more + // expensive) preview catches up at stroke end. + const indexed_triangle_set patch = m_triangle_selectors[0]->get_facets_strict(EnforcerBlockerType::ENFORCER); + if (patch.indices.empty()) + return; + + // In the true-displacement view the surface on screen is the *raised* one, and a tint built on + // the flat base mesh would sink underneath it wherever the relief is deepest - which is precisely + // where the user is looking. The bake is topology-preserving (patch vertex i is mesh vertex i, see + // build_texture_displacement()), so the displaced positions can be read straight across. Vertices + // the brush split live past the end of that array and keep their flat position; they sit on the + // patch boundary, where the displacement is smallest anyway. + const std::vector *displaced = nullptr; + if (!m_use_shaded_preview && m_preview_its.vertices.size() == mv->mesh().its.vertices.size() && + !m_preview_its.vertices.empty()) + displaced = &m_preview_its.vertices; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + init_data.reserve_vertices(patch.indices.size() * 3); + init_data.reserve_indices(patch.indices.size() * 3); + append_paint_patch(init_data, patch, displaced); + m_paint_overlay_glmodel.init_from(std::move(init_data)); + // GLModel::render() re-sets "uniform_color" from this field just before drawing, so the colour + // has to be set here rather than as a uniform at draw time. + m_paint_overlay_glmodel.set_color(ColorRGBA(0.16f, 0.79f, 0.35f, 0.38f)); +} + +void GLGizmoTextureDisplacement::render_paint_overlay(GLModel &overlay) +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr || !overlay.is_initialized()) + return; + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + // Translucent, and pulled toward the camera so it wins the depth test against the coincident + // shaded surface. Depth writes are off: this is a tint, and letting it own the depth buffer would + // make the wireframe and seam overlays drawn after it fight with geometry that is not really + // there. Blending is already enabled by render_painter_gizmo(). + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glPolygonOffset(-1.5f, -1.5f)); + glsafe(::glDepthMask(GL_FALSE)); + overlay.render(); + glsafe(::glDepthMask(GL_TRUE)); + glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); + shader->stop_using(); +} + +void GLGizmoTextureDisplacement::rebuild_island_overlay(const std::vector &selection) +{ + m_island_overlay_glmodel.reset(); + m_island_overlay_selection = selection; + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || selection.empty() || m_uv_editor_unwrap.empty()) + return; + // The unwrap was made from the painted patch in the bake frame; the same extraction on the + // volume's own mesh gives the same triangles and vertex order in local coordinates, which is the + // frame the overlay is drawn in (with the volume's transform, like the paint tint). + const indexed_triangle_set patch = extract_painted_patch(mv->mesh().its, m_uv_editor_state.facets); + const PatchUnwrap &uw = m_uv_editor_unwrap; + std::vector chosen(size_t(std::max(uw.chart_count, 0)), 0); + for (const int c : selection) + if (c >= 0 && size_t(c) < chosen.size()) + chosen[size_t(c)] = 1; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + unsigned n = 0; + for (const stl_triangle_vertex_indices &tri : uw.indices) { + const int v0 = tri[0]; + if (v0 < 0 || size_t(v0) >= uw.vertex_chart.size()) + continue; + const int c = uw.vertex_chart[size_t(v0)]; + if (c < 0 || size_t(c) >= chosen.size() || !chosen[size_t(c)]) + continue; + bool ok = true; + for (int k = 0; k < 3 && ok; ++k) { + const int u = tri[k]; + ok = u >= 0 && size_t(u) < uw.source_vertex.size() && uw.source_vertex[size_t(u)] >= 0 && + size_t(uw.source_vertex[size_t(u)]) < patch.vertices.size(); + } + if (!ok) + continue; + for (int k = 0; k < 3; ++k) + init_data.add_vertex(patch.vertices[size_t(uw.source_vertex[size_t(tri[k])])]); + init_data.add_triangle(n, n + 1, n + 2); + n += 3; + } + if (n == 0) + return; + m_island_overlay_glmodel.init_from(std::move(init_data)); + m_island_overlay_glmodel.set_color(ColorRGBA(0.10f, 0.55f, 0.95f, 0.45f)); // the pane's selection blue +} + +void GLGizmoTextureDisplacement::render_island_overlay() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr || !m_island_overlay_glmodel.is_initialized()) + return; + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + // Above the paint tint (a larger offset), translucent, no depth writes - a marker, not geometry. + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glPolygonOffset(-2.0f, -2.0f)); + glsafe(::glDepthMask(GL_FALSE)); + m_island_overlay_glmodel.render(); + glsafe(::glDepthMask(GL_TRUE)); + glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); + shader->stop_using(); +} + +void GLGizmoTextureDisplacement::rebuild_uvcheck_mesh() +{ + m_uvcheck_glmodel.reset(); + if (m_uv_check_mode == UVCheckMode::None) + return; + + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_triangle_selectors.empty()) + return; + const indexed_triangle_set patch = m_triangle_selectors[0]->get_facets_strict(EnforcerBlockerType::ENFORCER); + if (patch.indices.empty()) + return; + // Everything below works in the *patch's* vertex space, not the mesh's. Those agree only until a + // brush stroke splits a triangle, after which the patch array is longer - and since patch triangle + // indices are used to index it, reading the mesh's array instead would run off the end. An earlier + // version guarded that by bailing out, which quietly disabled the Checker and Distortion overlays + // for anything painted with the brush. + const TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr) + return; + + // The checker samples wherever the projection puts it; the projections the shader can't + // reconstruct (LSCM, ViewProjected) get a precomputed per-vertex uv, the rest project in-shader. + std::vector uv = compute_layer_vertex_uvs(patch, *layer); + const bool have_uvs = uv.size() == patch.vertices.size(); + m_uvcheck_uses_vertex_uv = have_uvs; + m_uvcheck_projection_mode = have_uvs ? 0 : + layer_projection_frame(patch, *layer, m_uvcheck_patch_center, m_uvcheck_patch_axis); + // Per corner as well: under LSCM a seam vertex has a + // different uv in each island it borders, so the shared-vertex form drew one triangle per face from + // a neighbouring island's placement. Only the *drawing* needs this; the distortion metric below is + // a per-vertex average by construction and keeps using `uv`. + const std::vector corner_uv = compute_layer_corner_uvs(patch, *layer); + const bool have_corner_uvs = have_uvs && corner_uv.size() == patch.indices.size() * 3; + + // Per-vertex area distortion in [0,1] (0.5 == ideal), only when both requested and possible. + std::vector distortion(patch.vertices.size(), 0.5f); + if (m_uv_check_mode == UVCheckMode::Distortion && have_uvs) { + std::vector tri_log(patch.indices.size(), 0.f); + for (size_t f = 0; f < patch.indices.size(); ++f) { + const stl_triangle_vertex_indices &t = patch.indices[f]; + const float a3 = 0.5f * (patch.vertices[t[1]] - patch.vertices[t[0]]).cross(patch.vertices[t[2]] - patch.vertices[t[0]]).norm(); + const Vec2f e0 = uv[t[1]] - uv[t[0]]; + const Vec2f e1 = uv[t[2]] - uv[t[0]]; + const float a2 = 0.5f * std::abs(e0.x() * e1.y() - e0.y() * e1.x()); + tri_log[f] = (a3 > 1e-12f && a2 > 1e-12f) ? std::log2(a2 / a3) : 0.f; + } + // Centre the heatmap on the patch's own median stretch, so a globally-scaled unwrap reads as + // uniformly "ideal" and only *relative* stretching (the thing that matters) shows up as colour. + std::vector sorted = tri_log; + float median = 0.f; + if (!sorted.empty()) { + std::nth_element(sorted.begin(), sorted.begin() + sorted.size() / 2, sorted.end()); + median = sorted[sorted.size() / 2]; + } + std::vector sum(patch.vertices.size(), 0.f); + std::vector cnt(patch.vertices.size(), 0); + for (size_t f = 0; f < patch.indices.size(); ++f) { + // +/- 2 stops (4x stretch either way) spans the full blue->red range. + const float d = std::clamp(0.5f + (tri_log[f] - median) / 4.f, 0.f, 1.f); + for (int k = 0; k < 3; ++k) { + sum[patch.indices[f][k]] += d; + ++cnt[patch.indices[f][k]]; + } + } + for (size_t v = 0; v < distortion.size(); ++v) + if (cnt[v] > 0) + distortion[v] = sum[v] / float(cnt[v]); + } + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3T2 }; + // Flat (one vertex per triangle corner), so each triangle can carry its own island's uv - see + // have_corner_uvs above. Costs nothing in shading quality: the overlay shades from uv and the + // interpolated distortion value alone, never from a per-vertex normal. + init_data.reserve_vertices(patch.indices.size() * 3); + init_data.reserve_indices(patch.indices.size() * 3); + unsigned vcount = 0; + for (size_t f = 0; f < patch.indices.size(); ++f) { + const stl_triangle_vertex_indices &tri = patch.indices[f]; + for (int k = 0; k < 3; ++k) { + const size_t vi = size_t(tri[k]); + init_data.add_vertex(patch.vertices[vi], Vec3f(distortion[vi], 0.f, 0.f), + have_corner_uvs ? corner_uv[f * 3 + size_t(k)] : + (have_uvs ? uv[vi] : Vec2f::Zero())); + } + init_data.add_triangle(vcount, vcount + 1, vcount + 2); + vcount += 3; + } + + m_uvcheck_glmodel.init_from(std::move(init_data)); +} + +void GLGizmoTextureDisplacement::render_uvcheck_mesh() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr || !m_uvcheck_glmodel.is_initialized()) + return; + const TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr) + return; + GLShaderProgram *shader = wxGetApp().get_shader("texture_displacement_uvcheck"); + if (shader == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("volume_world_matrix", trafo_matrix); + const ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); + shader->set_uniform("clipping_plane", clp_data.clp_dataf); + shader->set_uniform("z_range", clp_data.z_range); + // The shader works on world-space normals (it projects the texture in world millimetres, as the + // bake does), so the normal matrix is the view rotation alone - no model part. + const Matrix3d view_normal_matrix = camera.get_view_matrix().matrix().block(0, 0, 3, 3); + shader->set_uniform("view_normal_matrix", view_normal_matrix); + shader->set_uniform("volume_mirrored", trafo_matrix.matrix().determinant() < 0.0); + shader->set_uniform("tex_anchor", Vec3f(trafo_matrix.translation().cast())); // see the preview shader + shader->set_uniform("mode", m_uv_check_mode == UVCheckMode::Distortion ? 1 : 0); + shader->set_uniform("checker_freq", 4.f); // squares per texture tile + shader->set_uniform("tiling_scale", layer->tiling_scale); + shader->set_uniform("rotation_rad", layer->rotation_deg * float(M_PI) / 180.f); + shader->set_uniform("uv_offset", layer->offset); + shader->set_uniform("use_vertex_uv", m_uvcheck_uses_vertex_uv); + shader->set_uniform("projection_mode", m_uvcheck_projection_mode); + shader->set_uniform("patch_center", m_uvcheck_patch_center); + shader->set_uniform("patch_axis", m_uvcheck_patch_axis); + // Was never uploaded, so the checker disagreed with the bake for any non-square height map. + shader->set_uniform("tex_aspect", layer_texture_aspect(*layer)); + + // Coincident with the base surface, so pull it toward the camera to win the depth test. + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glPolygonOffset(-1.0f, -1.0f)); + m_uvcheck_glmodel.render(); + glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); + shader->stop_using(); +} + +void GLGizmoTextureDisplacement::build_wireframe_from_its(const indexed_triangle_set &its) +{ + m_wireframe_overlay_glmodel.reset(); + m_wireframe_overlay_vcount = its.vertices.size(); + if (its.indices.empty()) + return; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + init_data.reserve_vertices(its.vertices.size()); + init_data.reserve_indices(its.indices.size() * 6); + for (const Vec3f &v : its.vertices) + init_data.add_vertex(v); + // One segment per triangle edge; shared edges drawn twice, harmless for a wireframe and far + // cheaper than deduplicating a million of them. + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) + init_data.add_line(unsigned(tri[i]), unsigned(tri[(i + 1) % 3])); + + if (!init_data.is_empty()) + m_wireframe_overlay_glmodel.init_from(std::move(init_data)); +} + +void GLGizmoTextureDisplacement::rebuild_wireframe_overlay() +{ + if (!m_wireframe_overlay) { + m_wireframe_overlay_glmodel.reset(); + m_wireframe_overlay_vcount = 0; + return; + } + const ModelVolume *mv = texture_volume(); + if (mv == nullptr) + return; + const indexed_triangle_set &its = mv->mesh().its; + if (its.indices.empty()) + return; + + // Building from the base mesh (shaded/paint mode); its topology only changes on bake/subdivide, and + // this runs on every rebuild_preview(), so rebuild only when the vertex count actually changes. + if (m_wireframe_overlay_glmodel.is_initialized() && m_wireframe_overlay_vcount == its.vertices.size()) + return; + build_wireframe_from_its(its); +} + +void GLGizmoTextureDisplacement::refresh_wireframe() +{ + if (!m_wireframe_overlay) { + m_wireframe_overlay_glmodel.reset(); + m_wireframe_overlay_vcount = 0; + return; + } + // The wireframe has to sit on whatever mesh is actually on screen. In the true-displacement view + // that is the raised preview geometry (m_preview_its) - drawing the flat base mesh's edges there + // leaves them buried inside the relief, which is why the wireframe "didn't show in real mode". In + // Fast (shaded) mode or with nothing painted, the surface is the undisplaced base mesh. + if (!m_use_shaded_preview && !m_preview_its.indices.empty()) + build_wireframe_from_its(m_preview_its); + else + rebuild_wireframe_overlay(); +} + +void GLGizmoTextureDisplacement::render_wireframe_overlay() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr || !m_wireframe_overlay_glmodel.is_initialized()) + return; + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + // Pull the lines toward the camera so they sit on the surface rather than z-fighting into it. + glsafe(::glEnable(GL_POLYGON_OFFSET_LINE)); + glsafe(::glPolygonOffset(-1.0f, -1.0f)); + m_wireframe_overlay_glmodel.set_color(ColorRGBA(1.0f, 1.0f, 1.0f, 0.6f)); // white, so it reads on any material + m_wireframe_overlay_glmodel.render(); + glsafe(::glDisable(GL_POLYGON_OFFSET_LINE)); + shader->stop_using(); +} + +void GLGizmoTextureDisplacement::rebuild_preview() +{ + // Raised first: any in-flight job's result (captured generation from before this call) will + // now compare unequal to m_preview_generation and be discarded when it completes, even if it + // finishes after the job queued below - and, since the counter is shared with the worker, that + // job also notices mid-run and aborts rather than computing a result nobody will use. + m_preview_generation->fetch_add(1); + update_uv_editor(); + rebuild_shaded_preview_mesh(); + rebuild_paint_overlay(); + rebuild_uvcheck_mesh(); + rebuild_seam_overlay(); + // The adaptive subdivision preview is driven by the painted area, so it has to follow the paint + // while it is open - a plain stroke changes which triangles would be refined. The uniform preview + // depends only on the mesh, so it is left to its own controls. + if (m_subdivide_editing && m_subdivide_adaptive) + rebuild_subdivide_preview(); + + // The debug view owns m_preview_glmodel while it is up. A stage is a snapshot of a run that has + // already finished, so letting the live preview overwrite it would replace the thing being + // inspected with something else; leaving the view is explicit (its Close button). + if (m_debug_stage >= 0) + return; + + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || !mv->is_texture_displacement_painted()) { + m_preview_glmodel.reset(); + m_preview_its = indexed_triangle_set{}; // no displaced mesh; wireframe falls back to the base + m_preview_job_pending = false; + refresh_wireframe(); + return; + } + // In Fast/paint modes the wireframe follows the base mesh and can be built now; the true-displacement + // view's wireframe needs the displaced mesh, which only exists once the job below completes. + if (m_use_shaded_preview) { + refresh_wireframe(); + // Fast view: the shader *is* the preview, and m_preview_glmodel is never drawn. Running the + // full CPU displacement anyway - which is what happened on every stroke and slider release - + // was the single largest cost in the gizmo, and it bought nothing. The switch back to the + // true-displacement view queues it (see the View row in on_render_input_window()). + m_preview_job_pending = false; + return; + } + + queue_preview_job(); +} + +void GLGizmoTextureDisplacement::queue_preview_job() +{ + // A job in flight when the gizmo closes still runs its completion handler, which would otherwise + // happily queue the follow-up run it was holding - against a gizmo nobody is looking at any more. + if (m_state != On) + return; + const ModelVolume *mv = texture_volume(); + if (mv == nullptr || !mv->is_texture_displacement_painted()) + return; + + // One in flight at a time; everything requested meanwhile collapses into a single follow-up run + // issued from the completion handler. See m_preview_job_running. + if (m_preview_job_running) { + m_preview_job_pending = true; + return; + } + + const uint64_t generation = m_preview_generation->load(); + + TextureDisplacementPreviewInput input; + input.base_mesh = mv->mesh().its; + input.layers = mv->texture_displacement_layers; + input.options = mv->texture_displacement_options; + // The preview is looked at, not printed or sliced: skip the simplification and the repair that + // follows it, which are most of the one-run pipeline's time. The relief is the same. + if (input.options.pipeline_v2) + input.options.v2_max_triangles_k = 0; + input.volume_to_world = texture_displacement_volume_to_world(*mv); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + input.facets_data[size_t(i)] = mv->texture_displacement_facet(i).get_data(); + // Captured here rather than read in the handler: get_extruders_colors() is main-thread state and + // the preview has to be grouped against the same palette it was computed with, not whatever is + // loaded by the time it lands. + input.color = color_settings_for(*mv); + // The filament list the result's indices refer to, captured with the job rather than read back + // when it lands - loading a filament meanwhile must not recolour a preview computed against a + // different list. + const std::vector filaments = m_palette_filaments; + + m_preview_job_running = true; + auto &worker = wxGetApp().plater()->get_ui_job_worker(); + queue_job(worker, std::make_unique(std::move(input), generation, m_preview_generation, + [this, filaments](TextureDisplacementPreviewResult result, uint64_t result_generation) { + indexed_triangle_set its = std::move(result.mesh); + m_preview_job_running = false; + if (result_generation != m_preview_generation->load()) { + // Superseded while this was computing (it will have aborted early and come back + // empty). Whatever the newest state is, it still needs a run. + m_preview_job_pending = true; + } else if (its.indices.empty()) { + // Aborted or cancelled rather than finished - the handler runs on every outcome so + // the in-flight latch above always clears. Keep whatever preview is already on screen + // rather than blanking it; there is no new result to show, not a new empty one. + } else { + m_preview_glmodel.reset(); + m_preview_color_runs.clear(); + if (result.triangle_color.size() == its.indices.size() && !filaments.empty()) { + // Group by *filament*, not by palette entry: what the bake wrote is the resolved + // filament, interleaving already applied, so this shows the real banding rather + // than the flat average the eye will turn it into. + indexed_triangle_set sorted; + sorted.vertices = its.vertices; + sorted.indices.reserve(its.indices.size()); + for (int want = 0; want <= int(filaments.size()); ++want) { + const size_t first = sorted.indices.size(); + for (size_t i = 0; i < its.indices.size(); ++i) + if (int(result.triangle_color[i]) == want) + sorted.indices.push_back(its.indices[i]); + if (sorted.indices.size() == first) + continue; + m_preview_color_runs.push_back( + { { first * 3, sorted.indices.size() * 3 }, + want == 0 ? GLVolume::NEUTRAL_COLOR : filaments[size_t(want - 1)] }); + } + m_preview_glmodel.init_from(sorted); + } else { + m_preview_glmodel.init_from(its); + } + m_preview_glmodel.set_color(GLVolume::NEUTRAL_COLOR); + // Keep the displaced mesh so the wireframe overlay can be drawn on it (the + // true-displacement view), then refresh the wireframe from it. + m_preview_its = std::move(its); + refresh_wireframe(); + // The paint tint rides the displaced surface in this view, so it follows the new mesh. + m_paint_overlay_dirty = true; + } + if (m_preview_job_pending) { + m_preview_job_pending = false; + if (!m_use_shaded_preview) + queue_preview_job(); // no-ops if the gizmo has closed in the meantime + } + m_parent.set_as_dirty(); + })); +} + +void GLGizmoTextureDisplacement::update_uv_editor() +{ + Plater *plater = wxGetApp().plater(); + UVEditorCanvas *uv_canvas = plater->get_uv_editor_canvas(); + if (uv_canvas == nullptr) + return; + // Wired on every call rather than with the first unwrap: Unwrap itself is one of the pane's commands. + uv_canvas->set_command_callback([this](UVEditorCanvas::Command cmd, float value) { on_uv_command(int(cmd), value); }); + + const ModelVolume *mv = texture_volume(); + TextureDisplacementLayer *layer = active_layer(); + // The pane is opened only on the user's explicit request (m_show_uv_editor), and only for an LSCM + // layer - never automatically just because something is painted. Keep the cached state/unwrap so + // that switching the toggle back on re-shows instantly (and re-solves if the paint changed while + // it was hidden, via the state comparison below). + if (!m_show_uv_editor || mv == nullptr || layer == nullptr || + layer->projection_method != TextureProjectionMethod::LSCM) { + m_uv_editor_bg = UVBackground::None; // the next time it is shown, upload the background afresh + push_uv_pane_state(); + plater->show_uv_editor(false); + return; + } + + // A vertex/edge edit committing (or an undo reverting one) changes the per-vertex UV overrides + // without going through the Unwrap button. Detect that and force a re-solve, so the pane's geometry + // stays in step with what will bake - the one exception to "only re-solve on Unwrap". + { + size_t sig = 1469598103934665603ull; // FNV-1a seed + const auto mix = [&sig](uint64_t x) { sig = (sig ^ x) * 1099511628211ull; }; + mix(layer->lscm_uv_overrides.size()); + for (const auto &[v, uv] : layer->lscm_uv_overrides) { + mix(uint64_t(uint32_t(v))); + mix(uint64_t(uint32_t(int32_t(std::llround(uv.x() * 1024.f))))); + mix(uint64_t(uint32_t(int32_t(std::llround(uv.y() * 1024.f))))); + } + if (sig != m_uv_overrides_sig) { + m_uv_overrides_sig = sig; + m_uv_unwrap_pending = true; + } + } + + UVEditorState state; + state.slot = m_active_layer_slot; + state.image_data = layer->image_data.get(); + state.seam_angle = layer->lscm_seam_angle_deg; + state.padding = layer->island_padding_mm; + state.facets = mv->texture_displacement_facet(m_active_layer_slot).get_data(); + state.seam_edges = layer->lscm_seam_edges; + + // The re-solve happens only when the user pressed "Unwrap" (m_uv_unwrap_pending). Every other call + // into here - a paint stroke ending, a slider release, the check mode changing - must not pay for + // a fresh LSCM solve; it just re-applies the cheap affine transforms over whatever unwrap already + // exists. If the paint changed underneath but the user hasn't asked to re-unwrap, the pane keeps + // showing the last unwrap on purpose (that is the whole point of making it an explicit action). + bool unwrap_changed = false; + if (m_uv_unwrap_pending) { + m_uv_unwrap_pending = false; + // World millimetres, the space the bake unwraps in - otherwise the pane would lay the islands + // out at the volume's own scale and show the texture at a different size than it bakes at. + const indexed_triangle_set patch = patch_in_world(extract_painted_patch(mv->mesh().its, state.facets)); + if (patch.indices.empty()) { + // Nothing painted to unwrap: clear what the pane showed but keep it open - its status line says what to do. + m_uv_editor_state = UVEditorState{}; + m_uv_editor_unwrap = PatchUnwrap{}; + m_uv_editor_distortion_colors.clear(); + uv_canvas->set_islands({}); + push_uv_pane_state(); + plater->show_uv_editor(true); + return; + } + // Padding disabled (0): the user asked to pack islands with no gap between them. + m_uv_editor_unwrap = compute_patch_unwrap(patch, layer->lscm_seam_angle_deg, 0.f, layer->lscm_seam_edges); + m_island_overlay_glmodel.reset(); // the islands were renumbered: rebuilt from the pane's selection next frame + m_island_overlay_selection.clear(); + // Re-apply any stored UV edits onto the fresh unwrap, so the pane shows exactly what + // compute_lscm_uvs() will bake (which applies the same overrides). + apply_lscm_uv_overrides(m_uv_editor_unwrap, layer->lscm_uv_overrides); + m_uv_editor_state = std::move(state); + unwrap_changed = true; + // Precompute the distortion heatmap now, while the patch is in hand - relative stretch doesn't + // change when islands are only moved, so this need not be redone on a drag. It is fed to the + // canvas below only while the Distortion check mode is on. + compute_uv_editor_distortion_colors(patch); + } + + // The pane background either mirrors the height texture (default) or shows a UV checker (#7). It is uploaded + // before, and independently of, the unwrap - the texture belongs on screen before anything is unwrapped - and + // only when the choice, the layer's image or its smoothing changed, because the height image is large. + const UVBackground desired_bg = (m_uv_check_mode == UVCheckMode::Checker) ? UVBackground::Checker : UVBackground::Height; + const bool bg_smoothing_changed = (desired_bg == UVBackground::Height) && (m_uv_editor_bg_smoothing != layer->smoothing); + if (desired_bg != m_uv_editor_bg || layer->image_data.get() != m_uv_editor_bg_image || bg_smoothing_changed) { + m_uv_editor_bg_smoothing = layer->smoothing; + m_uv_editor_bg_image = layer->image_data.get(); + m_uv_editor_bg = desired_bg; + if (desired_bg == UVBackground::Checker) { + // An even squares-per-axis count so the pattern tiles seamlessly across the UV unit + // boundary (texcoord == position repeats it once per tile). Softened grays, not pure + // black/white, so it doesn't fight the island wires drawn over it. + constexpr int tex = 512, squares = 8, cell = tex / squares; + std::vector checker(size_t(tex) * size_t(tex)); + for (int y = 0; y < tex; ++y) + for (int x = 0; x < tex; ++x) + checker[size_t(y) * tex + x] = ((x / cell + y / cell) & 1) ? 205 : 70; + uv_canvas->set_background_texture(checker, tex, tex); + } else { + const DecodedHeightTexture height = decode_height_texture(*layer); + if (!height.empty()) { + uv_canvas->set_background_texture(height.pixels, height.width, height.height); + } else { + // Not recorded as uploaded, so the next update tries again rather than keeping a blank backdrop. + uv_canvas->set_background_texture({}, 0, 0); + m_uv_editor_bg = UVBackground::None; + } + } + } + // The backdrop's extent and repeat follow the tile settings, with or without an unwrap. + uv_canvas->set_uv_transform(layer->tiling_scale, layer->rotation_deg, layer->tile_enabled, + layer->tile_method == TextureTileMethod::MirroredRepeat); + + if (m_uv_editor_unwrap.empty()) { + // Nothing unwrapped yet: the pane opens anyway, because Unwrap itself lives in it. Its canvas shows the + // texture and its status line says to paint the area and press Unwrap. + push_uv_pane_state(); + plater->show_uv_editor(true); + return; + } + + // Grow (never shrink) the layer's island list to cover every chart. Shrinking would throw away a + // hand placement the moment a stroke temporarily merged two islands, and a stale extra entry is + // harmless - island_transform_matrix() only looks up the charts that actually exist. + if (layer->islands.size() < size_t(m_uv_editor_unwrap.chart_count)) + layer->islands.resize(size_t(m_uv_editor_unwrap.chart_count)); + + // Connected-net layout (on by default): a *fresh* unwrap is unfolded so adjacent charts sit + // edge-to-edge (cube -> a net), rather than as separately packed squares. Only when the user pressed + // Unwrap (m_uv_apply_connected_net) - a re-segmentation renumbers charts anyway, so any hand + // placement from before is already meaningless. A *refresh* re-solve (a committed vertex edit, or an + // undo) must NOT relayout, or it would throw away every island placement on every vertex edit. + if (unwrap_changed && m_uv_apply_connected_net && layer->auto_connect_islands) { + std::vector net = compute_connected_net(m_uv_editor_unwrap); + if (net.size() == size_t(m_uv_editor_unwrap.chart_count)) { + if (layer->islands.size() < net.size()) + layer->islands.resize(net.size()); + for (size_t i = 0; i < net.size(); ++i) + layer->islands[i] = net[i]; + } + } + if (unwrap_changed) + m_uv_apply_connected_net = false; // consumed; a refresh re-solve leaves placements alone + + // The geometry goes over in the unwrap's *raw* mm coordinates and is only re-uploaded when the + // unwrap itself changed. Everything a slider or a drag can touch - island placement, tiling, + // rotation, offset - is an affine map on top of that, so it goes over as one 2x3 matrix per + // island instead. That is the whole reason dragging an island is now free: a patch of a million + // triangles has a million UVs to re-transform and re-upload otherwise, and it was doing exactly + // that on every single mouse-move event. + if (unwrap_changed) { + UVEditorCanvas::Islands view; + view.uvs = m_uv_editor_unwrap.uvs; + view.indices = m_uv_editor_unwrap.indices; + view.vertex_island = m_uv_editor_unwrap.vertex_chart; + view.boundary_edges = m_uv_editor_unwrap.boundary_edges; + view.island_count = m_uv_editor_unwrap.chart_count; + + uv_canvas->set_island_edit_callback( + [this](int island, const Vec2f &offset_delta, float rotation_delta, float scale_factor, bool finished) { + on_island_edited(island, offset_delta, rotation_delta, scale_factor, finished); + }); + uv_canvas->set_vertex_edit_callback( + [this](const std::vector> &edits) { on_uv_vertex_edited(edits); }); + uv_canvas->set_islands(std::move(view)); + } + + uv_canvas->set_select_mode(static_cast(m_uv_select_mode)); + uv_canvas->set_island_transforms(uv_editor_island_transforms(*layer)); + // The distortion heatmap tints the island fills only while its check mode is on; otherwise the + // canvas falls back to its default light-green wash. + if (m_uv_check_mode == UVCheckMode::Distortion) + uv_canvas->set_island_fill_colors(m_uv_editor_distortion_colors); + else + uv_canvas->set_island_fill_colors({}); + + push_uv_pane_state(); + plater->show_uv_editor(true); +} + +void GLGizmoTextureDisplacement::compute_uv_editor_distortion_colors(const indexed_triangle_set &patch) +{ + m_uv_editor_distortion_colors.clear(); + const PatchUnwrap &u = m_uv_editor_unwrap; + if (u.empty() || u.chart_count <= 0) + return; + + // log2(uv area / 3D area) per unwrap triangle - the same measure the 3D distortion overlay uses. + std::vector tri_log(u.indices.size(), 0.f); + std::vector tri_chart(u.indices.size(), -1); + for (size_t f = 0; f < u.indices.size(); ++f) { + const stl_triangle_vertex_indices &t = u.indices[f]; + if (t[0] < 0 || size_t(t[0]) >= u.vertex_chart.size()) + continue; + tri_chart[f] = u.vertex_chart[size_t(t[0])]; + const auto p3 = [&](int uv_idx) -> Vec3f { + const int sv = (size_t(uv_idx) < u.source_vertex.size()) ? u.source_vertex[size_t(uv_idx)] : -1; + return (sv >= 0 && size_t(sv) < patch.vertices.size()) ? patch.vertices[size_t(sv)] : Vec3f::Zero(); + }; + const float a3 = 0.5f * (p3(t[1]) - p3(t[0])).cross(p3(t[2]) - p3(t[0])).norm(); + const Vec2f e0 = u.uvs[size_t(t[1])] - u.uvs[size_t(t[0])]; + const Vec2f e1 = u.uvs[size_t(t[2])] - u.uvs[size_t(t[0])]; + const float a2 = 0.5f * std::abs(e0.x() * e1.y() - e0.y() * e1.x()); + tri_log[f] = (a3 > 1e-12f && a2 > 1e-12f) ? std::log2(a2 / a3) : 0.f; + } + + // Centre on the median stretch, so a globally scaled unwrap reads as uniform and only *relative* + // stretching shows up - matching the 3D overlay's convention. + std::vector sorted = tri_log; + float median = 0.f; + if (!sorted.empty()) { + std::nth_element(sorted.begin(), sorted.begin() + sorted.size() / 2, sorted.end()); + median = sorted[sorted.size() / 2]; + } + + std::vector chart_sum(size_t(u.chart_count), 0.0); + std::vector chart_cnt(size_t(u.chart_count), 0); + for (size_t f = 0; f < tri_log.size(); ++f) { + const int c = tri_chart[f]; + if (c >= 0 && c < u.chart_count) { + chart_sum[size_t(c)] += tri_log[f]; + ++chart_cnt[size_t(c)]; + } + } + + // Blue (compressed) -> green (ideal) -> red (stretched), +/- 2 stops spanning the full range. + const auto heat = [](float t) -> ColorRGBA { + t = std::clamp(t, 0.f, 1.f); + const ColorRGBA blue{ 0.15f, 0.35f, 1.0f, 0.5f }, green{ 0.2f, 0.9f, 0.3f, 0.5f }, red{ 1.0f, 0.2f, 0.15f, 0.5f }; + if (t < 0.5f) { const float s = t * 2.f; return blue * (1.f - s) + green * s; } + const float s = (t - 0.5f) * 2.f; return green * (1.f - s) + red * s; + }; + + m_uv_editor_distortion_colors.resize(size_t(u.chart_count), heat(0.5f)); + for (int c = 0; c < u.chart_count; ++c) + if (chart_cnt[size_t(c)] > 0) { + const float avg = float(chart_sum[size_t(c)] / chart_cnt[size_t(c)]); + m_uv_editor_distortion_colors[size_t(c)] = heat(std::clamp(0.5f + (avg - median) / 4.f, 0.f, 1.f)); + } +} + +void GLGizmoTextureDisplacement::on_uv_command(int cmd, float value) +{ + m_uv_command_queue.emplace_back(cmd, value); + m_parent.set_as_dirty(); // the panel render that runs it +} + +void GLGizmoTextureDisplacement::process_uv_commands() +{ + std::vector> queue; + queue.swap(m_uv_command_queue); + for (const auto &[cmd, value] : queue) + run_uv_command(cmd, value); +} + +void GLGizmoTextureDisplacement::apply_view_mode(int mode) +{ + m_use_shaded_preview = (mode == 1); + m_uv_check_mode = (mode == 2) ? UVCheckMode::Checker : + (mode == 3) ? UVCheckMode::Distortion : UVCheckMode::None; + rebuild_uvcheck_mesh(); + if (m_use_shaded_preview) + rebuild_shaded_preview_mesh(); + else + // The Fast view skips the CPU displacement entirely (see rebuild_preview()), so leaving it means + // m_preview_glmodel may be stale or absent - ask for it now. + queue_preview_job(); + // ...and the paint tint between the base and the displaced surface, for the same reason. + m_paint_overlay_dirty = true; + refresh_wireframe(); // Normal<->Fast swaps the wireframe between displaced and base mesh + update_uv_editor(); // mirror the checker / distortion heatmap into the UV pane too + m_parent.set_as_dirty(); +} + +void GLGizmoTextureDisplacement::push_uv_pane_state() +{ + UVEditorCanvas *canvas = wxGetApp().plater()->get_uv_editor_canvas(); + if (canvas == nullptr) + return; + + UVEditorCanvas::PaneState st; + const ModelVolume *mv = texture_volume(); + const TextureDisplacementLayer *layer = active_layer(); + if (mv != nullptr && layer != nullptr && layer->projection_method == TextureProjectionMethod::LSCM) { + st.has_layer = true; + st.layer_name = from_u8(layer->name.empty() ? Slic3r::format(_u8L("Layer %1%"), layer->slot + 1) : layer->name); + st.tile_mm = layer->tiling_scale; + st.seam_angle_deg = layer->lscm_seam_angle_deg; + st.connect_islands = layer->auto_connect_islands; + st.has_seams = !layer->lscm_seam_edges.empty(); + st.has_uv_edits = !layer->lscm_uv_overrides.empty(); + + // Retried while empty: the image may not decode yet, and a blank thumbnail must not stick. + if (layer->image_data.get() != m_uv_thumb_source || m_uv_thumb_rgb.empty()) { + m_uv_thumb_source = nullptr; + m_uv_thumb_rgb.clear(); + const DecodedHeightTexture tex = decode_height_texture(*layer); + if (!tex.empty()) { + m_uv_thumb_source = layer->image_data.get(); + // Box-filtered, so a fine pattern such as bricks averages out instead of aliasing into noise. + const int n = UV_THUMB_PX; + const bool color = tex.has_color(); + m_uv_thumb_rgb.resize(size_t(n) * n * 3); + for (int y = 0; y < n; ++y) { + const int y0 = y * tex.height / n, y1 = std::max(y0 + 1, (y + 1) * tex.height / n); + for (int x = 0; x < n; ++x) { + const int x0 = x * tex.width / n, x1 = std::max(x0 + 1, (x + 1) * tex.width / n); + uint64_t sum[3]{}; + for (int sy = y0; sy < y1; ++sy) + for (int sx = x0; sx < x1; ++sx) { + const size_t src = size_t(sy) * size_t(tex.width) + size_t(sx); + for (int ch = 0; ch < 3; ++ch) + sum[ch] += color ? tex.rgb[src * 3 + ch] : tex.pixels[src]; + } + const uint64_t count = uint64_t(y1 - y0) * uint64_t(x1 - x0); + for (int ch = 0; ch < 3; ++ch) + m_uv_thumb_rgb[size_t(y * n + x) * 3 + ch] = (unsigned char) (sum[ch] / count); + } + } + } + } + if (!m_uv_thumb_rgb.empty()) { + st.thumbnail_px = UV_THUMB_PX; + st.thumbnail_rgb = m_uv_thumb_rgb; + } + + if (!m_uv_editor_unwrap.empty()) { + // Stale when the unwrap on screen was made from another layer, other paint, other seams or another + // seam angle than this layer has now - the same things update_uv_editor() re-solves for. + UVEditorState now; + now.slot = m_active_layer_slot; + now.image_data = layer->image_data.get(); + now.seam_angle = layer->lscm_seam_angle_deg; + now.padding = layer->island_padding_mm; + now.facets = mv->texture_displacement_facet(m_active_layer_slot).get_data(); + now.seam_edges = layer->lscm_seam_edges; + st.unwrapped = true; + st.unwrap_stale = !(now == m_uv_editor_state); + st.island_count = m_uv_editor_unwrap.chart_count; + st.face_count = m_uv_editor_unwrap.indices.size(); + } + } + st.mark_seams = m_seam_edit_mode; + st.seam_path = m_seam_path_mode; + st.background = m_uv_check_mode == UVCheckMode::Checker ? UVEditorCanvas::Background::Checker : + m_uv_check_mode == UVCheckMode::Distortion ? UVEditorCanvas::Background::Distortion : + UVEditorCanvas::Background::Height; + canvas->set_pane_state(std::move(st)); +} + +void GLGizmoTextureDisplacement::run_uv_command(int cmd, float value) +{ + using Command = UVEditorCanvas::Command; + if (cmd == int(Command::PaneClosed)) { + // Closed with the pane's own X: keep it closed until asked again, and upload the background afresh then. + m_show_uv_editor = false; + m_uv_editor_bg = UVBackground::None; + // The seam tool belongs to the pane: left on with the pane gone, every stroke on the model would + // be swallowed as a seam click and nothing would paint. + if (m_seam_edit_mode) { + m_seam_edit_mode = false; + m_seam_hover_edge = { -1, -1 }; + m_seam_hover_vertex = -1; + m_seam_hover_glmodel.reset(); + m_seam_path_anchor = -1; + m_seam_anchor_glmodel.reset(); + push_uv_pane_state(); + } + return; + } + if (cmd == int(Command::SetBackground)) { + // Height goes back to whichever of Normal / Fast was showing; Checker and Distortion are views of their own. + const int background = std::clamp(int(std::lround(value)), 0, 2); + apply_view_mode(background == 1 ? 2 : background == 2 ? 3 : (m_use_shaded_preview ? 1 : 0)); + return; + } + + TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr) + return; + + if (cmd == int(UVEditorCanvas::Command::AverageScale)) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Average island scale"), UndoRedo::SnapshotType::GizmoAction); + average_island_scales(layer->islands); + rebuild_preview(); + } else if (cmd == int(UVEditorCanvas::Command::CutSelectedIsland)) { + UVEditorCanvas *canvas = wxGetApp().plater()->get_uv_editor_canvas(); + const int chart = canvas != nullptr ? canvas->selected_island() : -1; + if (chart < 0) { + show_error(nullptr, _u8L("Select an island in the UV editor first.")); + return; + } + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Cut texture island"), UndoRedo::SnapshotType::GizmoAction); + cut_island(*layer, chart); + rebuild_preview(); + } else if (cmd == int(UVEditorCanvas::Command::JoinSelected)) { + UVEditorCanvas *canvas = wxGetApp().plater()->get_uv_editor_canvas(); + const int chart = canvas != nullptr ? canvas->selected_island() : -1; + if (chart < 0) { + show_error(nullptr, _u8L("Select an island in the UV editor first.")); + return; + } + // Join to whichever neighbouring island (one it shares an edge with) is currently placed + // nearest - i.e. the one it was dragged up against. + const Eigen::Matrix sel_m = island_transform_matrix(chart, m_uv_editor_unwrap, layer->islands); + const Vec2f sel_c = sel_m.block<2, 2>(0, 0) * m_uv_editor_unwrap.chart_centroid[size_t(chart)] + sel_m.col(2); + int best_parent = -1; + float best_d2 = std::numeric_limits::max(); + TextureIsland best_place, cand; + for (int p = 0; p < m_uv_editor_unwrap.chart_count; ++p) { + if (p == chart) + continue; + if (!join_chart_placement(m_uv_editor_unwrap, layer->islands, chart, p, cand)) + continue; // not a neighbour + const Eigen::Matrix pm = island_transform_matrix(p, m_uv_editor_unwrap, layer->islands); + const Vec2f pc = pm.block<2, 2>(0, 0) * m_uv_editor_unwrap.chart_centroid[size_t(p)] + pm.col(2); + const float d2 = (pc - sel_c).squaredNorm(); + if (d2 < best_d2) { best_d2 = d2; best_parent = p; best_place = cand; } + } + if (best_parent < 0) { + show_error(nullptr, _u8L("This island has no neighbour it shares an edge with.")); + return; + } + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Join texture island"), UndoRedo::SnapshotType::GizmoAction); + if (layer->islands.size() <= size_t(chart)) + layer->islands.resize(size_t(chart) + 1); + layer->islands[size_t(chart)] = best_place; + // Record the join so the two (and anything already grouped with either) move together from now + // on, not just visually snap once. + join_island_groups(layer->island_groups, chart, best_parent, m_uv_editor_unwrap.chart_count); + rebuild_preview(); + } else if (cmd == int(UVEditorCanvas::Command::UnjoinSelected)) { + UVEditorCanvas *canvas = wxGetApp().plater()->get_uv_editor_canvas(); + const int chart = canvas != nullptr ? canvas->selected_island() : -1; + if (chart < 0 || size_t(chart) >= layer->islands.size()) { + show_error(nullptr, _u8L("Select an island in the UV editor first.")); + return; + } + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Unjoin texture island"), UndoRedo::SnapshotType::GizmoAction); + layer->islands[size_t(chart)] = TextureIsland{}; // back to its own packed position + // Break its join link too, so it stops moving with the others (the rest stay grouped). + if (size_t(chart) < layer->island_groups.size()) + layer->island_groups[size_t(chart)] = chart; + rebuild_preview(); + } + else if (cmd == int(Command::PickTexture)) { + // The same texture library the layer card opens; the panel renders it this frame. + m_picker_slot = m_active_layer_slot; + m_picker_open_request = true; + } else if (cmd == int(Command::Unwrap)) { + // The solve runs only on this - painting, the seam angle and seam marking never trigger it. + m_uv_unwrap_pending = true; + m_uv_apply_connected_net = true; // a genuine re-unwrap may relayout the islands + m_show_uv_editor = true; + update_uv_editor(); + } else if (cmd == int(Command::SetSeamAngle)) { + const float angle = std::clamp(value, 5.f, 90.f); + if (angle != layer->lscm_seam_angle_deg) { + layer->lscm_seam_angle_deg = angle; + rebuild_preview(); // the bake unwraps with it; this also marks the pane's unwrap stale + } + } else if (cmd == int(Command::SetConnectIslands)) { + const bool connect = value != 0.f; + if (connect != layer->auto_connect_islands) { + layer->auto_connect_islands = connect; + // Apply (or, when turned off, just stop re-applying) right away rather than waiting for the next re-unwrap. + if (connect && !m_uv_editor_unwrap.empty()) { + std::vector net = compute_connected_net(m_uv_editor_unwrap); + if (net.size() == size_t(m_uv_editor_unwrap.chart_count)) { + if (layer->islands.size() < net.size()) + layer->islands.resize(net.size()); + for (size_t i = 0; i < net.size(); ++i) + layer->islands[i] = net[i]; + } + } + rebuild_preview(); + } + } else if (cmd == int(Command::SetSelectMode)) { + m_uv_select_mode = std::clamp(int(std::lround(value)), 0, 2); // the canvas has already switched + } else if (cmd == int(Command::SetMarkSeams)) { + m_seam_edit_mode = value != 0.f; + if (m_seam_edit_mode) + m_adjust_texture_mode = false; // the two click modes are mutually exclusive + else { + m_seam_hover_edge = { -1, -1 }; // drop the hover highlight when leaving the mode + m_seam_hover_vertex = -1; + m_seam_hover_glmodel.reset(); + m_seam_path_anchor = -1; + m_seam_anchor_glmodel.reset(); + } + push_uv_pane_state(); + } else if (cmd == int(Command::SetSeamPath)) { + m_seam_path_mode = value != 0.f; + m_seam_path_anchor = -1; + m_seam_hover_edge = { -1, -1 }; // hover target type changes with the mode + m_seam_hover_vertex = -1; + m_seam_hover_glmodel.reset(); + m_seam_anchor_glmodel.reset(); + push_uv_pane_state(); + } else if (cmd == int(Command::ClearSeams)) { + if (!layer->lscm_seam_edges.empty()) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Clear texture seams"), UndoRedo::SnapshotType::GizmoAction); + layer->lscm_seam_edges.clear(); + rebuild_preview(); + } + } else if (cmd == int(Command::ClearUVEdits)) { + if (!layer->lscm_uv_overrides.empty()) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Clear texture UV edits"), UndoRedo::SnapshotType::GizmoAction); + layer->lscm_uv_overrides.clear(); + m_uv_unwrap_pending = true; // re-solve so the pane drops the edited coords + update_uv_editor(); + rebuild_preview(); + } + } + // FrameAll/ToggleSnap are handled inside the canvas; ProjectFromView is not wired yet. + m_parent.set_as_dirty(); +} + +void GLGizmoTextureDisplacement::capture_view_projection(TextureDisplacementLayer &layer) +{ + const ModelVolume *mv = texture_volume(); + const ModelObject *mo = m_c->selection_info()->model_object(); + if (mv == nullptr || mo == nullptr) + return; + + const Camera &camera = wxGetApp().plater()->get_camera(); + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + + // The view matrix's rotation rows are the camera axes in world space; bring them into the + // volume's local frame (where the mesh vertices live) so the projector rides along with the part. + const Matrix3d view_rot = camera.get_view_matrix().matrix().block<3, 3>(0, 0); + const Matrix3d trafo_rot = trafo.matrix().block<3, 3>(0, 0); + const Matrix3d world_to_local = trafo_rot.inverse(); + const Vec3d local_right = world_to_local * Vec3d(view_rot.row(0).transpose()); + const Vec3d local_up = world_to_local * Vec3d(view_rot.row(1).transpose()); + + // Unit axes: the projected planar coordinate must stay in mm so tiling_scale keeps meaning mm. + layer.view_project_right = local_right.norm() > 1e-9 ? Vec3f(local_right.normalized().cast()) : Vec3f::UnitX(); + layer.view_project_up = local_up.norm() > 1e-9 ? Vec3f(local_up.normalized().cast()) : Vec3f::UnitY(); +} + +void GLGizmoTextureDisplacement::show_projector(bool show) +{ + if (!show) { + if (m_projector_frame != nullptr) + m_projector_frame->Hide(); + return; + } + + if (m_projector_frame == nullptr) { + // Parented to the main frame, not to Plater: Plater is a wxPanel, and wxFRAME_FLOAT_ON_PARENT + // wants a real top-level window to float above. + m_projector_frame = new TextureProjectorFrame(wxGetApp().mainframe); + m_projector_tex_source = nullptr; // fresh window, nothing uploaded into it yet + m_projector_tex_smoothing = -1.f; + m_projector_frame->set_opacity(m_projector_opacity); + + // Opened centred over the 3D canvas, at about half its size: the frame is meant to be + // dragged onto part of the model, so starting somewhere on top of it beats the OS's default + // cascade position, which is often off over the sidebar. + if (const wxGLCanvas *cnv = m_parent.get_wxglcanvas(); cnv != nullptr) { + const wxRect area = cnv->GetScreenRect(); + const wxSize size(std::max(160, area.width / 2), std::max(160, area.height / 2)); + m_projector_frame->SetSize(wxRect(area.GetTopLeft() + wxPoint((area.width - size.x) / 2, + (area.height - size.y) / 2), + size)); + } + } + + m_projector_frame->Show(); + m_projector_frame->Raise(); + update_projector(); +} + +void GLGizmoTextureDisplacement::update_projector() +{ + if (m_projector_frame == nullptr || !m_projector_frame->IsShown()) + return; + + const TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr || layer->projection_method != TextureProjectionMethod::ViewProjected) { + m_projector_frame->set_texture({}, 0, 0); + m_projector_tex_source = nullptr; + m_projector_tex_smoothing = -1.f; + return; + } + + // Only re-upload when the pixels actually changed - this is reached from the panel's per-edit + // flush, and rebuilding the bitmap from identical bytes every time would be pure waste. + if (m_projector_tex_source != layer->image_data.get() || m_projector_tex_smoothing != layer->smoothing) { + const DecodedHeightTexture height = decode_height_texture(*layer); + if (height.empty()) + m_projector_frame->set_texture({}, 0, 0); + else + m_projector_frame->set_texture(height.pixels, height.width, height.height); + m_projector_tex_source = layer->image_data.get(); + m_projector_tex_smoothing = layer->smoothing; + } +} + +int GLGizmoTextureDisplacement::apply_projection_frame() +{ + TextureDisplacementLayer *layer = active_layer(); + const ModelVolume *mv = texture_volume(); + const ModelObject *mo = m_c->selection_info()->model_object(); + wxGLCanvas *cnv = m_parent.get_wxglcanvas(); + if (layer == nullptr || mv == nullptr || mo == nullptr || cnv == nullptr || m_projector_frame == nullptr || + !m_projector_frame->IsShown()) + return -1; + + // The frame's gate, brought from screen coordinates into the GL viewport's pixel space. Two + // conversions, both necessary: ScreenToClient() because the viewport's origin is the canvas's + // top-left, not the desktop's, and the retina scale because the viewport is sized in physical + // pixels (see GLCanvas3D::get_canvas_size()) while wx hands out logical ones. + const wxRect gate = m_projector_frame->client_rect_on_screen(); + const wxPoint tl = cnv->ScreenToClient(gate.GetTopLeft()); + const double scale = double(m_parent.get_scale()); + const double rx = double(tl.x) * scale, ry = double(tl.y) * scale; + const double rw = double(gate.width) * scale, rh = double(gate.height) * scale; + if (rw < 1.0 || rh < 1.0) + return -1; + + const Camera &camera = wxGetApp().plater()->get_camera(); + const std::array &vp = camera.get_viewport(); + const Selection &sel = m_parent.get_selection(); + const Transform3d trafo = mo->instances[sel.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + + // Local space -> clip space, the same product the renderer uses, so the mapping agrees with what + // is actually on screen rather than with an idealisation of it. + const Eigen::Matrix4d K = camera.get_projection_matrix().matrix() * camera.get_view_matrix().matrix() * trafo.matrix(); + + // Window coordinates follow igl::project's convention (as CameraUtils::project does): + // win_x = vp.x + vp.w * (ndc.x + 1) / 2, and y measured downward as vp.h - win_y_gl. + // Turning those into uv = (win - rect_origin) / rect_size gives u and v as affine functions of + // ndc.x and ndc.y, and since ndc = clip.xyz / clip.w, multiplying through by clip.w leaves a + // plain linear combination of K's rows - i.e. one 3x4 matrix carrying the perspective divide. + const double A = double(vp[2]) / (2.0 * rw); + const double B = (double(vp[0]) + double(vp[2]) * 0.5 - rx) / rw; + const double C = -double(vp[3]) / (2.0 * rh); + const double D = (double(vp[3]) * 0.5 - double(vp[1]) - ry) / rh; + + const Eigen::Vector4d row_u = A * K.row(0).transpose() + B * K.row(3).transpose(); + const Eigen::Vector4d row_v = C * K.row(1).transpose() + D * K.row(3).transpose(); + const Eigen::Vector4d row_w = K.row(3).transpose(); + + std::array m{}; + for (int i = 0; i < 4; ++i) { + m[size_t(i)] = float(row_u[i]); + m[size_t(4 + i)] = float(row_v[i]); + m[size_t(8 + i)] = float(row_w[i]); + } + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Apply texture projection frame"), + UndoRedo::SnapshotType::GizmoAction); + + layer->projection_method = TextureProjectionMethod::ViewProjected; + layer->view_project_projective = true; + layer->view_project_matrix = m; + // Off, so the height sampler returns 0 outside [0,1) and the frame's border becomes a hard edge + // of the displacement rather than the first seam of an endless repeat. + layer->tile_enabled = false; + // The affine axes are kept up to date too, so turning the projective mapping off later leaves a + // sane flat projection from this same viewpoint instead of whatever was captured long ago. + capture_view_projection(*layer); + + const int painted = select_visible_faces(&m); + m_preview_params_dirty = true; + rebuild_preview(); + m_parent.set_as_dirty(); + return painted; +} + +void GLGizmoTextureDisplacement::cut_island(TextureDisplacementLayer &layer, int chart) +{ + const ModelVolume *mv = texture_volume(); + if (mv == nullptr) + return; + const std::vector &verts = mv->mesh().its.vertices; + const PatchUnwrap &u = m_uv_editor_unwrap; + + // Collect the chart's triangles back in mesh-vertex space, and its 3D bounding box. + std::vector> tris; + Vec3f lo(std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()); + Vec3f hi(std::numeric_limits::lowest(), std::numeric_limits::lowest(), std::numeric_limits::lowest()); + for (const stl_triangle_vertex_indices &t : u.indices) { + if (t[0] < 0 || size_t(t[0]) >= u.vertex_chart.size() || u.vertex_chart[size_t(t[0])] != chart) + continue; + std::array bt{}; + bool ok = true; + for (int k = 0; k < 3; ++k) { + const int uvv = t[k]; + if (uvv < 0 || size_t(uvv) >= u.source_vertex.size()) { ok = false; break; } + const int base = u.source_vertex[size_t(uvv)]; + if (base < 0 || size_t(base) >= verts.size()) { ok = false; break; } + bt[k] = base; + lo = lo.cwiseMin(verts[size_t(base)]); + hi = hi.cwiseMax(verts[size_t(base)]); + } + if (ok) + tris.push_back(bt); + } + if (tris.empty()) + return; + + // Cut perpendicular to the longest axis, through the centroid - a long thin island is split + // across its narrow middle, which is exactly the "islands might be very long" case. + const Vec3f ext = hi - lo; + const int axis = (ext.x() >= ext.y() && ext.x() >= ext.z()) ? 0 : (ext.y() >= ext.z() ? 1 : 2); + const float mid = 0.5f * (lo[axis] + hi[axis]); + + std::set> seams(layer.lscm_seam_edges.begin(), layer.lscm_seam_edges.end()); + for (const std::array &bt : tris) + for (int i = 0; i < 3; ++i) { + const int a = bt[i], b = bt[(i + 1) % 3]; + // Endpoints on opposite sides of the plane -> this edge crosses it -> make it a seam. + if ((verts[size_t(a)][axis] < mid) != (verts[size_t(b)][axis] < mid)) + seams.insert({ std::min(a, b), std::max(a, b) }); + } + layer.lscm_seam_edges.assign(seams.begin(), seams.end()); +} + +// unwrap mm -> texture uv, per island: the island's own hand placement, then the layer's +// tiling/rotation/offset. Both are affine, so they compose into one matrix the canvas can hand +// straight to a shader. +std::vector> +GLGizmoTextureDisplacement::uv_editor_island_transforms(const TextureDisplacementLayer &layer) +{ + const float uv_scale = (layer.tiling_scale > 1e-6f) ? (1.f / layer.tiling_scale) : 1.f; + const float rad = layer.rotation_deg * float(M_PI) / 180.f; + const float cs = std::cos(rad) * uv_scale; + const float sn = std::sin(rad) * uv_scale; + + Eigen::Matrix2f uv_linear; + uv_linear << cs, -sn, + sn, cs; + + m_uv_editor_bbox_min = Vec2f(std::numeric_limits::max(), std::numeric_limits::max()); + m_uv_editor_bbox_max = Vec2f(std::numeric_limits::lowest(), std::numeric_limits::lowest()); + + std::vector> transforms(size_t(std::max(m_uv_editor_unwrap.chart_count, 0))); + for (int c = 0; c < m_uv_editor_unwrap.chart_count; ++c) { + const Eigen::Matrix island = island_transform_matrix(c, m_uv_editor_unwrap, layer.islands); + Eigen::Matrix &m = transforms[size_t(c)]; + m.block<2, 2>(0, 0) = uv_linear * island.block<2, 2>(0, 0); + m.col(2) = uv_linear * island.col(2) + layer.offset; + } + + // Only for the panel's readout; the canvas computes its own bounds. + for (size_t i = 0; i < m_uv_editor_unwrap.uvs.size(); ++i) { + const int c = m_uv_editor_unwrap.vertex_chart[i]; + if (c < 0 || size_t(c) >= transforms.size()) + continue; + const Vec2f uv = transforms[size_t(c)].block<2, 2>(0, 0) * m_uv_editor_unwrap.uvs[i] + transforms[size_t(c)].col(2); + m_uv_editor_bbox_min = m_uv_editor_bbox_min.cwiseMin(uv); + m_uv_editor_bbox_max = m_uv_editor_bbox_max.cwiseMax(uv); + } + return transforms; +} + +void GLGizmoTextureDisplacement::on_island_edited(int island, const Vec2f &offset_delta, float rotation_delta, + float scale_factor, bool finished) +{ + TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr || island < 0) + return; + if (size_t(island) >= layer->islands.size()) + layer->islands.resize(size_t(island) + 1); + + // A pure translation (no rotation, no scale) is the only gesture that moves a whole group/selection + // together; rotate and scale stay on the primary island alone. This split is what makes flagging a + // group's worth of vertices on the GPU safe: the shared shader delta is a pure translation, so the + // same offset is correct for every flagged island. + const bool is_move = rotation_delta == 0.f && scale_factor == 1.f; + + if (!m_island_drag_active) { + // Taken before the first delta lands, so one undo reverts the whole drag rather than just + // its final mouse-move. + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Move texture island"), UndoRedo::SnapshotType::GizmoAction); + m_island_drag_active = true; + // Decide the moved set once, at drag start: the whole selection + join groups for a move, or + // just the primary for a rotate/scale. + m_island_move_set = is_move ? build_island_move_set(*layer, island) : std::vector{ island }; + // Set up the GPU drag: bake the mesh once (via the dirty flag), which is also what flags the + // moved islands' triangles. From then on the drag is a uniform update, no rebuild - see + // render_shaded_preview_mesh(). + m_shaded_active_chart = island; + m_shaded_island_delta = Eigen::Matrix::Identity(); + m_shaded_preview_dirty = true; + } + + // Apply the edit. A move goes to every island in the moved set (same offset -> they translate as + // one); a rotate/scale goes only to the primary, about its own centroid. + const std::vector single{ island }; + const std::vector &targets = (is_move && !m_island_move_set.empty()) ? m_island_move_set : single; + for (int c : targets) { + if (c < 0) + continue; + if (size_t(c) >= layer->islands.size()) + layer->islands.resize(size_t(c) + 1); + TextureIsland &target = layer->islands[size_t(c)]; + target.offset += offset_delta; + if (c == island) { + target.rotation_deg += rotation_delta; + // Guarded: a scale that reaches zero is unrecoverable (every subsequent factor multiplies it) + // and would collapse the island to a point - exactly the failure this feature hit once already. + target.scale = std::clamp(target.scale * scale_factor, 0.001f, 1000.f); + } + } + + if (finished) { + m_island_drag_active = false; + m_shaded_active_chart = -1; + m_shaded_active_face.clear(); + m_island_move_set.clear(); + m_shaded_island_delta = Eigen::Matrix::Identity(); + rebuild_preview(); // the real displaced geometry moved: recompute it once, at the end + } else { + const std::vector> xf = uv_editor_island_transforms(*layer); + if (UVEditorCanvas *uv_canvas = wxGetApp().plater()->get_uv_editor_canvas()) { + // Live feedback in the pane, and deliberately *just* the transforms: nothing about the + // unwrap changed, so none of the vertex buffers need touching. This is what makes a drag + // interactive on a patch with a million triangles. + uv_canvas->set_island_transforms(xf); + } + // Move the island on the model live through the shader's island_delta uniform - no mesh + // rebuild. delta = F_current * F_baked^-1 in final-uv space. + // The one rebuild that bakes the flags is + // scheduled at drag start above and consumed once per frame by render_painter_gizmo(). + if (m_use_shaded_preview && m_shaded_active_chart == island && size_t(island) < xf.size()) { + Eigen::Matrix3f cur = Eigen::Matrix3f::Identity(); + cur.topRows<2>() = xf[size_t(island)]; + Eigen::Matrix3f bak = Eigen::Matrix3f::Identity(); + bak.topRows<2>() = m_shaded_baked_active_xf; + m_shaded_island_delta = (cur * bak.inverse()).topRows<2>(); + m_parent.set_as_dirty(); + } + } +} + +void GLGizmoTextureDisplacement::on_uv_vertex_edited(const std::vector> &edits) +{ + TextureDisplacementLayer *layer = active_layer(); + if (layer == nullptr || edits.empty() || m_uv_editor_unwrap.empty()) + return; + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Edit texture UV"), UndoRedo::SnapshotType::GizmoAction); + + for (const auto &[unwrapped, raw_uv] : edits) { + if (unwrapped < 0 || size_t(unwrapped) >= m_uv_editor_unwrap.source_vertex.size()) + continue; + // Keep the gizmo's own unwrap copy in step, so the pane and the bake agree without a re-solve. + if (size_t(unwrapped) < m_uv_editor_unwrap.uvs.size()) + m_uv_editor_unwrap.uvs[size_t(unwrapped)] = raw_uv; + + // Keyed by this one unwrapped copy, not by its mesh vertex: a seam vertex has a copy in each island it + // borders, and only the one that was dragged may move. Small list, linear scan is fine. + const int key = lscm_uv_override_key(unwrapped); + auto it = std::find_if(layer->lscm_uv_overrides.begin(), layer->lscm_uv_overrides.end(), + [key](const std::pair &p) { return p.first == key; }); + if (it != layer->lscm_uv_overrides.end()) + it->second = raw_uv; + else + layer->lscm_uv_overrides.emplace_back(key, raw_uv); + } + + rebuild_preview(); // the baked displacement samples the moved uv now +} + +bool GLGizmoTextureDisplacement::update_adjust_anchor() +{ + const ModelVolume *mv = texture_volume(); + m_adjust_anchor_valid = mv != nullptr && + compute_layer_paint_anchor(mv->mesh().its, mv->texture_displacement_facet(m_active_layer_slot).get_data(), + m_adjust_anchor_pos, m_adjust_anchor_normal); + return m_adjust_anchor_valid; +} + +TextureDisplacementLayer *GLGizmoTextureDisplacement::active_layer() +{ + ModelVolume *mv = texture_volume(); + if (mv == nullptr) + return nullptr; + for (TextureDisplacementLayer &l : mv->texture_displacement_layers) + if (l.slot == m_active_layer_slot) + return &l; + return nullptr; +} + +const TextureDisplacementLayer *GLGizmoTextureDisplacement::active_layer() const +{ + return const_cast(this)->active_layer(); +} + +Vec3f GLGizmoTextureDisplacement::adjust_plane_point() const +{ + const ModelVolume *mv = texture_volume(); + const float bbox_size = (mv != nullptr) ? float(mv->mesh().bounding_box().size().norm()) : 1.f; + const float lift = bbox_size * 0.01f + 0.2f; // clear of the surface, to avoid z-fighting + return m_adjust_anchor_pos + m_adjust_anchor_normal * lift; +} + +Vec3f GLGizmoTextureDisplacement::adjust_handle_center(const TextureDisplacementLayer &layer) const +{ + // apply_uv_transform() maps a planar mm coordinate p to uv = R(p / tiling_scale) + offset, and + // on_mouse_adjust_texture() drives offset by offset = offset_start - R(delta / tiling_scale). + // Inverting that, the handle's displacement from the anchor is - R^-1(offset) * tiling_scale - + // which, substituted into the drag equation, moves the handle by exactly `delta`. So the handle + // follows the cursor precisely, and is back on the anchor exactly when offset is zero. + const float rad = layer.rotation_deg * float(M_PI) / 180.f; + const float cs = std::cos(rad), sn = std::sin(rad); + // Undo the non-square v scaling first - it is the last thing apply_uv_transform() does, so it is + // the first thing to come off on the way back. + const float aspect = layer_texture_aspect(layer); + const Vec2f o(layer.offset.x(), (aspect > 0.f) ? layer.offset.y() / aspect : layer.offset.y()); + const Vec2f unrotated(o.x() * cs + o.y() * sn, -o.x() * sn + o.y() * cs); + const Vec2f planar = -unrotated * layer.tiling_scale; + + Vec3f u_axis, v_axis; + adjust_tangent_basis(u_axis, v_axis); + return adjust_plane_point() + u_axis * planar.x() + v_axis * planar.y(); +} + +void GLGizmoTextureDisplacement::adjust_tangent_basis(Vec3f &u_axis, Vec3f &v_axis) const +{ + // Mirrors project_planar()'s own dominant-axis choice exactly, so the ring's "0 degrees" and + // the offset handle's plane always agree with what project_texture_displacement_uv() does. + const Vec3f n = m_adjust_anchor_normal.cwiseAbs(); + if (n.x() >= n.y() && n.x() >= n.z()) { + u_axis = Vec3f::UnitY(); + v_axis = Vec3f::UnitZ(); + } else if (n.y() >= n.x() && n.y() >= n.z()) { + u_axis = Vec3f::UnitX(); + v_axis = Vec3f::UnitZ(); + } else { + u_axis = Vec3f::UnitX(); + v_axis = Vec3f::UnitY(); + } +} + +void GLGizmoTextureDisplacement::render_adjust_texture_gizmo() +{ + if (!m_adjust_anchor_valid) + return; + + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + const TextureDisplacementLayer *layer = active_layer(); + if (mo == nullptr || mv == nullptr || layer == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + + // Handle sizes scale with the volume so they stay usable on both tiny and huge models. + const float bbox_size = float(mv->mesh().bounding_box().size().norm()); + const float panel_half = bbox_size * 0.04f + 1.f; + const float arrow_length = panel_half * 2.2f; + + // Tracks the layer's offset, so the handle actually travels with the texture as it is dragged. + const Vec3f handle_center_local = adjust_handle_center(*layer); + + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glEnable(GL_BLEND)); + shader->start_using(); + + const Camera &camera = wxGetApp().plater()->get_camera(); + + Vec3f u_axis, v_axis; + adjust_tangent_basis(u_axis, v_axis); + Transform3d plane_transform = Transform3d::Identity(); + plane_transform.linear().col(0) = u_axis.cast(); + plane_transform.linear().col(1) = v_axis.cast(); + plane_transform.linear().col(2) = m_adjust_anchor_normal.cast(); + plane_transform.translation() = handle_center_local.cast(); + + // Pan panel: a flat square lying in the patch's own tangent plane. Dragging anywhere on it + // moves the texture freely along both axes at once. + if (!m_adjust_panel_glmodel.is_initialized()) { + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + init_data.reserve_vertices(4); + init_data.reserve_indices(6); + init_data.add_vertex(Vec3f(-1.f, -1.f, 0.f)); + init_data.add_vertex(Vec3f(1.f, -1.f, 0.f)); + init_data.add_vertex(Vec3f(1.f, 1.f, 0.f)); + init_data.add_vertex(Vec3f(-1.f, 1.f, 0.f)); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(0, 2, 3); + m_adjust_panel_glmodel.init_from(std::move(init_data)); + } + Transform3d view_model_matrix = camera.get_view_matrix() * trafo_matrix * plane_transform * + Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d(panel_half, panel_half, panel_half)); + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + ColorRGBA panel_color = m_adjust_drag_handle == AdjustHandle::Pan ? ColorRGBA::YELLOW() : ColorRGBA::ORANGE(); + panel_color.a(0.45f); + m_adjust_panel_glmodel.set_color(panel_color); + m_adjust_panel_glmodel.render(); + + // Axis arrows: a shaft plus a small V-shaped arrowhead, both along local +X. Reused for both + // the U and V axes below by swapping which world direction local +X is transformed to. + if (!m_adjust_arrow_glmodel.is_initialized()) { + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + init_data.reserve_vertices(4); + init_data.reserve_indices(6); + init_data.add_vertex(Vec3f(0.f, 0.f, 0.f)); + init_data.add_vertex(Vec3f(1.f, 0.f, 0.f)); + init_data.add_vertex(Vec3f(0.82f, 0.08f, 0.f)); + init_data.add_vertex(Vec3f(0.82f, -0.08f, 0.f)); + init_data.add_line(0, 1); + init_data.add_line(1, 2); + init_data.add_line(1, 3); + m_adjust_arrow_glmodel.init_from(std::move(init_data)); + } +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(2.0f)); +#endif // !SLIC3R_OPENGL_ES + + auto render_arrow = [&](const Vec3f &axis, const Vec3f &other_axis, bool is_active) { + Transform3d arrow_transform = Transform3d::Identity(); + arrow_transform.linear().col(0) = axis.cast(); + arrow_transform.linear().col(1) = other_axis.cast(); + arrow_transform.linear().col(2) = m_adjust_anchor_normal.cast(); + arrow_transform.translation() = handle_center_local.cast(); + + const Transform3d vmm = camera.get_view_matrix() * trafo_matrix * arrow_transform * + Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d(arrow_length, arrow_length, arrow_length)); + shader->set_uniform("view_model_matrix", vmm); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + m_adjust_arrow_glmodel.set_color(is_active ? ColorRGBA::YELLOW() : ColorRGBA::ORANGE()); + m_adjust_arrow_glmodel.render(); + }; + render_arrow(u_axis, v_axis, m_adjust_drag_handle == AdjustHandle::AxisU); + render_arrow(v_axis, u_axis, m_adjust_drag_handle == AdjustHandle::AxisV); + + shader->stop_using(); + glsafe(::glDisable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); +} + +bool GLGizmoTextureDisplacement::on_mouse_adjust_texture(const wxMouseEvent &mouse_event) +{ + if (!m_adjust_anchor_valid) + return false; + + ModelVolume *mv = texture_volume(); + ModelObject *mo = m_c->selection_info()->model_object(); + TextureDisplacementLayer *layer = active_layer(); + if (mv == nullptr || mo == nullptr || layer == nullptr) + return false; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + const float bbox_size = float(mv->mesh().bounding_box().size().norm()); + const float panel_half = bbox_size * 0.04f + 1.f; + const float arrow_length = panel_half * 2.2f; + // Where the handle is drawn (moves with the layer's offset) vs. the plane the drag is measured + // against (fixed at the anchor). Keeping them apart is what stops the handle's own motion from + // feeding back into the delta that produced it. + const Vec3f handle_center_local = adjust_handle_center(*layer); + const Vec3f drag_plane_local = adjust_plane_point(); + const Vec3d handle_center_world = trafo_matrix * handle_center_local.cast(); + const Vec2d mouse_pos(mouse_event.GetX(), mouse_event.GetY()); + + Vec3f u_axis, v_axis; + adjust_tangent_basis(u_axis, v_axis); + + const Point handle_screen = CameraUtils::project(camera, handle_center_world); + const Vec2d handle_screen_d(double(handle_screen.x()), double(handle_screen.y())); + + // Point-to-segment distance in screen space, for the arrow shafts. + auto dist_to_segment_px = [](const Vec2d &p, const Vec2d &a, const Vec2d &b) { + const Vec2d ab = b - a; + const double len2 = ab.squaredNorm(); + const double t = (len2 > 1e-9) ? std::clamp((p - a).dot(ab) / len2, 0.0, 1.0) : 0.0; + return (p - (a + ab * t)).norm(); + }; + + if (mouse_event.LeftDown()) { + const Vec3d u_tip_world = trafo_matrix * (handle_center_local + u_axis * arrow_length).cast(); + const Vec3d v_tip_world = trafo_matrix * (handle_center_local + v_axis * arrow_length).cast(); + const Point u_tip_screen = CameraUtils::project(camera, u_tip_world); + const Point v_tip_screen = CameraUtils::project(camera, v_tip_world); + const Vec2d u_tip_screen_d(double(u_tip_screen.x()), double(u_tip_screen.y())); + const Vec2d v_tip_screen_d(double(v_tip_screen.x()), double(v_tip_screen.y())); + + // Panel screen-space "radius", approximated from one corner (a loose circle around the + // square is close enough for hit-testing purposes). + const Vec3d panel_corner_world = trafo_matrix * (handle_center_local + (u_axis + v_axis) * panel_half).cast(); + const Point panel_corner_screen = CameraUtils::project(camera, panel_corner_world); + const double panel_screen_radius = (Vec2d(double(panel_corner_screen.x()), double(panel_corner_screen.y())) - handle_screen_d).norm(); + + constexpr double pick_tolerance_px = 8.0; + const double dist_to_u = dist_to_segment_px(mouse_pos, handle_screen_d, u_tip_screen_d); + const double dist_to_v = dist_to_segment_px(mouse_pos, handle_screen_d, v_tip_screen_d); + const double dist_to_panel = (handle_screen_d - mouse_pos).norm(); + + // Arrows take priority over the panel (their tips extend past it), then the panel covers + // the broader central area. + if (dist_to_u <= pick_tolerance_px && dist_to_u <= dist_to_v) + m_adjust_drag_handle = AdjustHandle::AxisU; + else if (dist_to_v <= pick_tolerance_px) + m_adjust_drag_handle = AdjustHandle::AxisV; + else if (dist_to_panel <= panel_screen_radius) + m_adjust_drag_handle = AdjustHandle::Pan; + else { + m_adjust_drag_handle = AdjustHandle::None; + return false; + } + + m_adjust_drag_start_offset = layer->offset; + + Vec3d world_hit; + if (ray_plane_hit(camera, mouse_pos, trafo_matrix, drag_plane_local, m_adjust_anchor_normal, world_hit)) { + const Vec3f local_hit = (trafo_matrix.inverse() * world_hit).cast(); + m_adjust_drag_start_planar = project_planar(local_hit, m_adjust_anchor_normal); + } + return true; + } + + if (mouse_event.Dragging() && m_adjust_drag_handle != AdjustHandle::None) { + Vec3d world_hit; + if (!ray_plane_hit(camera, mouse_pos, trafo_matrix, drag_plane_local, m_adjust_anchor_normal, world_hit)) + return true; + const Vec3f local_hit = (trafo_matrix.inverse() * world_hit).cast(); + const Vec2f current_planar = project_planar(local_hit, m_adjust_anchor_normal); + + Vec2f delta_planar = current_planar - m_adjust_drag_start_planar; + // project_planar()'s (x, y) axes are exactly u_axis/v_axis (see adjust_tangent_basis()), + // so zeroing one component constrains the drag to only the other axis. + if (m_adjust_drag_handle == AdjustHandle::AxisU) + delta_planar.y() = 0.f; + else if (m_adjust_drag_handle == AdjustHandle::AxisV) + delta_planar.x() = 0.f; + + const float scale = (layer->tiling_scale > 1e-6f) ? (1.f / layer->tiling_scale) : 1.f; + const Vec2f delta_scaled = delta_planar * scale; + const float rad = layer->rotation_deg * float(M_PI) / 180.f; + const float cs = std::cos(rad), sn = std::sin(rad); + Vec2f delta_rotated(delta_scaled.x() * cs - delta_scaled.y() * sn, delta_scaled.x() * sn + delta_scaled.y() * cs); + // ...and the same v scaling apply_uv_transform() applies for a non-square texture, so the + // handle keeps tracking the cursor exactly instead of drifting on the v axis. + delta_rotated.y() *= layer_texture_aspect(*layer); + // Increasing `offset` shifts which texel is sampled at a fixed world position, which + // visually slides the pattern the *opposite* way - subtracting is this session's + // best-effort reasoning about the direction that feels like "dragging the texture", + // unverified against an actual render (see header comment). + layer->offset = m_adjust_drag_start_offset - delta_rotated; + + m_preview_params_dirty = true; + m_parent.set_as_dirty(); + return true; + } + + if (mouse_event.LeftUp() && m_adjust_drag_handle != AdjustHandle::None) { + m_adjust_drag_handle = AdjustHandle::None; + rebuild_preview(); + m_preview_params_dirty = false; + return true; + } + + return false; +} + +ModelVolume* GLGizmoTextureDisplacement::texture_volume() +{ + ModelObject *mo = m_c->selection_info()->model_object(); + if (!mo) + return nullptr; + for (ModelVolume *mv : mo->volumes) + if (mv->is_model_part()) + return mv; + return nullptr; +} + +const ModelVolume* GLGizmoTextureDisplacement::texture_volume() const +{ + return const_cast(this)->texture_volume(); +} + +void GLGizmoTextureDisplacement::update_model_object() +{ + bool updated = false; + ModelObject *mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume *mv : mo->volumes) { + if (!mv->is_model_part()) + continue; + ++idx; + FacetsAnnotation &facet = mv->texture_displacement_facet(m_active_layer_slot); + // See m_selectors_stale: the mask could not be loaded into this selector, so an empty selector + // here is "failed to load", not "nothing painted", and writing it back would erase the paint. + // A selector that does hold something is the user's own work and must be flushed as usual. + if (m_selectors_stale && !facet.empty() && m_triangle_selectors[idx]->serialize().triangles_to_split.empty()) + continue; + updated |= facet.set(*m_triangle_selectors[idx]); + } + + // The fast (shaded) preview reads the live selector, so it has to be rebuilt after any stroke that + // flushes here - not only when set() reports a change. Rebuilding it via rebuild_preview() below + // is gated on `updated`, which misses e.g. the first paint into a slot; marking it dirty makes the + // render loop (render_painter_gizmo) rebuild it next frame regardless. Without this, fast preview - + // now the default view - stayed blank until a full reload (select-whole-model / reopen). + m_shaded_preview_dirty = true; + + if (updated) { + const ModelObjectPtrs &mos = wxGetApp().model().objects; + wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin()); + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); + rebuild_preview(); + } +} + +void GLGizmoTextureDisplacement::update_from_model_object(bool first_update) +{ + wxBusyCursor wait; + + const ModelObject *mo = m_c->selection_info()->model_object(); + m_triangle_selectors.clear(); + + std::vector ebt_colors; + ebt_colors.push_back(GLVolume::NEUTRAL_COLOR); + ebt_colors.push_back(TriangleSelectorGUI::enforcers_color); + ebt_colors.push_back(TriangleSelectorGUI::blockers_color); + m_selectors_stale = false; + for (const ModelVolume *mv : mo->volumes) { + if (!mv->is_model_part()) + continue; + + const TriangleMesh *mesh = &mv->mesh(); + const TriangleSelector::TriangleSplittingData &data = + mv->texture_displacement_facet(m_active_layer_slot).get_data(); + // The same bound TriangleSelector::deserialize() checks before it gives up - silently, with a + // void return and no way to report it. A mask recorded before the mesh was replaced indexes + // triangles that no longer exist, and the selector then comes back empty even though the mask + // is not. That has to be caught here, because the next update_model_object() would otherwise + // write the empty selector back over the mask: the paint would vanish, and the bake would + // report "nothing is painted" about the very data the flush had just deleted. + const size_t facet_count = mesh->its.indices.size(); + for (const TriangleSelector::TriangleBitStreamMapping &m : data.triangles_to_split) + if (m.triangle_idx < 0 || size_t(m.triangle_idx) >= facet_count) { + m_selectors_stale = true; + break; + } + m_triangle_selectors.emplace_back(std::make_unique(*mesh, ebt_colors)); + m_triangle_selectors.back()->deserialize(data, false); + m_triangle_selectors.back()->request_update_render_data(); + } + + // Start a freshly opened, never-textured volume with one layer already in place, so the panel is + // ready to paint straight away rather than showing an empty layer list. Only on first open, and + // only when there are none - never during an undo/redo or layer-switch reload (which also come + // through here), where silently adding a layer would be wrong. + if (first_update) + if (ModelVolume *tv = texture_volume(); tv != nullptr && tv->texture_displacement_layers.empty()) { + add_texture_layer(); // takes its own snapshot and rebuilds the preview + return; + } + + rebuild_preview(); +} + +void GLGizmoTextureDisplacement::set_active_layer(int slot) +{ + if (slot == m_active_layer_slot) + return; + // Flush edits made while the previous layer was active before switching what the selectors + // reflect - otherwise they would be silently lost. + update_model_object(); + m_active_layer_slot = slot; + update_from_model_object(false); + // The on-canvas gizmo (if on) is anchored to whichever layer is active - keep it in sync + // instead of leaving it pointing at the previous layer's (now stale) paint patch. + if (m_adjust_texture_mode) + update_adjust_anchor(); + // Refresh every preview/overlay (shaded, UV editor, seams, ...) for the newly active layer. + rebuild_preview(); +} + +void GLGizmoTextureDisplacement::ensure_panel_icons() +{ + if (m_panel_icons_tried) + return; + m_panel_icons_tried = true; + + // Order is irrelevant; the map keys by file name. Loaded with color_wite_gray so each icon has both + // a monochrome ("normal", grey in the current theme) and an original-colour variant. + static const std::vector names = { + "texture_displacement_brush.svg", "texture_displacement_face.svg", "texture_displacement_connected_area.svg", + "texture_displacement_real_preview.svg", "texture_displacement_fast_preview.svg", + "texture_displacement_checker.svg", "texture_displacement_distortion.svg", + "texture_displacement_wireframe.svg", "texture_displacement_cross.svg", + "texture_displacement_uv_select_island.svg", "texture_displacement_uv_select_edge.svg", + "texture_displacement_uv_select_vertex.svg", + // Paint / Erase, brush cursor shape, mapping, tiling, placement and the dock toggle. + "texture_displacement_add.svg", "texture_displacement_add_negative.svg", "circle_paint.svg", + "menu_obj_sphere.svg", "menu_obj_cube.svg", "menu_obj_cylinder.svg", "texture_displacement_map_unwrap.svg", + "texture_displacement_map_view.svg", "texture_displacement_tile_repeat.svg", "menu_mirror_x.svg", + "texture_displacement_adjust.svg", "canvas_drag.svg", "texture_displacement_move_up.svg", + "texture_displacement_move_down.svg", "texture_displacement_drag.svg", + "texture_displacement_select_all.svg", "texture_displacement_erase_all.svg", + }; + std::vector paths; + paths.reserve(names.size()); + for (const std::string &n : names) + paths.push_back(resources_dir() + "/images/" + n); + + // Runs from the panel render, i.e. with a GL context current, so the upload is safe here. + // + // Rasterized at twice GLToolbar::Default_Icons_Size rather than at it: these are drawn at the + // toolbar's icon size, which is that constant scaled by DPI (toolbar_icon_scale() folds in + // em_unit), so on a 200% display the draw size reaches 80 px. Rasterizing at 40 would upscale a + // 40 px bitmap there, which is what actually reads as blurry - downscaling does not. The icon set + // is rasterized once for the gizmo's lifetime, so it cannot re-raster on a DPI change; sizing for + // the larger case and letting ImGui shrink it is the version that looks right on both. + const std::vector icons = + m_panel_icons.init(paths, ImVec2(2 * GLToolbar::Default_Icons_Size, 2 * GLToolbar::Default_Icons_Size), + IconManager::RasterType::color_wite_gray); + for (size_t i = 0; i < names.size() && i < icons.size(); ++i) + m_panel_icon_map[names[i]] = icons[i]; +} + +void GLGizmoTextureDisplacement::add_texture_layer() +{ + ModelVolume *mv = texture_volume(); + if (!mv) + return; + + std::array used{}; + for (const TextureDisplacementLayer &l : mv->texture_displacement_layers) + if (l.slot >= 0 && size_t(l.slot) < used.size()) + used[size_t(l.slot)] = true; + int free_slot = -1; + for (size_t i = 0; i < used.size(); ++i) + if (!used[i]) { free_slot = int(i); break; } + if (free_slot < 0) { + show_error(nullptr, _u8L("Maximum number of texture displacement layers reached.")); + return; + } + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Add texture displacement layer"), UndoRedo::SnapshotType::GizmoAction); + + TextureDisplacementLayer layer; + layer.slot = free_slot; + // Start the layer off on the first library texture rather than on nothing at all: a textureless + // layer looks broken (painting on it appears to do nothing, because there is no height map to + // displace by). The user swaps it for another from the layer's own picker. + const std::vector &library = texture_library(); + if (!library.empty()) + if (const LibraryTexture *tex = get_library_texture(library.front().path)) { + layer.name = library.front().name; + layer.path = library.front().path; + layer.image_data = tex->image_data; + } + mv->texture_displacement_layers.push_back(std::move(layer)); + // A new layer opens with every setting showing; there is nothing on it yet to hide settings from. + m_layer_expanded[size_t(free_slot)] = true; + + set_active_layer(free_slot); + // set_active_layer() is a no-op when the new slot happens to be the one already active (slot 0, + // for the very first layer added), so the preview would not pick the new texture up on its own. + rebuild_preview(); + m_parent.set_as_dirty(); +} + +const GLGizmoTextureDisplacement::LibraryTexture *GLGizmoTextureDisplacement::get_library_texture(const std::string &path) +{ + if (auto it = m_library_textures.find(path); it != m_library_textures.end()) + return it->second.image_data ? &it->second : nullptr; + + LibraryTexture entry; + std::string error; + entry.image_data = load_texture_image_data(path, error); + if (entry.image_data) { + TextureDisplacementLayer probe; + probe.image_data = entry.image_data; + entry.thumbnail = upload_height_thumbnail(decode_height_texture(probe)); + if (!entry.thumbnail) + entry.image_data.reset(); // decoded to nothing usable - treat it as a failed load + } else { + BOOST_LOG_TRIVIAL(error) << "Texture displacement: could not load texture " << path << ": " << error; + } + + // Cached whether it loaded or not: a file that failed is remembered as unusable, so the picker + // does not retry (and re-log) it on every frame it is on screen. + const auto [pos, inserted] = m_library_textures.emplace(path, std::move(entry)); + return pos->second.image_data ? &pos->second : nullptr; +} + +void GLGizmoTextureDisplacement::set_layer_texture(TextureDisplacementLayer &layer, const TextureLibraryEntry &entry) +{ + const LibraryTexture *tex = get_library_texture(entry.path); + if (tex == nullptr) { + show_error(nullptr, _u8L("Could not load the selected texture.")); + return; + } + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Change texture displacement texture"), UndoRedo::SnapshotType::GizmoAction); + layer.name = entry.name; + layer.path = entry.path; + // Handing over the library's own buffer (rather than a copy) is what lets decode_height_texture() + // - whose cache is keyed by exactly this pointer - hit straight away instead of re-decoding + // the PNG the first time the layer is previewed or baked. + layer.image_data = tex->image_data; + // The user's own textures are listed most recently used first. + if (entry.is_user) + touch_user_texture(entry.path); + + rebuild_preview(); + m_parent.set_as_dirty(); +} + +void GLGizmoTextureDisplacement::import_custom_texture(TextureDisplacementLayer &layer) +{ + const wxString wildcard = "Images (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp"; + wxFileDialog dialog(nullptr, _L("Choose a texture image (height map)"), wxEmptyString, wxEmptyString, wildcard, + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (dialog.ShowModal() != wxID_OK) + return; + + // Converts to the 8-bit grayscale PNG the bake code understands and copies it into the user's + // own texture folder, so it stays available for later models (and survives an app update, which + // rewrites the shipped folder wholesale). + std::string error; + const std::optional entry = import_texture_to_library(into_u8(dialog.GetPath()), error); + if (!entry) { + show_error(nullptr, error); + return; + } + set_layer_texture(layer, *entry); +} + +void GLGizmoTextureDisplacement::render_texture_library_popup(const ImVec2 &panel_min, const ImVec2 &panel_max) +{ + ModelVolume *mv = texture_volume(); + TextureDisplacementLayer *layer = nullptr; + if (mv != nullptr) + for (TextureDisplacementLayer &l : mv->texture_displacement_layers) + if (l.slot == m_picker_slot) + layer = &l; + + static const char *const popup_id = "##texture_library"; + if (m_picker_open_request) { + m_picker_open_request = false; + if (layer != nullptr) + ImGui::OpenPopup(popup_id); + } + + const float tile = std::round(m_imgui->scaled(3.2f)); + const float spacing = std::round(m_imgui->scaled(0.4f)); + const float grid_w = 4.f * tile + 3.f * spacing; + const float gap = m_imgui->scaled(0.5f); + // Beside the panel rather than over it, so the layer being retextured stays in view: to its left when + // there is room (the docked panel sits against the right edge of the canvas), otherwise to its right. + const float popup_w = grid_w + 2.f * ImGui::GetStyle().WindowPadding.x; + const bool left = panel_min.x - gap - popup_w >= 0.f; + ImGui::SetNextWindowPos(ImVec2(left ? panel_min.x - gap : panel_max.x + gap, panel_min.y + m_imgui->scaled(4.f)), + ImGuiCond_Appearing, ImVec2(left ? 1.f : 0.f, 0.f)); + if (!ImGui::BeginPopup(popup_id)) + return; + if (layer == nullptr) { + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + return; + } + + m_imgui->push_bold_font(); + m_imgui->text(_L("Choose a texture")); + m_imgui->pop_bold_font(); + + const std::vector &library = texture_library(); + ImDrawList *dl = ImGui::GetWindowDrawList(); + const ImU32 selected_col = ImGui::GetColorU32(ImGuiWrapper::COL_ORCA); + std::optional chosen; + std::optional to_remove; + bool import_clicked = false; + + // Tiles are placed on the four-column grid explicitly rather than flowed with SameLine(): a user tile + // overlays a remove button on its corner, and that button would otherwise be "the previous item" the + // next tile lines up against. + const auto tile_pos = [&](const ImVec2 &origin, int i) { + return ImVec2(origin.x + float(i % 4) * (tile + spacing), origin.y + float(i / 4) * (tile + spacing)); + }; + // Leaves the cursor below a grid of `count` tiles, with the grid's area registered as content. + const auto end_grid = [&](const ImVec2 &origin, int count) { + ImGui::SetCursorScreenPos(origin); + if (count > 0) { + const int rows = (count + 3) / 4; + ImGui::Dummy(ImVec2(grid_w, float(rows) * tile + float(rows - 1) * spacing)); + } + }; + // One group's tiles: shipped textures alphabetically, or the user's own most recently used first (the + // order texture_library() keeps), those with a remove button on hover. Returns how many it drew. + const auto grid = [&](const ImVec2 &origin, bool user) { + int n = 0; + for (const TextureLibraryEntry &entry : library) { + if (entry.is_user != user) + continue; + ImGui::SetCursorScreenPos(tile_pos(origin, n++)); + ImGui::PushID(entry.path.c_str()); + const LibraryTexture *tex = get_library_texture(entry.path); + GLTexture *thumb = tex != nullptr ? tex->thumbnail.get() : nullptr; + bool clicked = false; + if (thumb != nullptr) { + // Centre-crop a non-square image into the square tile instead of squashing it. + const float aspect = thumb->get_height() > 0 ? float(thumb->get_width()) / float(thumb->get_height()) : 1.f; + ImVec2 uv0(0.f, 0.f), uv1(1.f, 1.f); + if (aspect > 1.f) { + uv0.x = 0.5f * (1.f - 1.f / aspect); + uv1.x = 1.f - uv0.x; + } else if (aspect < 1.f) { + uv0.y = 0.5f * (1.f - aspect); + uv1.y = 1.f - uv0.y; + } + clicked = ImGui::ImageButton((ImTextureID) (intptr_t) thumb->get_id(), ImVec2(tile, tile), uv0, uv1, 0); + } else { + clicked = ImGui::Button("?", ImVec2(tile, tile)); + } + if (user) + ImGui::SetItemAllowOverlap(); // the remove button drawn over its corner takes its own clicks + const ImVec2 a = ImGui::GetItemRectMin(), b = ImGui::GetItemRectMax(); + if (entry.path == layer->path) + dl->AddRect(ImVec2(a.x - 1.f, a.y - 1.f), ImVec2(b.x + 1.f, b.y + 1.f), selected_col, 0.f, 0, 2.f); + if (ImGui::IsItemHovered()) + m_imgui->tooltip(entry.name, m_imgui->scaled(18.f)); + + if (user && ImGui::IsMouseHoveringRect(a, b)) { + const float r = std::round(tile * 0.17f); + const ImVec2 c(b.x - r - 2.f, a.y + r + 2.f); + ImGui::SetCursorScreenPos(ImVec2(c.x - r, c.y - r)); + const bool remove_clicked = ImGui::InvisibleButton("##remove", ImVec2(2.f * r, 2.f * r)); + const bool hot = ImGui::IsItemHovered(); + dl->AddCircleFilled(c, r, hot ? IM_COL32(214, 72, 64, 235) : IM_COL32(0, 0, 0, 170)); + const float k = 0.42f * r; + dl->AddLine(ImVec2(c.x - k, c.y - k), ImVec2(c.x + k, c.y + k), IM_COL32_WHITE, 1.5f); + dl->AddLine(ImVec2(c.x - k, c.y + k), ImVec2(c.x + k, c.y - k), IM_COL32_WHITE, 1.5f); + if (hot) + m_imgui->tooltip(_u8L("Remove from My textures"), m_imgui->scaled(18.f)); + if (remove_clicked) + to_remove = entry; + } + ImGui::PopID(); + if (clicked) + chosen = entry; + } + return n; + }; + + ImGui::TextDisabled("%s", _u8L("Built-in").c_str()); + { + const ImVec2 origin = ImGui::GetCursorScreenPos(); + const int count = grid(origin, false); + end_grid(origin, count); + if (count == 0) + ImGui::TextDisabled("%s", _u8L("No textures found.").c_str()); + } + ImGui::TextDisabled("%s", _u8L("My textures").c_str()); + { + const ImVec2 origin = ImGui::GetCursorScreenPos(); + const int count = grid(origin, true); + ImGui::SetCursorScreenPos(tile_pos(origin, count)); + if (ImGui::Button("+##import_texture", ImVec2(tile, tile))) + import_clicked = true; + if (ImGui::IsItemHovered()) + m_imgui->tooltip(_u8L("Import your own image as a height map. It is converted to the format the slicer " + "bakes from and saved to your personal texture folder, kept separate from the " + "textures shipped with OrcaSlicer."), + m_imgui->scaled(20.f)); + end_grid(origin, count + 1); + } + + ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + grid_w); + ImGui::TextDisabled("%s", _u8L("PNG, JPG or BMP - converted to a height map on import. Hover one of yours to remove it.").c_str()); + ImGui::PopTextWrapPos(); + + if (chosen || import_clicked) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + + // Only once the loop over the library is done: importing, picking (which reorders the recently used) + // and removing all change the library the loop was iterating. + if (chosen) + set_layer_texture(*layer, *chosen); + else if (import_clicked) + import_custom_texture(*layer); + else if (to_remove) { + MessageDialog dlg(nullptr, + wxString::Format(_L("Remove \"%s\" from My textures?\n\nThe image file is deleted from your " + "texture folder. Layers already using it keep it."), + from_u8(to_remove->name)), + _L("Remove texture"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); + if (dlg.ShowModal() == wxID_YES) { + std::string error; + if (remove_user_texture(to_remove->path, error)) + m_library_textures.erase(to_remove->path); // its cached thumbnail and bytes go with it + else + show_error(nullptr, error); + } + // The modal dialog took the focus, which closes the popup; the user was choosing a texture and + // still is, so bring it back. + m_picker_open_request = true; + } +} + +void GLGizmoTextureDisplacement::remove_texture_layer(int slot) +{ + ModelVolume *mv = texture_volume(); + if (!mv) + return; + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Remove texture displacement layer"), UndoRedo::SnapshotType::GizmoAction); + + auto &layers = mv->texture_displacement_layers; + layers.erase(std::remove_if(layers.begin(), layers.end(), + [slot](const TextureDisplacementLayer &l) { return l.slot == slot; }), + layers.end()); + if (slot >= 0 && slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS)) { + mv->texture_displacement_facet(slot).reset(); + m_thumbnails[size_t(slot)].reset(); + m_thumbnail_source[size_t(slot)] = nullptr; + m_layer_expanded[size_t(slot)] = false; + } + if (m_picker_slot == slot) + m_picker_slot = -1; + + if (m_active_layer_slot == slot) + update_from_model_object(false); // also rebuilds the preview + else + rebuild_preview(); // a non-active layer's contribution to the combined preview changed + + m_parent.set_as_dirty(); +} + +void GLGizmoTextureDisplacement::swap_layer_slots(int slot_a, int slot_b) +{ + ModelObject *mo = m_c->selection_info()->model_object(); + ModelVolume *mv = texture_volume(); + const int n = int(TEXTURE_DISPLACEMENT_MAX_LAYERS); + if (mo == nullptr || mv == nullptr || slot_a == slot_b || slot_a < 0 || slot_b < 0 || slot_a >= n || slot_b >= n) + return; + + // Every model part, not only the texture volume: the selectors paint the active slot on all of them. + for (ModelVolume *v : mo->volumes) { + if (!v->is_model_part()) + continue; + TriangleSelector::TriangleSplittingData data_a = v->texture_displacement_facet(slot_a).get_data(); + TriangleSelector::TriangleSplittingData data_b = v->texture_displacement_facet(slot_b).get_data(); + v->texture_displacement_facet(slot_a).set_data(std::move(data_b)); + v->texture_displacement_facet(slot_b).set_data(std::move(data_a)); + } + for (TextureDisplacementLayer &l : mv->texture_displacement_layers) { + if (l.slot == slot_a) + l.slot = slot_b; + else if (l.slot == slot_b) + l.slot = slot_a; + } + + const size_t a = size_t(slot_a), b = size_t(slot_b); + std::swap(m_thumbnails[a], m_thumbnails[b]); + std::swap(m_thumbnail_source[a], m_thumbnail_source[b]); + std::swap(m_thumbnail_smoothing[a], m_thumbnail_smoothing[b]); + std::swap(m_layer_expanded[a], m_layer_expanded[b]); + if (m_active_layer_slot == slot_a) + m_active_layer_slot = slot_b; + else if (m_active_layer_slot == slot_b) + m_active_layer_slot = slot_a; + if (m_picker_slot == slot_a) + m_picker_slot = slot_b; + else if (m_picker_slot == slot_b) + m_picker_slot = slot_a; +} + +void GLGizmoTextureDisplacement::move_texture_layer(int slot, int to_index) +{ + ModelVolume *mv = texture_volume(); + if (mv == nullptr) + return; + + std::vector slots; + for (const TextureDisplacementLayer &l : mv->texture_displacement_layers) + slots.push_back(l.slot); + std::sort(slots.begin(), slots.end()); + const auto it = std::find(slots.begin(), slots.end(), slot); + if (it == slots.end()) + return; + const int from = int(it - slots.begin()); + // An insertion index counts the moved layer's own position, which is gone once it is lifted out. + const int to = std::clamp(to_index > from ? to_index - 1 : to_index, 0, int(slots.size()) - 1); + if (to == from) + return; + + update_model_object(); // flush the active layer's strokes into its slot before slots are exchanged + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Reorder texture displacement layers"), + UndoRedo::SnapshotType::GizmoAction); + // Walked one neighbour at a time, so every layer in between shifts by one and keeps its order. + const int step = to > from ? 1 : -1; + for (int i = from; i != to; i += step) + swap_layer_slots(slots[size_t(i)], slots[size_t(i + step)]); + + // The active layer's mask now sits in a different slot, so the selectors are reloaded from there. + update_from_model_object(false); // also rebuilds the preview + if (m_adjust_texture_mode) + update_adjust_anchor(); + m_parent.set_as_dirty(); +} + +int GLGizmoTextureDisplacement::select_visible_faces(const std::array *uv_clip) +{ + ModelVolume *mv = texture_volume(); + ModelObject *mo = m_c->selection_info()->model_object(); + const int idx = texture_volume_raycaster_index(); + if (mv == nullptr || mo == nullptr || idx < 0 || idx >= int(m_triangle_selectors.size())) + return 0; + + const indexed_triangle_set &its = mv->mesh().its; + if (its.indices.empty()) + return 0; + + const Selection &selection = m_parent.get_selection(); + const Geometry::Transformation trafo(mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * + mv->get_matrix()); + const Transform3d &to_world = trafo.get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + // Normals transform by the inverse transpose, not by the matrix itself - with a non-uniform + // scale the two differ, and using the wrong one flips the facing test on the scaled axes. + const Matrix3d normal_matrix = to_world.matrix().block<3, 3>(0, 0).inverse().transpose(); + + // Pass 1 (cheap): drop back-facing triangles. Under perspective the view direction varies across + // the model, so it is taken per triangle from the eye to the centroid; under an orthographic + // camera get_position() is still a point on the view axis, so the same expression stays correct + // in direction terms for everything actually on screen. + const Vec3d eye = camera.get_position(); + const bool ortho = camera.get_type() == Camera::EType::Ortho; + const Vec3d fwd = camera.get_dir_forward(); + + std::vector centroids; // world coords, what get_unobscured_idxs() expects + std::vector front_facing; // parallel: which facet each centroid came from + centroids.reserve(its.indices.size() / 2); + front_facing.reserve(its.indices.size() / 2); + + for (size_t f = 0; f < its.indices.size(); ++f) { + const stl_triangle_vertex_indices &tri = its.indices[f]; + const Vec3d a = its.vertices[tri[0]].cast(); + const Vec3d b = its.vertices[tri[1]].cast(); + const Vec3d c = its.vertices[tri[2]].cast(); + const Vec3d n_world = normal_matrix * (b - a).cross(c - a); + if (n_world.squaredNorm() < 1e-20) + continue; // degenerate triangle: no meaningful normal, so no meaningful facing test + const Vec3d centroid_local = (a + b + c) / 3.0; + const Vec3d centroid_world = to_world * centroid_local; + const Vec3d view_dir = ortho ? fwd : Vec3d(centroid_world - eye); + if (n_world.dot(view_dir) >= 0.0) + continue; // facing away from the camera + + // Clip to the projection frame before the raycast, not after: outside the frame the texture + // samples to nothing anyway, so those facets would only be painted to no effect - and this + // is also what keeps the ray queries proportional to the framed area instead of the model. + if (uv_clip != nullptr) { + Vec2f uv; + if (!project_uv_projective(*uv_clip, centroid_local.cast(), uv)) + continue; // behind the projector + if (uv.x() < 0.f || uv.x() > 1.f || uv.y() < 0.f || uv.y() > 1.f) + continue; + } + centroids.emplace_back(centroid_world.cast()); + front_facing.push_back(unsigned(f)); + } + if (centroids.empty()) + return 0; + + // Pass 2 (the expensive one): a real ray query per surviving centroid, so geometry in front of a + // front-facing triangle correctly hides it - the far inner wall of a cup is front-facing but not + // visible. This is why the whole thing is click-driven rather than live. + std::vector unobscured; + { + wxBusyCursor wait; + unobscured = m_c->raycaster()->raycasters()[size_t(idx)]->get_unobscured_idxs( + trafo, camera, centroids, m_c->object_clipper()->get_clipping_plane()); + } + if (unobscured.empty()) + return 0; + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Select visible faces for texture displacement"), + UndoRedo::SnapshotType::GizmoAction); + + // Replaces the layer's paint rather than adding to it: the checkbox means "project onto what I + // can see", so a second capture from a new angle should not leave the previous angle painted. + // TriangleSelectorGUI, not the TriangleSelector base: request_update_render_data() is declared on + // the GUI subclass, so binding to the base here would drop it. + TriangleSelectorGUI &selector = *m_triangle_selectors[size_t(idx)]; + selector.reset(); + for (unsigned i : unobscured) + selector.set_facet(int(front_facing[i]), EnforcerBlockerType::ENFORCER); + selector.request_update_render_data(); + + update_model_object(); + m_parent.set_as_dirty(); + return int(unobscured.size()); +} + +void GLGizmoTextureDisplacement::select_whole_model() +{ + ModelObject *mo = m_c->selection_info()->model_object(); + if (!mo) + return; + + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Select whole model for texture displacement"), UndoRedo::SnapshotType::GizmoAction); + + int idx = -1; + for (const ModelVolume *v : mo->volumes) { + if (!v->is_model_part()) + continue; + ++idx; + const size_t facet_count = v->mesh().its.indices.size(); + for (size_t i = 0; i < facet_count; ++i) + m_triangle_selectors[idx]->set_facet(int(i), EnforcerBlockerType::ENFORCER); + m_triangle_selectors[idx]->request_update_render_data(); + } + update_model_object(); + m_parent.set_as_dirty(); +} + +void GLGizmoTextureDisplacement::subdivide_model() +{ + ModelVolume *mv = texture_volume(); + ModelObject *mo = m_c->selection_info()->model_object(); + if (mv == nullptr || mo == nullptr || m_subdivide_count < 1) + return; // 0 passes means "no subdivision" - don't take a snapshot for a no-op + + Plater *plater = wxGetApp().plater(); + Plater::TakeSnapshot snapshot(plater, _u8L("Subdivide model for texture displacement"), UndoRedo::SnapshotType::GizmoAction); + + // Same save/replace/restore-painting dance GLGizmoSimplify uses when it re-tessellates a + // volume's mesh: supported/seam/mmu/fuzzy-skin masks get remapped onto the new triangles, + // texture-displacement doesn't (no remap support for it yet) and is dropped instead of being + // left referring to triangle indices that no longer mean the same thing. + std::optional saved_painting = mv->save_painting(); + + // max_edge_length 0 means "no triangle is ever small enough", so every non-degenerate edge is + // split on each of the m_subdivide_count passes - i.e. a plain "subdivide the whole mesh N times". + TriangleMesh new_mesh(subdivide_mesh_uniform(mv->mesh().its, 0.f, m_subdivide_count)); + mv->set_mesh(std::move(new_mesh)); + mv->set_new_unique_id(); + mv->calculate_convex_hull(); + mv->restore_painting(saved_painting); + + if (ObjectList *obj_list = wxGetApp().obj_list()) { + const ModelObjectPtrs &objs = plater->model().objects; + auto it = std::find(objs.begin(), objs.end(), mo); + if (it != objs.end()) + obj_list->update_info_items(size_t(it - objs.begin())); + } + + plater->changed_object(*mo); + update_from_model_object(false); // reload selectors/preview against the new mesh + cleared paint + m_parent.set_as_dirty(); +} + +bool GLGizmoTextureDisplacement::collect_paint_region( + const TriangleMesh &mesh, const TextureDisplacementFacetsData &facets, + std::vector ®ion, + std::array *paint) +{ + const indexed_triangle_set &its = mesh.its; + const size_t ntri = its.indices.size(); + const size_t nvert = its.vertices.size(); + + region.assign(ntri, 0); + if (paint) + for (LayerPaintMap &pm : *paint) + pm = LayerPaintMap{}; + + // Twice the area of each source triangle, for the "is this one covered edge to edge" test below. + // Only the paint carry-forward needs it, and the live subdivide preview calls this on every + // slider frame, so it is not built for the region-only path. + const auto tri_area2 = [](const Vec3f &a, const Vec3f &b, const Vec3f &c) { + return (b - a).cross(c - a).norm(); + }; + std::vector source_area2; + if (paint) { + source_area2.resize(ntri); + for (size_t i = 0; i < ntri; ++i) + source_area2[i] = tri_area2(its.vertices[size_t(its.indices[i][0])], + its.vertices[size_t(its.indices[i][1])], + its.vertices[size_t(its.indices[i][2])]); + } + + bool any_paint = false; + for (int slot = 0; slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++slot) { + const TriangleSelector::TriangleSplittingData &data = facets[size_t(slot)]; + if (!TriangleSelector::has_facets(data, EnforcerBlockerType::ENFORCER)) + continue; + + // The refine region is exactly the original triangles the brush touched. `triangles_to_split` + // lists precisely those: serialize() records an entry for every original triangle that is + // either split (i.e. partially painted, which is the patch boundary) or carries a non-default + // state (fully painted). No dilation - an earlier version marked every triangle sharing a + // *vertex* with the patch, which on a coarse model pulls in a whole fan of huge unpainted + // neighbours and then refines them to the resolution floor, since the height field the detail + // test samples is not restricted to the painted area. The conformal closure inside + // subdivide_mesh_adaptive() already grades the size change outward on its own. + for (const TriangleSelector::TriangleBitStreamMapping &m : data.triangles_to_split) + if (size_t(m.triangle_idx) < ntri) + region[m.triangle_idx] |= REFINE_PAINTED; + + if (paint) { + TriangleSelector sel(mesh); + sel.deserialize(data, false); + // get_facets_strict() now reports which source triangle each sub-triangle came from, which + // is what lets partial coverage be carried forward geometrically instead of being rounded + // away. Note a *fully* painted source can still come back as several sub-triangles (T-joint + // splits forced by a refined neighbour), so "wholly painted" is an area test, not a + // one-piece test. + std::vector src; + const indexed_triangle_set patch = sel.get_facets_strict(EnforcerBlockerType::ENFORCER, &src); + + LayerPaintMap &pm = (*paint)[slot]; + pm.full.assign(ntri, 0); + pm.part_start.assign(ntri + 1, 0); + + std::vector covered2(ntri, 0.f); + for (size_t j = 0; j < patch.indices.size() && j < src.size(); ++j) { + if (size_t(src[j]) >= ntri) + continue; + const stl_triangle_vertex_indices &t = patch.indices[j]; + covered2[size_t(src[j])] += tri_area2(patch.vertices[size_t(t[0])], patch.vertices[size_t(t[1])], + patch.vertices[size_t(t[2])]); + } + for (size_t i = 0; i < ntri; ++i) + pm.full[i] = (source_area2[i] > 0.f && covered2[i] >= 0.999f * source_area2[i]) ? 1 : 0; + + // Only partly covered sources need their pieces kept - a full one answers every query with + // "painted", and an untouched one with "not painted". + for (size_t j = 0; j < patch.indices.size() && j < src.size(); ++j) + if (size_t(src[j]) < ntri && !pm.full[size_t(src[j])]) + ++pm.part_start[size_t(src[j]) + 1]; + for (size_t i = 0; i < ntri; ++i) + pm.part_start[i + 1] += pm.part_start[i]; + pm.part.resize(size_t(pm.part_start[ntri])); + { + std::vector fill(pm.part_start.begin(), pm.part_start.begin() + ntri); + for (size_t j = 0; j < patch.indices.size() && j < src.size(); ++j) { + const size_t S = size_t(src[j]); + if (S >= ntri || pm.full[S]) + continue; + const stl_triangle_vertex_indices &t = patch.indices[j]; + pm.part[size_t(fill[S]++)] = { patch.vertices[size_t(t[0])], patch.vertices[size_t(t[1])], + patch.vertices[size_t(t[2])] }; + } + } + } + any_paint = true; + } + if (!any_paint) + return false; + + // The band straddling the paint's edge. The bake steps the surface from full displacement to zero + // across it, and nothing else in the refinement criteria can see that step: the chord-error + // sampler has no per-point paint test, so just outside the paint it keeps reporting the same + // smooth height field and reports no error at all. Left alone, the transition therefore stays at + // whatever density the input had - which is what makes the rim of an unpainted island a ring of + // big, steeply tilted triangles. + // + // Seeded from the vertices shared by a painted and an unpainted triangle (the actual edge of the + // paint) and grown outward over vertex adjacency, so the band covers both sides of the step. + if (BORDER_BAND_RINGS > 0) { + // Vertex -> incident triangles, CSR-style (counted, prefix-summed, filled). This runs on every + // frame of the subdivide preview's sliders, so it must not allocate a small vector per vertex. + std::vector vstart(nvert + 1, 0); + for (size_t i = 0; i < ntri; ++i) + for (int k = 0; k < 3; ++k) + if (size_t(its.indices[i][k]) < nvert) + ++vstart[size_t(its.indices[i][k]) + 1]; + for (size_t v = 0; v < nvert; ++v) + vstart[v + 1] += vstart[v]; + // static_cast, not size_t(...): the latter parses as a parameter declaration (see the note + // above the identical prefix sum on `part`). + std::vector vtri(static_cast(vstart[nvert]), 0); + { + std::vector fill(vstart.begin(), vstart.begin() + nvert); + for (size_t i = 0; i < ntri; ++i) + for (int k = 0; k < 3; ++k) + if (size_t(its.indices[i][k]) < nvert) + vtri[size_t(fill[size_t(its.indices[i][k])]++)] = int(i); + } + + // A vertex used by both a painted and an unpainted triangle sits exactly on the paint's edge. + std::vector ring_vertex(nvert, 0); + for (size_t v = 0; v < nvert; ++v) { + bool painted = false, unpainted = false; + for (int k = vstart[v]; k < vstart[v + 1]; ++k) + ((region[size_t(vtri[size_t(k)])] & REFINE_PAINTED) ? painted : unpainted) = true; + ring_vertex[v] = (painted && unpainted) ? 1 : 0; + } + + for (int ring = 0; ring < BORDER_BAND_RINGS; ++ring) { + std::vector next = ring_vertex; + for (size_t v = 0; v < nvert; ++v) { + if (!ring_vertex[v]) + continue; + for (int k = vstart[v]; k < vstart[v + 1]; ++k) { + const size_t t = size_t(vtri[size_t(k)]); + region[t] |= REFINE_BORDER; + // Grow through this triangle's other corners, for the following ring. + for (int c = 0; c < 3; ++c) + if (size_t(its.indices[t][c]) < nvert) + next[size_t(its.indices[t][c])] = 1; + } + } + ring_vertex.swap(next); + } + } + return true; +} + +TextureDisplacementFacetsData GLGizmoTextureDisplacement::masks_after_subdivision( + const TriangleMesh &new_mesh, const std::vector &source, + const std::array &paint) +{ + // Children inherit their parent's source triangle, and subdivision only ever adds edge midpoints, + // so every new triangle lies inside its source and on the same surface - which means the source's + // painted *pieces* can be queried directly by point containment. That is what keeps a brush outline + // smooth: rounding each source to wholly painted or not instead leaves a ragged fringe of isolated + // triangles along any curved boundary, and the refined mesh then reproduces that fringe exactly + // rather than hiding it. + TextureDisplacementFacetsData out{}; + const indexed_triangle_set &its = new_mesh.its; + for (int slot = 0; slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++slot) { + const LayerPaintMap &pm = paint[size_t(slot)]; + if (pm.empty()) + continue; + TriangleSelector sel(new_mesh); + for (size_t i = 0; i < source.size() && i < its.indices.size(); ++i) { + const size_t S = size_t(source[i]); + if (S >= pm.full.size()) + continue; + bool painted = pm.full[S] != 0; + if (!painted && pm.part_start[S] != pm.part_start[S + 1]) { + const stl_triangle_vertex_indices &t = its.indices[i]; + const Vec3f centroid = (its.vertices[size_t(t[0])] + its.vertices[size_t(t[1])] + + its.vertices[size_t(t[2])]) / 3.f; + for (int k = pm.part_start[S]; k < pm.part_start[S + 1] && !painted; ++k) + painted = point_in_triangle_coplanar(centroid, pm.part[size_t(k)]); + } + if (painted) + sel.set_facet(int(i), EnforcerBlockerType::ENFORCER); + } + out[size_t(slot)] = sel.serialize(); + } + return out; +} + +double GLGizmoTextureDisplacement::painted_area_mm2(const ModelVolume &mv) +{ + // Keyed on the paint generation, which every stroke and every layer edit raises, so a panel that + // asks for this on every frame walks the mesh only when the answer can have changed. + const std::string key = std::to_string(mv.id().id) + ":" + std::to_string(mv.mesh().facets_count()) + ":" + + std::to_string(m_preview_generation->load()); + if (key == m_painted_area_key) + return m_painted_area_mm2; + + const TriangleMesh &mesh = mv.mesh(); + std::vector region; + double area = 0.; + if (collect_paint_region(mesh, facets_data_of(mv), region, nullptr)) { + // In the frame the bake refines in, so a scaled instance is measured at the size it prints at. + const Transform3d frame = texture_displacement_bake_frame(texture_displacement_volume_to_world(mv)); + const indexed_triangle_set &its = mesh.its; + for (size_t t = 0; t < its.indices.size() && t < region.size(); ++t) { + if ((region[t] & REFINE_PAINTED) == 0) + continue; + const stl_triangle_vertex_indices &tri = its.indices[t]; + const Vec3d a = frame * its.vertices[size_t(tri[0])].cast(); + const Vec3d b = frame * its.vertices[size_t(tri[1])].cast(); + const Vec3d c = frame * its.vertices[size_t(tri[2])].cast(); + area += 0.5 * (b - a).cross(c - a).norm(); + } + } + m_painted_area_mm2 = area; + m_painted_area_key = key; + return area; +} + +size_t GLGizmoTextureDisplacement::estimated_refined_triangles(const ModelVolume &mv, float edge_mm) +{ + if (edge_mm <= 0.f) + return 0; + return size_t(4.0 * painted_area_mm2(mv) / (double(edge_mm) * double(edge_mm))); +} + +const V2Resolution &GLGizmoTextureDisplacement::v2_recommendation(const ModelVolume &mv) +{ + // Rebuilt only when something it depends on changes: the surface area scan is O(triangles) and the + // panel asks for this every frame. + std::string key = std::to_string(mv.id().id) + ":" + std::to_string(mv.mesh().facets_count()); + for (const TextureDisplacementLayer &l : mv.texture_displacement_layers) + key += Slic3r::format("|%1%:%2%:%3%:%4%", l.slot, reinterpret_cast(l.image_data.get()), l.tiling_scale, l.depth_mm); + const Transform3d trafo = texture_displacement_volume_to_world(mv); + for (int i = 0; i < 12; ++i) + key += Slic3r::format(",%1%", trafo.matrix()(i / 4, i % 4)); + if (key != m_v2_rec_key) { + m_v2_rec = recommend_v2_resolution(mv.mesh().its, mv.texture_displacement_layers, trafo); + m_v2_rec_key = std::move(key); + } + return m_v2_rec; +} + +TextureDisplacementFacetsData GLGizmoTextureDisplacement::facets_data_of(const ModelVolume &mv) +{ + TextureDisplacementFacetsData out{}; + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + out[size_t(i)] = mv.texture_displacement_facet(i).get_data(); + return out; +} + +bool GLGizmoTextureDisplacement::any_layer_colors(const ModelVolume &mv) +{ + for (const TextureDisplacementLayer &layer : mv.texture_displacement_layers) + if (layer.color_enabled && !layer.empty() && decode_height_texture(layer).has_color()) + return true; + return false; +} + +TextureColorSettings GLGizmoTextureDisplacement::color_settings_for(const ModelVolume &mv) +{ + TextureColorSettings out; + if (!any_layer_colors(mv)) + return out; // nothing is colouring: every colour path stays switched off + out.palette = cached_palette(); + out.palette_pure = make_palette(m_palette_filaments, /* mixing */ false); + out.mix_mode = mv.texture_displacement_options.color_mix_mode; + out.despeckle_passes = mv.texture_displacement_options.color_despeckle; + out.layer_height = color_band_mm(mv); + // The dither cell is tied to the colour-detail target: a cell much smaller than a facet cannot be + // drawn at all, and one much larger stops reading as a blend and starts reading as a check. + out.dither_cell_mm = std::max(m_subdivide_color_mm, 0.05f) * 2.f; + return out; +} + +const std::vector &GLGizmoTextureDisplacement::cached_palette() +{ + // Rebuilt only when the loaded filaments or the mixing setting actually change. The shaded preview + // rebuilds on every paint stroke and the subdivide preview on every slider frame, and filling the + // quantizer's lookup cube for a 64-entry palette is tens of milliseconds - paying that per stroke + // is the difference between painting that keeps up and painting that stutters. + const ModelVolume *mv = texture_volume(); + const bool mixing = mv != nullptr && mv->texture_displacement_options.color_mix_enabled; + std::vector filaments = filament_palette(); + if (m_palette_cache.empty() || filaments != m_palette_filaments || mixing != m_palette_mixing) { + m_palette_filaments = std::move(filaments); + m_palette_mixing = mixing; + m_palette_cache = make_palette(m_palette_filaments, mixing); + m_palette_quantizer = make_palette_quantizer(m_palette_cache); + } + return m_palette_cache; +} + +std::vector GLGizmoTextureDisplacement::filament_palette() +{ + std::vector palette = wxGetApp().plater()->get_extruders_colors(); + // mmu_segmentation_facets encodes the filament in a 6-bit prefix code and stops at Extruder16. + if (palette.size() > size_t(EnforcerBlockerType::ExtruderMax)) + palette.resize(size_t(EnforcerBlockerType::ExtruderMax)); + return palette; +} + +float GLGizmoTextureDisplacement::color_band_mm(const ModelVolume &mv) +{ + const float lh = print_layer_height(); + const float edge = (mv.texture_displacement_options.v2_refine_mm > 0.f) ? mv.texture_displacement_options.v2_refine_mm + : v2_recommendation(mv).edge_mm; + if (edge <= 0.f || lh <= 0.f) + return lh; + // A refined triangle of edge e stacks in rows about 0.87 * e apart (an equilateral triangle's + // height), and a dither needs at least two rows per period to be a dither at all. + constexpr float ROW_PER_EDGE = 0.87f; + return lh * std::max(1.f, std::ceil(2.f * ROW_PER_EDGE * edge / lh)); +} + +float GLGizmoTextureDisplacement::print_layer_height() +{ + try { + const DynamicPrintConfig &cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config; + if (const ConfigOptionFloat *opt = cfg.option("layer_height"); opt != nullptr) + if (opt->value > 1e-3) + return float(opt->value); + } catch (...) { + } + return 0.2f; +} + +std::vector GLGizmoTextureDisplacement::make_palette( + const std::vector &filaments, bool mixing) +{ + std::vector out; + const int n = int(filaments.size()); + for (int i = 0; i < n; ++i) + out.push_back({ Vec3f(filaments[size_t(i)].r(), filaments[size_t(i)].g(), filaments[size_t(i)].b()), + i, i, 1, 1 }); + if (!mixing || n < 2) + return out; + + // How many intermediate steps each pair gets, chosen so the whole palette stays under + // PALETTE_MAX_ENTRIES. Fewer filaments means more room for mixes, which is also what you want: + // with two filaments the mixes are the only way to get anywhere, and with sixteen there is little + // point mixing at all. `den` is also the band/dither repeat, so a small one is a short pattern. + const int pairs = n * (n - 1) / 2; + int steps = 0; + for (int s = 5; s >= 1; --s) + if (n + pairs * s <= PALETTE_MAX_ENTRIES) { + steps = s; + break; + } + if (steps == 0) + return out; + const int den = steps + 1; + + for (int i = 0; i < n; ++i) + for (int j = i + 1; j < n; ++j) { + const Vec3f lab_i = srgb_to_lab(Vec3f(filaments[size_t(i)].r(), filaments[size_t(i)].g(), filaments[size_t(i)].b())); + const Vec3f lab_j = srgb_to_lab(Vec3f(filaments[size_t(j)].r(), filaments[size_t(j)].g(), filaments[size_t(j)].b())); + for (int k = 1; k <= steps; ++k) { + // k/den of filament i, the rest of j - averaged in Lab, which is what the eye does + // when the two are interleaved too finely to resolve. + const float t = float(k) / float(den); + out.push_back({ lab_to_srgb(lab_i * t + lab_j * (1.f - t)), i, j, k, den }); + } + } + return out; +} + +ColorResolveFn GLGizmoTextureDisplacement::make_mix_resolver(const std::vector &palette, + ColorMixMode mode, float layer_height, + float cell_mm) +{ + if (palette.empty()) + return nullptr; + auto entries = std::make_shared>(palette); + const float band = std::max(layer_height, 0.01f); + const float cell = std::max(cell_mm, 0.01f); + + return [entries, mode, band, cell](int index, const Vec3f &pos, const Vec3f &normal) -> int { + if (index < 0 || size_t(index) >= entries->size()) + return -1; + const PaletteEntry &e = (*entries)[size_t(index)]; + if (!e.is_mix()) + return e.a; + + // Which of the two filaments this point falls on. Both patterns are *ordered*, never random: + // the eye blends a regular pattern into a flat colour, and turns a random one into noise. + // Auto: bands wherever the surface is steeper than ~45 degrees - consecutive layers alternate + // there, which is how a blend prints and reads. On a flat-facing surface a layer is one band + // and the only way to interleave is a checkerboard across the surface, which at print scale + // reads as a pattern rather than a colour; there the mix falls back to its dominant filament. + const bool upright = std::abs(normal.z()) < 0.7f; + if (mode == ColorMixMode::Auto && !upright) + return e.num * 2 >= e.den ? e.a : e.b; + const bool bands = mode == ColorMixMode::ZBands || mode == ColorMixMode::Auto; + if (bands) { + // One band per print layer. floorf, not a cast, so this stays correct below z = 0. + const int slot = int(std::floor(pos.z() / band)); + const int phase = ((slot % e.den) + e.den) % e.den; + return phase < e.num ? e.a : e.b; + } + // Ordered 4x4 Bayer over the surface, indexed by position so the pattern is stable in space + // rather than in triangle order (which would move under any remesh, and read as noise). + static const int BAYER[16] = { 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5 }; + const int gx = ((int(std::floor(pos.x() / cell)) % 4) + 4) % 4; + const int gy = ((int(std::floor(pos.y() / cell)) % 4) + 4) % 4; + // A third axis would be ideal, but the two dominant ones are enough for a surface pattern and + // keep the cell square on the faces that matter. + const float threshold = (float(BAYER[gy * 4 + gx]) + 0.5f) / 16.f; + return (float(e.num) / float(e.den)) > threshold ? e.a : e.b; + }; +} + +ColorQuantizeFn GLGizmoTextureDisplacement::make_palette_quantizer(const std::vector &palette) +{ + if (palette.empty()) + return nullptr; + + // Lab once per entry, not once per lookup. + struct Lab { float l, a, b; }; + std::vector palette_lab(palette.size()); + for (size_t i = 0; i < palette.size(); ++i) { + const Vec3f lab = srgb_to_lab(palette[i].rgb); + palette_lab[i] = { lab.x(), lab.y(), lab.z() }; + } + + constexpr int E = PALETTE_LUT_EDGE; + auto lut = std::make_shared>(size_t(E) * E * E, 0); + tbb::parallel_for(tbb::blocked_range(0, E), [&](const tbb::blocked_range &range) { + for (int r = range.begin(); r < range.end(); ++r) + for (int g = 0; g < E; ++g) + for (int b = 0; b < E; ++b) { + // Cell centre, so the quantization error is symmetric across the cell. + float l0, a0, b0; + const Vec3f lab0 = srgb_to_lab(Vec3f((r + 0.5f) / E, (g + 0.5f) / E, (b + 0.5f) / E)); + l0 = lab0.x(); a0 = lab0.y(); b0 = lab0.z(); + int best = 0, best_pure = -1; + float best_d = std::numeric_limits::max(), best_pure_d = best_d; + for (size_t i = 0; i < palette_lab.size(); ++i) { + const float d = DeltaE00(l0, a0, b0, palette_lab[i].l, palette_lab[i].a, palette_lab[i].b); + if (d < best_d) { + best_d = d; + best = int(i); + } + if (!palette[i].is_mix() && d < best_pure_d) { + best_pure_d = d; + best_pure = int(i); + } + } + // A mix is an interleave that only reads as its colour from a distance; up close + // it is stripes. Spend it only where it buys a clearly better match than the nearest + // single filament: ten Delta E is a visible step, less is not worth the stripes. + constexpr float PREFER_PURE_DE = 10.f; + if (best_pure >= 0 && palette[size_t(best)].is_mix() && best_pure_d - best_d < PREFER_PURE_DE) + best = best_pure; + (*lut)[(size_t(r) * E + size_t(g)) * E + size_t(b)] = uint8_t(best); + } + }); + + return [lut](const Vec3f &rgb) -> int { + constexpr int E = PALETTE_LUT_EDGE; + const int r = std::clamp(int(rgb.x() * E), 0, E - 1); + const int g = std::clamp(int(rgb.y() * E), 0, E - 1); + const int b = std::clamp(int(rgb.z() * E), 0, E - 1); + return int((*lut)[(size_t(r) * E + size_t(g)) * E + size_t(b)]); + }; +} + +TextureDisplacementPrepareResult GLGizmoTextureDisplacement::prepare_mesh( + const indexed_triangle_set &base, const TextureDisplacementFacetsData &masks, + const std::vector &layers, const TextureDisplacementPrepareParams ¶ms, + const std::vector &palette, const DisplacementProgressFn &progress, + BakeStageRecorder *debug) +{ + TextureDisplacementPrepareResult out; + const auto report = [&progress](int pct) { return !progress || progress(pct); }; + + // Stage capture for the debug view. Timed from the end of the previous stage, so the capture - + // a copy plus an edge scan - never lands inside the measurement it reports. + auto stage_clock = std::chrono::steady_clock::now(); + const auto capture = [&](const char *name, const indexed_triangle_set &m, + const std::string &detail = {}) { + if (debug == nullptr) + return; + const double ms = + std::chrono::duration(std::chrono::steady_clock::now() - stage_clock).count(); + debug->capture(name, m.vertices, m.indices, ms, detail); + stage_clock = std::chrono::steady_clock::now(); + }; + capture("input", base, "as handed to prepare"); + + TriangleMesh mesh(base); + TextureDisplacementFacetsData current = masks; + bool changed = false; + bool had_paint = false; + for (const TriangleSelector::TriangleSplittingData &m : masks) + had_paint = had_paint || TriangleSelector::has_facets(m, EnforcerBlockerType::ENFORCER); + if (!report(1)) + return out; + + // 1. Even out the triangle density, and carry the paint onto the result. Everything downstream is + // driven by that paint, so losing it is a hard stop rather than something to bake around - and + // stopping here, before anything is committed, leaves the user's model exactly as it was. + if (params.remesh_edge_mm > 0.f) { + indexed_triangle_set remeshed; + if (plan_remesh(mesh.its, params.remesh_edge_mm, params.remesh_sharp_deg, remeshed)) { + TriangleMesh new_mesh(std::move(remeshed)); + const AABBTreeIndirect::Tree3f old_tree = + AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(mesh.its.vertices, mesh.its.indices); + TextureDisplacementFacetsData carried{}; + bool any = false; + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) { + // Both meshes are the volume's own local frame, so there is no shift between them. + carried[size_t(i)] = + remap_texture_paint_spatial(mesh, current[size_t(i)], old_tree, new_mesh, Vec3f::Zero()); + any = any || !carried[size_t(i)].bitstream.empty(); + } + mesh = std::move(new_mesh); + current = std::move(carried); + changed = true; + capture("remesh", mesh.its, + "target " + std::to_string(params.remesh_edge_mm) + " mm" + + (had_paint && !any ? ", paint lost" : "")); + if (had_paint && !any) { + out.paint_lost = true; + return out; + } + } else if (debug != nullptr) { + capture("remesh", mesh.its, "skipped: remeshing changed nothing"); + } + } + if (!report(50)) + return {}; + + // 2. Refine where the texture bends - the painted area only, plus the graded band the conformal + // closure pulls in around it. + if (params.subdiv_target_mm > 0.f) { + std::vector region; + std::array paint; + if (collect_paint_region(mesh, current, region, &paint)) { + // Feature-adaptive: sample the combined displacement so refinement follows texture + // curvature. A null sampler (only LSCM layers, or nothing decodable) falls back to the + // length baseline alone. + HeightFieldSampler sampler; + if (params.subdiv_feature) + sampler = make_combined_displacement_sampler(mesh.its, layers, current); + // Colour boundaries need triangles of their own - the chord test cannot see them, since + // the height field is perfectly smooth across a change of filament. + ColorFieldSampler color; + if (params.subdiv_color_edge_mm > 0.f && !palette.empty()) + color = make_combined_color_sampler(mesh.its, layers, current, make_palette_quantizer(palette)); + // Note the sampler is built on the *quantizer* alone - the refinement follows perceived + // colour, never the interleaving that realises a mix (see ColorResolveFn). + // "Min edge" is a feature-mode control (it is the floor the curvature test refines down + // to); in plain adaptive mode the target edge length is the only criterion, so the floor + // must not be allowed to silently override a target the user set below it. + const float tol = params.subdiv_feature ? params.subdiv_detail_mm : 0.f; + const float floor = params.subdiv_feature ? params.subdiv_min_edge_mm : 0.f; + // Step textures (a grid, a knurl: two levels with sharp edges between them) are cut into + // walls after refining rather than refined into ramps, see 3. below. The verdict is taken + // here, on the coarse mesh, because the refinement has to know: in step mode it leaves + // the stepped triangles to the cutter, which is only right if the cutter then cuts them. + // The step width and the seam gap both span two texels of the finest layer: the bilinear + // blend across a step is a texel wide, so a seam copy a texel from the step samples a + // pure side. + float texel_mm = std::numeric_limits::max(); + if (params.cut_steps && sampler) + for (const TextureDisplacementLayer &layer : layers) { + if (layer.empty()) + continue; + const DecodedHeightTexture &tex = decode_height_texture(layer); + if (tex.width > 0 && layer.tiling_scale > 0.f) + texel_mm = std::min(texel_mm, layer.tiling_scale / float(tex.width)); + } + const bool cut_steps = texel_mm < std::numeric_limits::max() && + texture_has_steps_to_cut(mesh.its, region, sampler, 2.f * texel_mm, 2.f * texel_mm); + bool aborted = false; + std::vector source; + // The budget is "triangles the refinement may *add*", so the mesh's own count is the + // baseline - otherwise the control would be meaningless (or a dead end) on a dense model. + indexed_triangle_set refined = + subdivide_mesh_adaptive(mesh.its, region, params.subdiv_target_mm, + int(mesh.its.indices.size()) + params.subdiv_added_triangles, &source, + sampler, tol, floor, params.subdiv_border_mm, [&](int pct) { + aborted = !report(50 + pct / 2); + return !aborted; + }, + color, params.subdiv_color_edge_mm, cut_steps); + if (aborted) + return {}; + if (refined.indices.size() != mesh.its.indices.size()) { + mesh = TriangleMesh(std::move(refined)); + current = masks_after_subdivision(mesh, source, paint); + changed = true; + capture("adaptive subdivide", mesh.its, + params.subdiv_feature ? "feature adaptive" : "length only"); + } else if (debug != nullptr) { + capture("adaptive subdivide", mesh.its, "skipped: already meets the criteria"); + } + + // 3. Cut the painted area along the texture's sharp steps so they bake as walls. The + // refinement above left the stepped triangles alone, so this is where a binary + // texture's edges get their geometry. Paint is carried the same way as through the + // subdivision: every output triangle lies inside the pre-subdivision triangle it + // descends from, so the source maps compose. + if (cut_steps) { + std::vector cut_region(mesh.its.indices.size(), 0); + for (size_t i = 0; i < cut_region.size() && i < source.size(); ++i) + cut_region[i] = (region[size_t(source[i])] & REFINE_PAINTED) ? 1 : 0; + const HeightFieldSampler refined_sampler = + make_combined_displacement_sampler(mesh.its, layers, current); + std::vector cut_source; + size_t cuts = 0; + indexed_triangle_set cut = cut_mesh_at_steps(mesh.its, cut_region, refined_sampler, + 2.f * texel_mm, 2.f * texel_mm, 0.f, + &cut_source, &cuts); + if (cuts > 0) { + for (int &s : cut_source) + s = source[size_t(s)]; + mesh = TriangleMesh(std::move(cut)); + current = masks_after_subdivision(mesh, cut_source, paint); + changed = true; + capture("step cut", mesh.its, std::to_string(cuts) + " triangles cut"); + } else if (debug != nullptr) { + capture("step cut", mesh.its, "skipped: the refined mesh has no steps left to cut"); + } + } else if (debug != nullptr && params.cut_steps) { + capture("step cut", mesh.its, "skipped: not a step texture"); + } + } + } + if (!report(100) || !changed) + return out; // an empty result: nothing to commit, which is not a failure + + out.mesh = std::move(mesh.its); + out.masks = std::move(current); + return out; +} + +void GLGizmoTextureDisplacement::subdivide_model_adaptive() +{ + ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_subdivide_target_mm <= 0.f) + return; + + update_model_object(); // flush any in-progress stroke into the committed masks first + + if (!mv->is_texture_displacement_painted()) { + show_error(nullptr, _u8L("Paint the area you want to subdivide first - adaptive subdivision only " + "refines where you have painted.")); + return; + } + + TextureDisplacementPrepareParams params; + params.subdiv_target_mm = m_subdivide_target_mm; + params.subdiv_detail_mm = m_subdivide_detail_mm; + params.subdiv_min_edge_mm = m_subdivide_min_edge_mm; + params.subdiv_border_mm = m_subdivide_border_mm; + params.subdiv_color_edge_mm = m_subdivide_color_mm; + params.subdiv_feature = m_subdivide_feature; + params.subdiv_added_triangles = m_subdivide_budget_k * 1000; + queue_prepare(params, _u8L("Adaptive subdivide for texture displacement"), /* then_bake */ false, + _u8L("Nothing to subdivide - the painted area already meets the target edge length and " + "detail tolerance, or the triangle budget is already used up.")); +} + +void GLGizmoTextureDisplacement::smooth_model() +{ + ModelVolume *mv = texture_volume(); + ModelObject *mo = m_c->selection_info()->model_object(); + if (mv == nullptr || mo == nullptr) + return; + const TextureDisplacementOptions &opts = mv->texture_displacement_options; + if (opts.smooth_strength <= 0.f || opts.smooth_iterations <= 0) + return; + + update_model_object(); // flush any in-progress stroke, so the painted region below is current + + // Movable = the vertices of the painted triangles, so the first ring of purely unpainted vertices + // outside them stays put and anchors the result. Restricted rather than whole-model on purpose: + // this runs on geometry that has already been baked, and relaxing the whole thing would quietly + // round off every unrelated feature on the part. With "Ignore outer ring" the patch's own rim is + // held as well - see TextureDisplacementOptions::smooth_skip_border. + const indexed_triangle_set &its = mv->mesh().its; + std::vector painted_face(its.indices.size(), 0); + bool any = false; + for (int slot = 0; slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++slot) + for (const TriangleSelector::TriangleBitStreamMapping &m : mv->texture_displacement_facet(slot).get_data().triangles_to_split) + if (size_t(m.triangle_idx) < its.indices.size()) { + painted_face[size_t(m.triangle_idx)] = 1; + any = true; + } + if (!any) { + show_error(nullptr, _u8L("Paint the area you want to smooth first - smoothing only touches the " + "painted part of the model.")); + return; + } + std::vector movable(its.vertices.size(), 0); + for (size_t i = 0; i < its.indices.size(); ++i) + if (painted_face[i]) + for (int k = 0; k < 3; ++k) + movable[size_t(its.indices[i][k])] = 1; + if (opts.smooth_skip_border) + for (size_t i = 0; i < its.indices.size(); ++i) + if (!painted_face[i]) + for (int k = 0; k < 3; ++k) + movable[size_t(its.indices[i][k])] = 0; // also used by unpainted geometry -> the rim + if (std::none_of(movable.begin(), movable.end(), [](uint8_t m) { return m != 0; })) { + // Every painted vertex is on the patch's rim, so "Ignore outer ring" leaves nothing to move. + show_error(nullptr, _u8L("Nothing to smooth - the painted area is only one triangle deep, so with " + "\"Ignore outer ring\" on there are no interior vertices to relax.")); + return; + } + + indexed_triangle_set smoothed = its; + { + wxBusyCursor wait; + smooth_mesh_vertices(smoothed, movable, opts.smooth_strength, opts.smooth_iterations); + } + + Plater *plater = wxGetApp().plater(); + Plater::TakeSnapshot snapshot(plater, _u8L("Smooth texture displacement"), UndoRedo::SnapshotType::GizmoAction); + + // No save/restore-painting dance here, unlike subdivide and remesh: smoothing only moves vertices, + // it does not touch the triangle list, so every paint channel still refers to exactly the triangles + // it did before. set_mesh() clears the extra facets, so this saves and puts back the + // texture-displacement masks verbatim - no remap needed, and none of them is lost. + std::optional saved_painting = mv->save_painting(); + std::array saved_texture; + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + saved_texture[size_t(i)] = mv->texture_displacement_facet(i).get_data(); + + mv->set_mesh(TriangleMesh(std::move(smoothed))); + mv->set_new_unique_id(); + mv->calculate_convex_hull(); + mv->restore_painting(saved_painting); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + mv->texture_displacement_facet(i).set_data(std::move(saved_texture[size_t(i)])); + + if (ObjectList *obj_list = wxGetApp().obj_list()) { + const ModelObjectPtrs &objs = plater->model().objects; + auto it = std::find(objs.begin(), objs.end(), mo); + if (it != objs.end()) + obj_list->update_info_items(size_t(it - objs.begin())); + } + plater->changed_object(*mo); + update_from_model_object(false); + m_parent.set_as_dirty(); +} + +bool GLGizmoTextureDisplacement::plan_remesh(const indexed_triangle_set &src, float target_edge_mm, + float sharp_angle_deg, indexed_triangle_set &out) +{ + if (target_edge_mm <= 0.f) + return false; + + // Its cost and memory grow with the *square* of 1/target_edge, and it runs single-threaded on the + // UI thread, so the target has to be bounded against the part's actual surface area rather than + // taken at face value. Standard mode asks for 1 mm whatever it is handed, and the slider goes down + // to 0.1 mm: on a 150 mm part those are ~500 k and ~50 M triangles respectively - minutes to hours + // of frozen UI, which is indistinguishable from a hang. Raising the target instead still gives the + // subdivider the even density it needs, and the subdivision that follows is where the detail was + // always going to come from anyway. An equilateral triangle of edge L covers sqrt(3)/4 * L^2. + static constexpr double REMESH_MAX_TRIANGLES = 150000.0; + double area = 0.0; + for (const stl_triangle_vertex_indices &tri : src.indices) + area += 0.5 * double((src.vertices[size_t(tri[1])] - src.vertices[size_t(tri[0])]) + .cross(src.vertices[size_t(tri[2])] - src.vertices[size_t(tri[0])]) + .norm()); + if (const double budget_edge = std::sqrt(area / (0.4330127 * REMESH_MAX_TRIANGLES)); + budget_edge > double(target_edge_mm)) { + BOOST_LOG_TRIVIAL(info) << "Texture displacement: remesh target raised from " << target_edge_mm + << " mm to " << budget_edge << " mm to stay within " + << int(REMESH_MAX_TRIANGLES) << " triangles."; + target_edge_mm = float(budget_edge); + } + + // Five iterations with three relaxation passes each, rather than CGAL's three-and-one. Splitting + // and collapsing bring edge lengths near the target but leave the vertices where they fell, so it + // is the relaxation count that decides how even the result looks - and three passes in total was + // nowhere near enough. Fifteen costs proportionally more, but only on an explicit Remesh. + indexed_triangle_set remeshed = MeshBoolean::cgal::remesh_isotropic( + src, double(target_edge_mm), /* iterations */ 5, double(sharp_angle_deg), + /* relaxation steps */ 3); + // remesh_isotropic() signals failure by handing the input straight back, so compare against it + // structurally. Vertex count alone is not enough: a remesh that only redistributes triangles at + // roughly the current density legitimately lands on the same count, and treating that as failure + // meant a perfectly good result got thrown away with an error message. + if (remeshed.indices.empty() || + (remeshed.vertices.size() == src.vertices.size() && remeshed.indices.size() == src.indices.size() && + remeshed.indices == src.indices)) + return false; + + out = std::move(remeshed); + return true; +} + +void GLGizmoTextureDisplacement::remesh_model() +{ + if (texture_volume() == nullptr || m_remesh_target_edge_mm <= 0.f) + return; + + update_model_object(); // the paint rides across the remesh, so flush any in-progress stroke first + + TextureDisplacementPrepareParams params; + params.remesh_edge_mm = m_remesh_target_edge_mm; + params.remesh_sharp_deg = m_remesh_keep_sharp_edges ? m_remesh_sharp_angle_deg : 0.f; + queue_prepare(params, _u8L("Remesh model for texture displacement"), /* then_bake */ false, + _u8L("Remeshing did not change the model. It may be non-manifold (open edges or edges " + "shared by more than two triangles), or the target edge length may already be met.")); +} + +void GLGizmoTextureDisplacement::rebuild_subdivide_preview() +{ + m_subdivide_preview_glmodel.reset(); + m_subdivide_preview_tris = -1; + const ModelVolume *mv = texture_volume(); + if (mv == nullptr) + return; + + // The same subdivision Apply would commit, kept in a throwaway mesh and shown only as a + // wireframe - the model itself is not touched until Apply. + indexed_triangle_set its; + if (m_subdivide_adaptive) { + if (m_subdivide_target_mm <= 0.f) + return; + const TextureDisplacementFacetsData facets = facets_data_of(*mv); + std::vector region; + if (!collect_paint_region(mv->mesh(), facets, region, nullptr)) + return; // nothing painted yet: nothing to preview + HeightFieldSampler sampler; + if (m_subdivide_feature) + sampler = make_combined_displacement_sampler(mv->mesh().its, mv->texture_displacement_layers, facets); + // Feature mode: curvature (Detail tolerance) on top of the Max-edge baseline, down to the + // Min-edge floor. Plain adaptive: tol 0, so only the target-edge-length criterion applies. + const float tol = m_subdivide_feature ? m_subdivide_detail_mm : 0.f; + const float floor = m_subdivide_feature ? m_subdivide_min_edge_mm : 0.f; + // Same colour criterion Apply will use, so the previewed wireframe is the mesh that commits. + ColorFieldSampler color; + if (m_subdivide_color_mm > 0.f && any_layer_colors(*mv)) { + cached_palette(); // refreshes m_palette_quantizer if the filaments changed + color = make_combined_color_sampler(mv->mesh().its, mv->texture_displacement_layers, facets, + m_palette_quantizer); + } + its = subdivide_mesh_adaptive(mv->mesh().its, region, m_subdivide_target_mm, + int(mv->mesh().its.indices.size()) + m_subdivide_budget_k * 1000, + nullptr, sampler, tol, floor, m_subdivide_border_mm, nullptr, color, + m_subdivide_color_mm); + } else { + if (m_subdivide_count < 1) + return; + its = subdivide_mesh_uniform(mv->mesh().its, 0.f, m_subdivide_count); + } + if (its.indices.empty()) + return; + m_subdivide_preview_tris = int(its.indices.size()); + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + init_data.reserve_vertices(its.vertices.size()); + init_data.reserve_indices(its.indices.size() * 6); + for (const Vec3f &v : its.vertices) + init_data.add_vertex(v); + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) + init_data.add_line(unsigned(tri[i]), unsigned(tri[(i + 1) % 3])); + if (!init_data.is_empty()) + m_subdivide_preview_glmodel.init_from(std::move(init_data)); +} + +void GLGizmoTextureDisplacement::render_subdivide_preview() +{ + const ModelObject *mo = m_c->selection_info()->model_object(); + const ModelVolume *mv = texture_volume(); + if (mo == nullptr || mv == nullptr || !m_subdivide_preview_glmodel.is_initialized()) + return; + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + const Selection &selection = m_parent.get_selection(); + const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); + const Camera &camera = wxGetApp().plater()->get_camera(); + + shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + glsafe(::glEnable(GL_POLYGON_OFFSET_LINE)); + glsafe(::glPolygonOffset(-1.0f, -1.0f)); + m_subdivide_preview_glmodel.set_color(ColorRGBA(0.2f, 0.9f, 1.0f, 0.7f)); // cyan, reads as "preview" + m_subdivide_preview_glmodel.render(); + glsafe(::glDisable(GL_POLYGON_OFFSET_LINE)); + shader->stop_using(); +} + +GLTexture *GLGizmoTextureDisplacement::get_layer_thumbnail(const TextureDisplacementLayer &layer) +{ + if (layer.empty() || layer.slot < 0 || size_t(layer.slot) >= TEXTURE_DISPLACEMENT_MAX_LAYERS) + return nullptr; + + const size_t slot = size_t(layer.slot); + if (m_thumbnails[slot] && m_thumbnail_source[slot] == layer.image_data.get() && + m_thumbnail_smoothing[slot] == layer.smoothing) + return m_thumbnails[slot].get(); + + // Reuses the already-decoded, already-cached grayscale pixels (see decode_height_texture()'s + // own cache in TextureDisplacement.cpp) - only the gray-to-RGBA expansion and GPU upload below are + // new work. Rebuilt when the texture *or the smoothing* changes, so the fast/shaded preview - which + // samples this GPU texture directly - reflects the current smoothing rather than the raw image. + std::unique_ptr texture = upload_height_thumbnail(decode_height_texture(layer)); + if (!texture) + return nullptr; + + m_thumbnails[slot] = std::move(texture); + m_thumbnail_source[slot] = layer.image_data.get(); + m_thumbnail_smoothing[slot] = layer.smoothing; + return m_thumbnails[slot].get(); +} + +GLTexture *GLGizmoTextureDisplacement::get_layer_color_texture(const TextureDisplacementLayer &layer) +{ + if (layer.empty() || !layer.color_enabled) + return nullptr; + if (m_color_tex && m_color_tex_source == layer.image_data.get() && m_color_tex_smoothing == layer.smoothing) + return m_color_tex.get(); + + std::unique_ptr texture = upload_color_texture(decode_height_texture(layer), HEIGHT_TEX_MAX_PX); + if (!texture) { + m_color_tex.reset(); + m_color_tex_source = nullptr; + return nullptr; + } + m_color_tex = std::move(texture); + m_color_tex_source = layer.image_data.get(); + m_color_tex_smoothing = layer.smoothing; + return m_color_tex.get(); +} + +GLTexture *GLGizmoTextureDisplacement::get_layer_height_texture(const TextureDisplacementLayer &layer) +{ + if (layer.empty()) + return nullptr; + + // One slot, not one per layer: the preview shader only ever shades the *active* layer, so a single + // full-resolution upload is enough and the VRAM cost stays at one texture rather than eight. + if (m_height_tex && m_height_tex_source == layer.image_data.get() && m_height_tex_smoothing == layer.smoothing) + return m_height_tex.get(); + + std::unique_ptr texture = upload_height_thumbnail(decode_height_texture(layer), HEIGHT_TEX_MAX_PX); + if (!texture) + return nullptr; + + m_height_tex = std::move(texture); + m_height_tex_source = layer.image_data.get(); + m_height_tex_smoothing = layer.smoothing; + return m_height_tex.get(); +} + +void GLGizmoTextureDisplacement::bake(bool own_snapshot) +{ + ModelVolume *mv = texture_volume(); + if (!mv || m_bake_in_progress) + return; + + // Make sure the currently active layer's in-progress edits are flushed into the model before + // baking, otherwise the most recent, not-yet-committed strokes would be silently skipped. + update_model_object(); + + if (!mv->is_texture_displacement_painted()) { + show_error(nullptr, _u8L("Nothing is painted, there is nothing to bake.")); + return; + } + + m_bake_in_progress = true; + queue_texture_displacement_bake(*mv, color_settings_for(*mv), [this]() { + m_bake_in_progress = false; + // Baking replaces the volume's mesh (new id, new topology) without changing the object's + // id or volume count, so GLGizmoPainterBase::data_changed()'s usual change-detection never + // notices it needs to reload - do it explicitly here, otherwise the gizmo keeps painting + // and rendering against the stale, pre-bake TriangleSelectorPatch until the object is + // deselected and reselected. + if (m_state == On && m_c->selection_info() && m_c->selection_info()->model_object()) + update_from_model_object(false); + m_parent.set_as_dirty(); + }, own_snapshot); +} + +// Standard mode's fixed recipe. These are both the values the hidden controls are pinned to and what +// bake_standard() drives its remesh and subdivision with - one set of numbers, so the preview cannot +// disagree with the bake. Chosen to be safe on an arbitrary imported part rather than optimal on any +// particular one: a 1 mm isotropic remesh gives the subdivider an even starting density whatever the +// input looked like, and the subdivision then spends up to 1.5 M triangles chasing texture curvature +// down to a 0.02 mm floor, which is finer than any FDM nozzle will resolve. The triangle budget is not +// here: it is the one control Standard mode still shows, so it belongs to the user (its default is +// m_subdivide_budget_k's initialiser). +static constexpr float STD_REMESH_EDGE_MM = 1.0f; +static constexpr float STD_REMESH_SHARP_DEG = 40.f; +static constexpr float STD_SUBDIV_MAX_EDGE_MM = 20.f; +static constexpr float STD_SUBDIV_DETAIL_MM = 0.02f; +// 0.1 mm rather than the 0.02 it was: a hard step in the texture never satisfies the chord tolerance +// however finely it is split, so the floor is what stops it, and 0.02 mm carpeted every step edge with +// triangles five times finer than a nozzle can print - most of the budget, on almost every texture. +static constexpr float STD_SUBDIV_MIN_EDGE_MM = 0.1f; +// Edge length the band straddling the paint's edge is refined to. This is the one number that decides +// how clean the rim of an unpainted island looks: the bake steps the surface from full displacement to +// zero across that band, and nothing else in the criteria can see the step (see collect_paint_region()). +static constexpr float STD_SUBDIV_BORDER_MM = 0.4f; +// Edge length a colour boundary is refined to. Finer than the border band because a colour edge is +// what the eye actually lands on - a stepped outline around a printed decal reads as a defect in a +// way a slightly coarse relief transition does not - and it costs triangles along an outline only. +static constexpr float STD_SUBDIV_COLOR_MM = 0.25f; + +bool GLGizmoTextureDisplacement::apply_standard_mode_presets(ModelVolume *mv) +{ + bool changed = false; + const auto pin = [&changed](auto &field, auto value) { + if (field != value) { + field = value; + changed = true; + } + }; + + if (mv != nullptr) { + pin(mv->texture_displacement_options.displace_border, true); + pin(mv->texture_displacement_options.smooth_enabled, false); + } + pin(m_subdivide_adaptive, true); + pin(m_subdivide_feature, true); + pin(m_subdivide_target_mm, STD_SUBDIV_MAX_EDGE_MM); + pin(m_subdivide_detail_mm, STD_SUBDIV_DETAIL_MM); + pin(m_subdivide_min_edge_mm, STD_SUBDIV_MIN_EDGE_MM); + pin(m_subdivide_border_mm, STD_SUBDIV_BORDER_MM); + pin(m_subdivide_color_mm, STD_SUBDIV_COLOR_MM); + // Deliberately *not* pinned: the triangle budget stays visible and editable in Standard mode, so + // pinning it would fight the user's own slider every frame. + pin(m_remesh_target_edge_mm, STD_REMESH_EDGE_MM); + pin(m_remesh_keep_sharp_edges, true); + pin(m_remesh_sharp_angle_deg, STD_REMESH_SHARP_DEG); + return changed; +} + +void GLGizmoTextureDisplacement::bake_standard() +{ + ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_bake_in_progress || m_prepare_in_progress) + return; + + update_model_object(); // flush the active layer's in-progress strokes before anything reads them + if (!mv->is_texture_displacement_painted()) { + show_error(nullptr, _u8L("Nothing is painted, there is nothing to bake.")); + return; + } + apply_standard_mode_presets(mv); // belt and braces: never bake with values the panel is not showing + + // It refines as part of the bake, so preparing first would refine a second time at another + // target. + if (mv->texture_displacement_options.pipeline_v2) { + bake(); + return; + } + + // The whole recipe in one go. Either stage having nothing to do is normal, not a failure - a mesh + // that is already even needs no remesh, one that is already fine enough for the texture needs no + // subdivision - so no "nothing changed" message here: it goes straight on to the displacement. + TextureDisplacementPrepareParams params; + params.remesh_edge_mm = STD_REMESH_EDGE_MM; + params.remesh_sharp_deg = STD_REMESH_SHARP_DEG; + params.subdiv_target_mm = STD_SUBDIV_MAX_EDGE_MM; + params.subdiv_detail_mm = STD_SUBDIV_DETAIL_MM; + params.subdiv_min_edge_mm = STD_SUBDIV_MIN_EDGE_MM; + params.subdiv_border_mm = STD_SUBDIV_BORDER_MM; + params.subdiv_color_edge_mm = STD_SUBDIV_COLOR_MM; + params.subdiv_feature = true; + params.subdiv_added_triangles = m_subdivide_budget_k * 1000; + params.cut_steps = true; + queue_prepare(params, _u8L("Bake texture displacement"), /* then_bake */ true, {}); +} + +// --------------------------------------------------------------------------------------------- +// Bake stage debug view +// --------------------------------------------------------------------------------------------- + +void GLGizmoTextureDisplacement::run_stage_debug() +{ + ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_debug_in_progress || m_bake_in_progress || m_prepare_in_progress) + return; + + update_model_object(); // flush the active layer's in-progress strokes, as a real bake would + if (!mv->is_texture_displacement_painted()) { + show_error(nullptr, _u8L("Nothing is painted, so there are no bake stages to capture.")); + return; + } + + // The default (one-run) pipeline refines as part of the bake, and Pro mode has the user prepare the + // mesh themselves with the controls above - in both cases there is no preparation to replay, and + // running one anyway would show stages the Bake button would not. + const bool run_prepare = !pro_mode() && !mv->texture_displacement_options.pipeline_v2; + + TextureDisplacementPrepareParams params; + if (run_prepare) { + apply_standard_mode_presets(mv); // capture what the panel is showing, exactly as Bake does + params.remesh_edge_mm = STD_REMESH_EDGE_MM; + params.remesh_sharp_deg = STD_REMESH_SHARP_DEG; + params.subdiv_target_mm = STD_SUBDIV_MAX_EDGE_MM; + params.subdiv_detail_mm = STD_SUBDIV_DETAIL_MM; + params.subdiv_min_edge_mm = STD_SUBDIV_MIN_EDGE_MM; + params.subdiv_border_mm = STD_SUBDIV_BORDER_MM; + params.subdiv_color_edge_mm = STD_SUBDIV_COLOR_MM; + params.subdiv_feature = true; + params.subdiv_added_triangles = m_subdivide_budget_k * 1000; + params.cut_steps = true; + } + + // Free the previous run's meshes before the next one allocates its own: every stage is a full + // copy of the mesh, so holding two runs at once doubles what is already the expensive part. + exit_debug_view(); + + m_debug_in_progress = true; + queue_texture_displacement_debug( + *mv, color_settings_for(*mv), params, run_prepare, m_debug_check_topology, + [this](std::vector stages) { + m_debug_in_progress = false; + if (!stages.empty()) { + m_debug_stages = std::move(stages); + // Land on the last stage: that is what a real bake would have committed, and the + // question is usually what it looks like before stepping back to find where it went + // wrong. + show_debug_stage(int(m_debug_stages.size()) - 1); + } + m_parent.set_as_dirty(); + }); +} + +void GLGizmoTextureDisplacement::show_debug_stage(int index) +{ + if (index < 0 || size_t(index) >= m_debug_stages.size()) + return; + const BakeStageSnapshot &stage = m_debug_stages[size_t(index)]; + if (stage.mesh.empty()) + return; // over the memory cap: its counts are still listed, there is just nothing to draw + + m_debug_stage = index; + // Drawn through the ordinary true-displacement preview, so the Fast view - a shader trick over + // the base mesh that never draws m_preview_glmodel - has to be left first. + m_use_shaded_preview = false; + m_preview_color_runs.clear(); + m_preview_glmodel.reset(); + + indexed_triangle_set its; + its.vertices = stage.mesh.vertices; + its.indices = stage.mesh.indices; + m_preview_glmodel.init_from(its); + m_preview_glmodel.set_color(GLVolume::NEUTRAL_COLOR); + // Kept so the wireframe overlay draws this stage's edges rather than the base mesh's - which is + // most of the point, since what a refinement stage did is a change in the edges, not the surface. + m_preview_its = std::move(its); + refresh_wireframe(); + m_parent.set_as_dirty(); +} + +void GLGizmoTextureDisplacement::exit_debug_view() +{ + const bool was_showing = m_debug_stage >= 0; + m_debug_stage = -1; + m_debug_stages.clear(); + m_debug_stages.shrink_to_fit(); + if (was_showing) + rebuild_preview(); // hands m_preview_glmodel back to the live preview +} + +void GLGizmoTextureDisplacement::render_debug_stage_panel(ModelVolume *mv) +{ + if (mv == nullptr) + return; + + ImGui::Separator(); + if (!ImGui::CollapsingHeader(_u8L("Bake stages (debug)").c_str())) + return; + + m_imgui->disabled_begin(m_debug_in_progress || m_bake_in_progress || m_prepare_in_progress || + !mv->is_texture_displacement_painted()); + if (m_imgui->button(m_debug_in_progress ? _L("Capturing...") : _L("Capture stages"))) + run_stage_debug(); + m_imgui->disabled_end(); + if (ImGui::IsItemHovered()) + m_imgui->tooltip(_u8L("Run the same bake the Bake button runs, keeping the mesh after every " + "stage, and step through them here. Nothing is committed to the model - " + "this is for finding which stage a bad result came from."), + m_imgui->scaled(20.f)); + + ImGui::SameLine(); + ImGui::Checkbox(_u8L("Check topology").c_str(), &m_debug_check_topology); + if (ImGui::IsItemHovered()) + m_imgui->tooltip(_u8L("Count open and non-manifold edges after each stage, which is how a stage " + "that tore the mesh is spotted. It scans every edge, so it adds noticeably " + "to the capture on a fine bake."), + m_imgui->scaled(20.f)); + + if (m_debug_stages.empty()) + return; + + // Stage list. Selecting one draws it; the wireframe overlay is what makes a refinement stage + // readable, so it is worth leaving on while stepping. + ImGui::BeginChild("##bake_stages", ImVec2(0.f, m_imgui->scaled(9.f)), true, + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize); + for (size_t i = 0; i < m_debug_stages.size(); ++i) { + const BakeStageSnapshot &st = m_debug_stages[i]; + char label[256]; + std::snprintf(label, sizeof(label), "%zu. %-18s %8zu tris %8.1f ms##stage%zu", i, + st.name.c_str(), st.triangles, st.ms, i); + if (ImGui::Selectable(label, int(i) == m_debug_stage) && !st.mesh.empty()) + show_debug_stage(int(i)); + } + ImGui::EndChild(); + + // Prev / next, so stepping does not mean aiming at a list entry. + m_imgui->disabled_begin(m_debug_stage <= 0); + if (m_imgui->button(_L("< Previous"))) + show_debug_stage(m_debug_stage - 1); + m_imgui->disabled_end(); + ImGui::SameLine(); + m_imgui->disabled_begin(m_debug_stage < 0 || size_t(m_debug_stage + 1) >= m_debug_stages.size()); + if (m_imgui->button(_L("Next >"))) + show_debug_stage(m_debug_stage + 1); + m_imgui->disabled_end(); + ImGui::SameLine(); + if (m_imgui->button(_L("Close"))) + exit_debug_view(); + + if (m_debug_stage >= 0 && size_t(m_debug_stage) < m_debug_stages.size()) { + const BakeStageSnapshot &st = m_debug_stages[size_t(m_debug_stage)]; + m_imgui->text(from_u8(st.name) + ": " + std::to_string(st.triangles) + " " + + _u8L("triangles") + ", " + std::to_string(st.vertices) + " " + _u8L("vertices")); + if (!st.detail.empty()) + m_imgui->text(from_u8(st.detail)); + if (st.topology_checked) { + // Zero on both counts is the claim every stage's header makes; anything else is the bug. + const std::string topo = _u8L("Open edges") + ": " + std::to_string(st.open_edges) + " " + + _u8L("Non-manifold") + ": " + std::to_string(st.non_manifold_edges) + + " " + _u8L("Degenerate") + ": " + std::to_string(st.degenerate); + if (st.open_edges > 0 || st.non_manifold_edges > 0) + m_imgui->warning_text(from_u8(topo)); + else + m_imgui->text(topo); + } + } + + double total_ms = 0.0; + for (const BakeStageSnapshot &st : m_debug_stages) + total_ms += st.ms; + char total[128]; + std::snprintf(total, sizeof(total), "%s: %.1f ms", _u8L("Total").c_str(), total_ms); + m_imgui->text(total); + + if (m_imgui->button(_L("Write stage meshes"))) { + const std::string dir = + (boost::filesystem::temp_directory_path() / "orca-bake-stages").string(); + const size_t written = dump_bake_stages(m_debug_stages, dir); + if (written > 0) + show_info(nullptr, from_u8(_u8L("Wrote the stage meshes as OBJ files to:") + "\n" + dir)); + else + show_error(nullptr, _u8L("Could not write the stage meshes.")); + } + if (ImGui::IsItemHovered()) + m_imgui->tooltip(_u8L("Write every captured stage out as an OBJ file, so they can be opened " + "side by side in a mesh viewer."), + m_imgui->scaled(20.f)); +} + +void GLGizmoTextureDisplacement::queue_prepare(const TextureDisplacementPrepareParams ¶ms, + const std::string &snapshot_name, bool then_bake, + const std::string &unchanged_msg) +{ + ModelVolume *mv = texture_volume(); + if (mv == nullptr || m_prepare_in_progress || m_bake_in_progress) + return; + + TextureDisplacementPrepareInput input; + input.volume_id = mv->id(); + input.base_mesh = mv->mesh().its; + input.masks = facets_data_of(*mv); + input.layers = mv->texture_displacement_layers; + input.params = params; + input.snapshot_name = snapshot_name; + if (params.subdiv_color_edge_mm > 0.f) + input.color = color_settings_for(*mv); + + m_prepare_in_progress = true; + queue_texture_displacement_prepare(std::move(input), [this, then_bake, unchanged_msg]( + TextureDisplacementPrepareOutcome outcome) { + m_prepare_in_progress = false; + // The commit replaced the volume's mesh (new id, new topology) without changing the object's id + // or volume count, which is not something GLGizmoPainterBase::data_changed() can detect - so the + // reload is explicit, exactly as it is after a bake. Done for every outcome: even a run that + // committed nothing may have left the panel showing a stale triangle count. + if (m_state == On && m_c->selection_info() && m_c->selection_info()->model_object()) + update_from_model_object(false); + m_parent.set_as_dirty(); + + switch (outcome) { + case TextureDisplacementPrepareOutcome::Failed: + return; // cancelled, or the volume went away while the job ran - say nothing, do nothing + case TextureDisplacementPrepareOutcome::PaintLost: + show_error(nullptr, _u8L("The painted area could not be carried onto the remeshed model, so " + "nothing was changed. Switch to Pro mode and remesh before painting.")); + return; + case TextureDisplacementPrepareOutcome::Unchanged: + if (!unchanged_msg.empty()) + show_error(nullptr, unchanged_msg); + break; + case TextureDisplacementPrepareOutcome::Committed: + break; + } + // ... and then the displacement itself, in the background exactly as the Pro-mode button does. + // It commits into the snapshot the prepare opened - but only if the prepare opened one: a run + // that found nothing to do took none, and a bake chained onto that has to push its own or it + // would not be undoable at all. + if (then_bake) + bake(/* own_snapshot */ outcome == TextureDisplacementPrepareOutcome::Unchanged); + }); +} + +void GLGizmoTextureDisplacement::render_paint_cursor_hint() +{ + // Only in the plain paint/select modes; seam and adjust modes have their own click semantics where + // an add/remove sign would just be noise. + if (m_seam_edit_mode || m_adjust_texture_mode) + return; + const ImGuiIO &io = ImGui::GetIO(); + // The pointer must be over the 3D view, not over this panel (or any other ImGui window). + if (io.WantCaptureMouse || !ImGui::IsMousePosValid()) + return; + + // Shift erases (see handle_snapshot_action_name()), and so does a plain stroke in Erase mode. + const bool removing = io.KeyShift || m_erase_mode; + const ImU32 color = removing ? IM_COL32(235, 70, 60, 255) : IM_COL32(90, 210, 110, 255); + const char *glyph = removing ? "-" : "+"; + + ImDrawList *dl = ImGui::GetForegroundDrawList(); + const float fs = ImGui::GetFontSize() * 1.5f; + const ImVec2 at(io.MousePos.x + 15.f, io.MousePos.y - fs - 6.f); + // A translucent dark disc behind the glyph so it reads on any material colour. + dl->AddCircleFilled(ImVec2(at.x + fs * 0.28f, at.y + fs * 0.5f), fs * 0.62f, IM_COL32(0, 0, 0, 150)); + dl->AddText(ImGui::GetFont(), fs, at, color, glyph); +} + +void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float bottom_limit) +{ + ModelObject *mo = m_c->selection_info()->model_object(); + if (!mo) + return; + ModelVolume *mv = texture_volume(); + + const float approx_height = m_imgui->scaled(24.f); + y = std::min(y, bottom_limit - approx_height); + + // Docked (the default) the panel is pinned to the right edge of the 3D canvas and cannot be + // moved. Deliberately *not* next to the gizmo toolbar, which is where `x` points and where every + // other gizmo's window goes: this panel is far taller than those (layer stack plus the whole + // per-layer control set), so at the toolbar it sits right on top of the part of the model being + // painted. Pinning it to the canvas edge also parks it against the UV editor, since that pane is + // docked on the right and the canvas therefore ends exactly at the pane's left edge - so the + // panel follows the pane in and out instead of being clipped by it. + // + // Undocked it becomes an ordinary floating window: a title bar to drag it by, and no forced + // position - the position is deliberately not seeded on undock, so the window stays exactly + // where it already was and the user just gains the ability to move it from there. + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse; + if (!m_undocked) { + flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar; + // Right-aligned (pivot 1), so the width the panel auto-resized to last frame does not need to + // be known here. Width 0 skips GizmoImguiSetNextWIndowPos()'s own left-aligned fit-to-canvas + // clamp, which would push the window back off the edge it is being pinned to. + float right = float(m_parent.get_canvas_size().get_width()) - m_imgui->scaled(0.5f); + GizmoImguiSetNextWIndowPos(right, y, 0.f, 0.f, ImGuiCond_Always, 1.0f, 0.0f); + } + + ImGuiWrapper::push_toolbar_style(m_parent.get_scale()); + GizmoImguiBegin(get_name(), flags); + ensure_panel_icons(); + process_uv_commands(); // clicks from the UV editor pane, run here where the GL context is current + + // Pinned every frame while Standard is active, so what Preview shows is always what Bake will do. + if (!pro_mode() && apply_standard_mode_presets(mv)) + m_preview_params_dirty = true; + + // Layout follows the Option C design: a fixed-width panel, a header pinned at the top, a body that + // scrolls as one, and a footer with Bake pinned at the bottom. Rows are laid out against panel_w and + // against the body child's own fixed width - never against this window's width, which under + // AlwaysAutoResize is derived from its content and would feed back into it. + const bool dark = wxGetApp().dark_mode(); + const bool busy = m_bake_in_progress || m_prepare_in_progress; + const ImGuiStyle &style = ImGui::GetStyle(); + const float panel_w = m_imgui->scaled(21.5f); + const float frame_h = ImGui::GetFrameHeight(); + const float icon_md = std::round(frame_h * 1.25f); // tool and view buttons + const float icon_sm = std::round(frame_h * 1.05f); // buttons sitting in a row of text + const float gap_s = std::round(m_imgui->scaled(0.4f)); + const float label_w = m_imgui->scaled(4.8f); // label column of a label + slider row + const float card_pad = std::round(m_imgui->scaled(0.55f)); + const float wrap_w = m_imgui->scaled(20.f); + const ImVec4 orca = ImGuiWrapper::COL_ORCA; + const ImVec4 col_link = dark ? ImVec4(0.30f, 0.71f, 0.67f, 1.f) : ImVec4(0.f, 0.47f, 0.42f, 1.f); + const ImVec4 col_frame = dark ? ImVec4(0.212f, 0.212f, 0.235f, 1.f) : ImVec4(0.808f, 0.808f, 0.808f, 1.f); + const ImU32 col_card = dark ? IM_COL32(255, 255, 255, 10) : IM_COL32(0, 0, 0, 12); + const ImU32 col_line = dark ? IM_COL32(255, 255, 255, 18) : IM_COL32(0, 0, 0, 23); + const ImU32 col_sep = ImGui::GetColorU32(ImGuiCol_Separator); + + // Combo drop-downs otherwise inherit ImGui's near-black default popup background; under the light + // theme that leaves the dark item text unreadable ("the dropbox is black"). Pushed only around each + // Combo below (never around a tooltip, whose own near-black default is what makes it readable). + const ImVec4 combo_popup_bg = dark ? ImVec4(0.18f, 0.18f, 0.19f, 1.f) : ImVec4(0.93f, 0.93f, 0.93f, 1.f); + const auto scoped_combo = [&](const char *id, int *v, const char *const items[], int n) { + ImGui::PushStyleColor(ImGuiCol_PopupBg, combo_popup_bg); + const bool changed = ImGui::Combo(id, v, items, n); + ImGui::PopStyleColor(); + return changed; + }; + const auto hover_tip = [&](const auto &text) { + if (ImGui::IsItemHovered()) + m_imgui->tooltip(text, wrap_w); + }; + + // Framed icon toggle: a 1 px frame, and when on a teal frame over a teal tint with the icon in its + // original colours (IconManager's color_wite_gray variant [1]); off, the theme's grey variant [0]. + // `unavailable`, when not empty, draws it faded but still hoverable, so the tooltip can say why it + // cannot be used - a disabled ImGui item would swallow the hover and leave the user guessing. + const auto icon_toggle = [&](int uid, const std::string &iconfile, bool active, float sz, const wxString &label, + const wxString &tip_text, const wxString &unavailable = wxString()) -> bool { + const bool na = !unavailable.empty(); + const auto it = m_panel_icon_map.find(iconfile); + const float pad = std::max(1.f, std::round(sz * 0.14f)); + const int variant = active ? 1 : 0; + bool clicked = false; + ImGui::PushID(uid); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, na ? style.Alpha * 0.32f : style.Alpha); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.f); + ImGui::PushStyleColor(ImGuiCol_Button, active ? ImVec4(orca.x, orca.y, orca.z, 0.22f) : ImVec4(0.f, 0.f, 0.f, 0.f)); + if (na) { + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.f, 0.f, 0.f, 0.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f)); + } + if (it != m_panel_icon_map.end() && int(it->second.size()) > variant && it->second[size_t(variant)]->is_valid()) { + const IconManager::Icon &ic = *it->second[size_t(variant)]; + clicked = m_imgui->image_button((ImTextureID) (intptr_t) ic.tex_id, ImVec2(sz - 2.f * pad, sz - 2.f * pad), ic.tl, ic.br, + int(pad)); + } else { + clicked = ImGui::Button(label.ToUTF8().data(), ImVec2(0.f, sz)); // the control is never lost to a missing icon + } + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), + ImGui::GetColorU32(active ? orca : col_frame), style.FrameRounding); + ImGui::PopStyleColor(na ? 3 : 1); + ImGui::PopStyleVar(2); + ImGui::PopID(); + if (ImGui::IsItemHovered()) + m_imgui->tooltip(na ? tip_text + "\n\n" + unavailable : tip_text, wrap_w); + return clicked && !na; + }; + // Borderless icon button (non-toggle): always the grey monochrome variant. + const auto icon_button = [&](int uid, const std::string &iconfile, float sz, const wxString &label, + const wxString &tip_text) -> bool { + const auto it = m_panel_icon_map.find(iconfile); + const float pad = std::max(1.f, std::round(sz * 0.14f)); + bool clicked = false; + ImGui::PushID(uid); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.f); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); + if (it != m_panel_icon_map.end() && !it->second.empty() && it->second[0]->is_valid()) { + const IconManager::Icon &ic = *it->second[0]; + clicked = m_imgui->image_button((ImTextureID) (intptr_t) ic.tex_id, ImVec2(sz - 2.f * pad, sz - 2.f * pad), ic.tl, ic.br, + int(pad)); + } else { + clicked = ImGui::Button(label.ToUTF8().data(), ImVec2(0.f, sz)); + } + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); + ImGui::PopID(); + if (!tip_text.empty() && ImGui::IsItemHovered()) + m_imgui->tooltip(tip_text, wrap_w); + return clicked; + }; + // A short vertical rule between groups of buttons on one row; call it right after an item. + const auto vsep = [&](float h) { + ImGui::SameLine(0.f, gap_s); + const ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddLine(ImVec2(p.x, p.y + h * 0.2f), ImVec2(p.x, p.y + h * 0.8f), col_sep); + ImGui::Dummy(ImVec2(1.f, h)); + ImGui::SameLine(0.f, gap_s); + }; + const auto heading = [&](const wxString &text) { + m_imgui->push_bold_font(); + m_imgui->text(text); + m_imgui->pop_bold_font(); + }; + // Cuts a UTF-8 string down to `max_w` pixels, ending it in "..." when it had to be cut. + const auto ellipsize = [](std::string s, float max_w) { + if (ImGui::CalcTextSize(s.c_str()).x <= max_w) + return s; + while (!s.empty() && ImGui::CalcTextSize((s + "...").c_str()).x > max_w) { + unsigned char c; + do { // a whole code point at a time + c = static_cast(s.back()); + s.pop_back(); + } while (!s.empty() && (c & 0xC0) == 0x80); + } + return s + "..."; + }; + // Label column + a slider filling the rest of the row, value printed inside the track. Ctrl+click on + // any of these types a value in. `right_inset` keeps a layer card's inner padding. + const auto slider_label = [&](const wxString &label) { + const float x0 = ImGui::GetCursorPosX(); + ImGui::AlignTextToFramePadding(); + m_imgui->text(label); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w)); + }; + const auto float_row = [&](const char *id, const wxString &label, float *v, float v_min, float v_max, const char *format, + bool log, float right_inset) -> bool { + slider_label(label); + ImGui::SetNextItemWidth(-std::max(right_inset, 1.f)); + return ImGui::SliderFloat(id, v, v_min, v_max, format, ImGuiSliderFlags_AlwaysClamp | (log ? ImGuiSliderFlags_Logarithmic : 0)); + }; + const auto int_row = [&](const char *id, const wxString &label, int *v, int v_min, int v_max, const char *format, + float right_inset) -> bool { + slider_label(label); + ImGui::SetNextItemWidth(-std::max(right_inset, 1.f)); + return ImGui::SliderInt(id, v, v_min, v_max, format, ImGuiSliderFlags_AlwaysClamp); + }; + const auto layer_name = [](const TextureDisplacementLayer &l) { + return l.name.empty() ? Slic3r::format(_u8L("Layer %1%"), l.slot + 1) : l.name; + }; + // Painted on any model part. The selectors flush into the model at the end of every stroke. + const auto slot_painted = [mo](int slot) { + for (const ModelVolume *v : mo->volumes) + if (v->is_model_part() && !v->texture_displacement_facet(slot).empty()) + return true; + return false; + }; + + // ---- Header: title, Standard / Pro, dock toggle. Pinned above the body. ---- + { + const float x0 = ImGui::GetCursorPosX(); + ImGui::AlignTextToFramePadding(); + heading(_L("Texture displacement")); + + const std::string labels[2] = { _u8L("Standard"), _u8L("Pro") }; + const float seg_pad = m_imgui->scaled(0.5f); + const float seg_w[2] = { ImGui::CalcTextSize(labels[0].c_str()).x + 2.f * seg_pad, ImGui::CalcTextSize(labels[1].c_str()).x + 2.f * seg_pad }; + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + panel_w - (seg_w[0] + seg_w[1] + gap_s + icon_sm))); + + // Standard / Pro is a mode, not an option: Standard hides every mesh-preparation control and folds + // the whole recipe into Bake, Pro shows all of it and hands the ordering to the user. + const ImVec2 seg_min = ImGui::GetCursorScreenPos(); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.f, style.ItemSpacing.y)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.f); + m_imgui->disabled_begin(busy); + for (int m = 0; m < 2; ++m) { + if (m > 0) + ImGui::SameLine(); + const bool on = m_panel_mode == m; + ImGui::PushStyleColor(ImGuiCol_Button, on ? orca : ImVec4(0.f, 0.f, 0.f, 0.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, on ? orca : ImVec4(orca.x, orca.y, orca.z, 0.25f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, orca); + ImGui::PushStyleColor(ImGuiCol_Text, on ? ImVec4(1.f, 1.f, 1.f, 1.f) : style.Colors[ImGuiCol_TextDisabled]); + const bool clicked = ImGui::Button((labels[m] + "##panel_mode").c_str(), ImVec2(seg_w[m], frame_h)); + ImGui::PopStyleColor(4); + hover_tip(m == 0 ? _u8L("Standard - pick a texture, paint where it goes, press Bake. Everything the " + "mesh needs is done for you in that one step.") : + _u8L("Pro - the mesh preparation is yours to run: Remesh, Subdivide and Bake as " + "separate steps, with every setting on show. For when Standard's result is " + "not what you wanted and you know why.")); + if (clicked && !on) { + m_panel_mode = m; + if (!pro_mode()) { + // Leaving the subdivision preview open would strand a wireframe whose controls just + // disappeared, so close it as part of the switch. + m_subdivide_editing = false; + m_subdivide_preview_tris = -1; + m_subdivide_preview_glmodel.reset(); + if (apply_standard_mode_presets(mv)) + m_preview_params_dirty = true; + } + m_parent.set_as_dirty(); + } + } + m_imgui->disabled_end(); + ImGui::PopStyleVar(2); + ImGui::GetWindowDrawList()->AddRect(seg_min, ImVec2(ImGui::GetItemRectMax().x, seg_min.y + frame_h), + ImGui::GetColorU32(col_frame), style.FrameRounding); + + ImGui::SameLine(0.f, gap_s); + if (icon_button(806, "canvas_drag.svg", icon_sm, m_undocked ? _L("Dock panel") : _L("Undock panel"), + _L("Detach this panel so it can be dragged anywhere over the 3D view, or dock it back beside " + "the toolbar."))) + m_undocked = !m_undocked; + } + ImGui::Separator(); + + // ---- Body: everything between the header and the footer, scrolling as one. ---- + // Sized from last frame's content and footer heights (see m_panel_body_h): as tall as its content, + // but never so tall that the footer drops below the bottom of the canvas. + const float bottom = m_undocked ? ImGui::GetIO().DisplaySize.y : bottom_limit; + const float max_body_h = std::max(m_imgui->scaled(8.f), bottom - ImGui::GetCursorScreenPos().y - m_panel_footer_h - + style.WindowPadding.y - style.ItemSpacing.y); + const float body_h = m_panel_body_h > 0.f ? std::min(m_panel_body_h + 1.f, max_body_h) : max_body_h; + + // ImGui's stock scrollbar is a wide, square-cornered slab in a tinted track - against this flat panel + // it reads as a raw widget bolted onto the edge. Slim it to a rounded thumb over an invisible track. + const float scrollbar_w = m_imgui->scaled(0.5f); + const ImVec4 grab = dark ? ImVec4(1.f, 1.f, 1.f, 0.26f) : ImVec4(0.f, 0.f, 0.f, 0.26f); + ImGui::PushStyleVar(ImGuiStyleVar_ScrollbarSize, scrollbar_w); + ImGui::PushStyleVar(ImGuiStyleVar_ScrollbarRounding, 0.5f * scrollbar_w); + ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImVec4(0.f, 0.f, 0.f, 0.f)); + ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, grab); + ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(grab.x, grab.y, grab.z, 0.45f)); + ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(grab.x, grab.y, grab.z, 0.65f)); + ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.f, 0.f, 0.f, 0.f)); + // NoScrollWithMouse: the wheel is handled below so the scroll can be eased instead of teleporting + // five text lines per notch, which on blocks this tall lost the reader's place. + ImGui::BeginChild("##td_body", ImVec2(panel_w, body_h), false, ImGuiWindowFlags_NoScrollWithMouse); + { + ImGuiIO &io = ImGui::GetIO(); + const float scroll_now = ImGui::GetScrollY(); + const float scroll_max = ImGui::GetScrollMaxY(); + + // Anything that moved the scroll without us - dragging the grab, a keyboard/gamepad nav step, the + // content shrinking under a clamped offset - has to re-seed the target, or the easing below would + // immediately drag the view back to where it last animated to. + if (m_panel_scroll_applied < 0.f || std::abs(scroll_now - m_panel_scroll_applied) > 0.5f) + m_panel_scroll_target = scroll_now; + + if (io.MouseWheel != 0.f && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) + m_panel_scroll_target -= io.MouseWheel * ImGui::GetFontSize() * 4.f; + // Whole pixels: ImGui floors whatever SetScrollY() is given, so a fractional target could never be + // reached and the "still gliding" test below would stay true forever, repainting the canvas for good. + m_panel_scroll_target = std::floor(std::clamp(m_panel_scroll_target, 0.f, scroll_max)); + + const float delta = m_panel_scroll_target - scroll_now; + if (std::abs(delta) >= 1.f) { + // Exponential ease, formulated against the frame time so the glide takes the same wall time + // whether the canvas is running at 30 or 144 fps. The last sub-pixel step would be floored + // away, so land on the target outright once the remainder is that small. + const float t = 1.f - std::exp(-20.f * std::clamp(io.DeltaTime, 1.f / 240.f, 1.f / 15.f)); + const float step = (std::abs(delta * t) < 1.f) ? delta : delta * t; + const float next = std::floor(scroll_now + step); + ImGui::SetScrollY(next); + m_panel_scroll_applied = next; + m_parent.set_as_dirty(); // nothing else would redraw mid-glide once the mouse stops + } else { + m_panel_scroll_applied = scroll_now; + } + } + + // Everything that changes the layer list is deferred until the list is no longer being drawn: + // removing or reordering shifts mv->texture_displacement_layers under the pointers the loop holds, + // and switching the active layer mid-loop would draw two cards open for a frame. + int slot_to_remove = -1; + int move_slot = -1; + int move_to = -1; + int activate_slot = -1; + + TextureDisplacementLayer *active = mv != nullptr ? active_layer() : nullptr; + + // ---- Paint: which layer strokes land in, and Paint / Erase ---- + { + ImGui::AlignTextToFramePadding(); + heading(_L("Paint")); + const std::string into = active != nullptr ? Slic3r::format(_u8L("into %1%"), layer_name(*active)) : + _u8L("add a layer to paint"); + const float toggles_x = ImGui::GetWindowContentRegionMax().x - (2.f * icon_sm + gap_s); + const float text_end = toggles_x - (2.f * gap_s + 1.f); + ImGui::SameLine(); + const std::string shown = ellipsize(into, std::max(0.f, text_end - ImGui::GetCursorPosX())); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), text_end - ImGui::CalcTextSize(shown.c_str()).x)); + ImGui::TextDisabled("%s", shown.c_str()); + vsep(icon_sm); + ImGui::SetCursorPosX(toggles_x); + if (icon_toggle(820, "texture_displacement_add.svg", !m_erase_mode, icon_sm, _L("Paint"), + _L("Paint - add the active layer where you click or drag. The right button erases, and so does " + "holding Shift."))) + m_erase_mode = false; + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(821, "texture_displacement_add_negative.svg", m_erase_mode, icon_sm, _L("Erase"), + _L("Erase - remove the active layer where you click or drag. The right button paints."))) + m_erase_mode = true; + } + + // ---- Tools: brush / face / connected area, then the whole-model actions, then the active tool's own + // control filling the rest of the row ---- + // "Face" and "Connected area" reuse the exact same selection machinery every other paint gizmo has + // (single-facet click, and angle-limited flood fill respectively). + { + const bool is_brush_mode = m_tool_type == ToolType::BRUSH && m_cursor_type != TriangleSelector::CursorType::POINTER; + const bool is_face_mode = m_tool_type == ToolType::BRUSH && m_cursor_type == TriangleSelector::CursorType::POINTER; + const bool is_area_mode = m_tool_type == ToolType::SMART_FILL; + const float row_y = ImGui::GetCursorPosY(); + if (icon_toggle(801, "texture_displacement_brush.svg", is_brush_mode, icon_md, _L("Brush"), + _L("Brush - paint over the surface by dragging"))) { + m_tool_type = ToolType::BRUSH; + if (m_cursor_type == TriangleSelector::CursorType::POINTER) + m_cursor_type = TriangleSelector::CursorType::CIRCLE; + } + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(802, "texture_displacement_face.svg", is_face_mode, icon_md, _L("Face"), _L("Face - click individual triangles"))) { + m_tool_type = ToolType::BRUSH; + m_cursor_type = TriangleSelector::CursorType::POINTER; + } + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(803, "texture_displacement_connected_area.svg", is_area_mode, icon_md, _L("Connected area"), + _L("Connected area - flood-fill the region reachable without crossing an edge sharper than the " + "angle threshold"))) { + m_tool_type = ToolType::SMART_FILL; + m_cursor_type = TriangleSelector::CursorType::POINTER; + } + + // Whole model: paint every face with the active layer, or clear its paint from all of them. + const wxString whole_na = busy ? _L("Wait for the bake to finish.") : + active == nullptr ? _L("Add a layer first.") : + wxString(); + const wxString erase_na = !whole_na.empty() ? whole_na : + !slot_painted(m_active_layer_slot) ? _L("The active layer has no paint yet.") : + wxString(); + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(806, "texture_displacement_select_all.svg", false, icon_md, _L("Select whole model"), + _L("Select whole model - paint every face of the model with the active layer"), whole_na)) + select_whole_model(); + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(807, "texture_displacement_erase_all.svg", false, icon_md, _L("Erase whole model"), + _L("Erase whole model - clear the active layer's paint from every face"), erase_na)) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Reset texture displacement selection"), + UndoRedo::SnapshotType::GizmoAction); + int idx = -1; + for (ModelVolume *v : mo->volumes) + if (v->is_model_part()) { + ++idx; + m_triangle_selectors[idx]->reset(); + m_triangle_selectors[idx]->request_update_render_data(); + } + update_model_object(); + m_parent.set_as_dirty(); + } + + // The active tool's control fills the rest of the row, each part centred on the (taller) tool icons. + const float row_end = ImGui::GetWindowContentRegionMax().x; + const auto centre_on_row = [&](float h) { ImGui::SetCursorPosY(row_y + std::round((icon_md - h) * 0.5f)); }; + vsep(icon_md); + if (is_brush_mode) { + ImGui::SetNextItemWidth(std::max(1.f, row_end - ImGui::GetCursorPosX() - (3.f * gap_s + 1.f + 2.f * icon_sm))); + centre_on_row(frame_h); + ImGui::SliderFloat("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f mm", + ImGuiSliderFlags_AlwaysClamp); + hover_tip(m_desc.at("cursor_size")); + vsep(icon_sm); + const bool is_circle = m_cursor_type == TriangleSelector::CursorType::CIRCLE; + centre_on_row(icon_sm); + if (icon_toggle(804, "circle_paint.svg", is_circle, icon_sm, m_desc.at("circle"), + _L("Circle - paints everything under the brush as seen from the camera"))) + m_cursor_type = TriangleSelector::CursorType::CIRCLE; + ImGui::SameLine(0.f, gap_s); + centre_on_row(icon_sm); + if (icon_toggle(805, "menu_obj_sphere.svg", !is_circle, icon_sm, m_desc.at("sphere"), + _L("Sphere - paints only within a ball around the point under the cursor"))) + m_cursor_type = TriangleSelector::CursorType::SPHERE; + } else if (is_area_mode) { + ImGui::SetNextItemWidth(std::max(1.f, row_end - ImGui::GetCursorPosX())); + centre_on_row(frame_h); + ImGui::SliderFloat("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, "%.0f°", + ImGuiSliderFlags_AlwaysClamp); + hover_tip(_u8L("Angle threshold - the fill stops at edges sharper than this")); + } else { + centre_on_row(frame_h); + ImGui::AlignTextToFramePadding(); + ImGui::TextDisabled("%s", ellipsize(_u8L("Click a triangle to paint it"), + std::max(0.f, row_end - ImGui::GetCursorPosX())).c_str()); + } + } + + // ---- View: Normal / Fast / Checker / Distortion as one group, Wireframe on its own ---- + // The underlying state stays m_use_shaded_preview + m_uv_check_mode. + { + const int cur_mode = m_use_shaded_preview ? 1 : + m_uv_check_mode == UVCheckMode::Checker ? 2 : + m_uv_check_mode == UVCheckMode::Distortion ? 3 : 0; + int new_mode = cur_mode; + bool wf_toggle = false; + const wxString distortion_na = active == nullptr ? _L("Add a layer first.") : + active->projection_method != TextureProjectionMethod::LSCM ? + _L("Needs the active layer mapped with Unwrap (LSCM).") : + wxString(); + // Distortion over a layer that stopped being an unwrap shows nothing at all, so fall back to Normal. + if (cur_mode == 3 && !distortion_na.empty()) + new_mode = 0; + + const float x0 = ImGui::GetCursorPosX(); + ImGui::AlignTextToFramePadding(); + ImGui::TextDisabled("%s", _u8L("View").c_str()); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + m_imgui->scaled(2.6f))); + if (icon_toggle(701, "texture_displacement_real_preview.svg", cur_mode == 0, icon_md, _L("Normal"), + _L("Normal - the real geometry, exactly what Bake will produce. Slower to update"))) + new_mode = 0; + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(702, "texture_displacement_fast_preview.svg", cur_mode == 1, icon_md, _L("Fast"), + _L("Fast - the relief is only shaded on, not built, and only for the layer you are " + "editing. Updates instantly while you paint"))) + new_mode = 1; + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(703, "texture_displacement_checker.svg", cur_mode == 2, icon_md, _L("Checker"), + _L("Checker - a test grid instead of the texture. Where the squares stay square the " + "texture is undistorted; where they stretch, it will too"))) + new_mode = 2; + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(704, "texture_displacement_distortion.svg", cur_mode == 3, icon_md, _L("Distortion"), + _L("Distortion - blue-to-red stretch heatmap over the unwrap"), distortion_na)) + new_mode = 3; + vsep(icon_md); + if (icon_toggle(705, "texture_displacement_wireframe.svg", m_wireframe_overlay, icon_md, _L("Wireframe"), + _L("Wireframe - overlay the mesh edges; independent of the view above"))) + wf_toggle = true; + + const std::string auto_label = _u8L("Auto"); + const float auto_w = frame_h + style.ItemInnerSpacing.x + ImGui::CalcTextSize(auto_label.c_str()).x; + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), ImGui::GetWindowContentRegionMax().x - auto_w)); + if (ImGui::Checkbox((auto_label + "##auto_update").c_str(), &m_auto_update) && m_auto_update) + rebuild_preview(); // catch up anything that changed while it was off + hover_tip(_u8L("Rebuilds the preview as soon as anything changes. Turn it off on a heavy model if painting " + "or dragging a slider starts to stutter - the preview then waits until you let go.")); + + if (new_mode != cur_mode) + apply_view_mode(new_mode); + if (wf_toggle) { + m_wireframe_overlay = !m_wireframe_overlay; + refresh_wireframe(); + m_parent.set_as_dirty(); + } + } + + ImGui::Separator(); + // ---- Texture layers: the active layer as an open card, every other one as a single row ---- + { + ImGui::AlignTextToFramePadding(); + heading(_L("Texture layers")); + if (mv != nullptr) { + const std::string count = std::to_string(mv->texture_displacement_layers.size()) + " / " + + std::to_string(TEXTURE_DISPLACEMENT_MAX_LAYERS); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), ImGui::GetWindowContentRegionMax().x - ImGui::CalcTextSize(count.c_str()).x)); + ImGui::TextDisabled("%s", count.c_str()); + } + } + + std::vector ordered; + if (mv != nullptr) { + for (TextureDisplacementLayer &l : mv->texture_displacement_layers) + ordered.push_back(&l); + std::sort(ordered.begin(), ordered.end(), [](const auto *a, const auto *b) { return a->slot < b->slot; }); + } + + ImDrawList *dl = ImGui::GetWindowDrawList(); + const float content_rx = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x; + const float rounding = style.FrameRounding + 1.f; + + // Opens the texture library for a layer, making it the active one too (after the loop). + const auto open_picker = [&](int slot) { + m_picker_slot = slot; + m_picker_open_request = true; + }; + // The six-dot drag icon, drawn into `list` over [x, x + w] x [y, y + h]. + const auto draw_drag_icon = [&](ImDrawList *list, float x, float y, float w, float h, ImU32 tint) { + const auto it = m_panel_icon_map.find("texture_displacement_drag.svg"); + if (it != m_panel_icon_map.end() && !it->second.empty() && it->second[0]->is_valid()) { + // The icon's dots sit in the middle of its square, so it is drawn at the row's height centred on the + // narrow hit area; only its transparent margins overhang the neighbouring widgets. + const IconManager::Icon &ic = *it->second[0]; + const float cx = x + 0.5f * w; + list->AddImage((ImTextureID) (intptr_t) ic.tex_id, ImVec2(cx - 0.5f * h, y), ImVec2(cx + 0.5f * h, y + h), ic.tl, ic.br, tint); + } else { + const float r = std::max(1.f, std::round(m_imgui->scaled(0.08f))); + for (int row = 0; row < 3; ++row) + for (int col = 0; col < 2; ++col) + list->AddCircleFilled(ImVec2(x + w * (0.3f + 0.4f * col), y + h * 0.5f + float(row - 1) * 4.f * r), r, tint); + } + }; + const auto drag_tint = [dark](int alpha) { return dark ? IM_COL32(255, 255, 255, alpha) : IM_COL32(90, 90, 90, alpha); }; + + const float grip_w = std::round(m_imgui->scaled(0.7f)); + // Six-dot handle that drags a layer onto another one to reorder the stack. + const auto grip = [&](const TextureDisplacementLayer &l, float h) { + const ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::InvisibleButton("##grip", ImVec2(grip_w, h)); + const bool hot = ImGui::IsItemHovered() || ImGui::IsItemActive(); + draw_drag_icon(dl, p.x, p.y, grip_w, h, drag_tint(hot ? 255 : 150)); + hover_tip(_u8L("Drag onto another layer to reorder. The first layer sits on the bare surface; each one after " + "it adds its relief on top of the ones before.")); + // ImGui's own preview is a tooltip holding whatever is submitted here. The panel draws a copy of the whole + // layer row under the cursor instead (after the layer list), so that one is switched off. + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip)) { + const int slot = l.slot; + ImGui::SetDragDropPayload("TD_LAYER", &slot, sizeof(slot)); + ImGui::EndDragDropSource(); + } + }; + + // The layer being dragged, while a reorder drag is in flight. Its card stays in place as a faded ghost. + int dragged_slot = -1; + if (const ImGuiPayload *payload = ImGui::GetDragDropPayload(); payload != nullptr && payload->IsDataType("TD_LAYER")) + dragged_slot = *static_cast(payload->Data); + int dragged_index = -1; + for (size_t i = 0; i < ordered.size(); ++i) + if (ordered[i]->slot == dragged_slot) + dragged_index = int(i); + const ImU32 ghost_col = ImGui::GetColorU32(ImGuiCol_WindowBg, 0.65f); + + // A layer card or row [mn, mx] as a drop target. Dropped anywhere on another layer, the dragged one takes its + // place and the layers in between shift over by one - so it lands above the target when moving up and below it + // when moving down. A teal line on that side shows where; ImGui's default highlight rectangle says only + // "something is here", so it is replaced by the line. + // + // Deciding by which half of the target the cursor is over instead made dropping onto a neighbour's near half a + // silent no-op ("after the layer I am already after"), and that is exactly where a drag to the top ends. + const auto drop_target = [&](size_t index, int slot, const ImVec2 &mn, const ImVec2 &mx) { + if (!ImGui::BeginDragDropTarget()) + return; + if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("TD_LAYER", ImGuiDragDropFlags_AcceptBeforeDelivery | + ImGuiDragDropFlags_AcceptNoDrawDefaultRect)) { + const int from = *static_cast(payload->Data); + const bool after = dragged_index >= 0 && dragged_index < int(index); + if (from != slot) { + const float y = after ? mx.y + 2.f : mn.y - 2.f; + dl->AddLine(ImVec2(mn.x, y), ImVec2(mx.x, y), ImGui::GetColorU32(orca), 2.f); + } + if (payload->IsDelivery()) { + move_slot = from; + move_to = int(index) + (after ? 1 : 0); + } + } + ImGui::EndDragDropTarget(); + }; + + for (size_t li = 0; li < ordered.size(); ++li) { + TextureDisplacementLayer &layer = *ordered[li]; + const bool is_active = layer.slot == m_active_layer_slot; + const bool painted = slot_painted(layer.slot); + ImGui::PushID(layer.slot); + + if (is_active) { + // The card's height is not known until it is laid out, so its content goes into a foreground + // channel and the backing rectangle into a background one, merged at the end - the standard + // ImGui "rect behind a group" trick. + const ImVec2 card_min = ImGui::GetCursorScreenPos(); + dl->ChannelsSplit(2); + dl->ChannelsSetCurrent(1); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + card_pad); + ImGui::Indent(card_pad); + ImGui::BeginGroup(); + + // Header: grip, thumbnail and name (both open the library), paint state, order, remove. + { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(gap_s, style.ItemSpacing.y)); + grip(layer, frame_h); + ImGui::SameLine(); + if (GLTexture *thumb = get_layer_thumbnail(layer)) { + if (ImGui::ImageButton((ImTextureID) (intptr_t) thumb->get_id(), ImVec2(frame_h, frame_h), ImVec2(0.f, 0.f), + ImVec2(1.f, 1.f), 0)) + open_picker(layer.slot); + } else if (ImGui::Button("?##thumb", ImVec2(frame_h, frame_h))) { + open_picker(layer.slot); + } + hover_tip(_u8L("Pick a different image for this layer. The paint, depth and tiling stay as they are.")); + { + // The teal outline on the thumbnail is what marks this card as the layer being painted. + const ImVec2 a = ImGui::GetItemRectMin(), b = ImGui::GetItemRectMax(); + dl->AddRect(ImVec2(a.x - 2.f, a.y - 2.f), ImVec2(b.x + 2.f, b.y + 2.f), ImGui::GetColorU32(orca), style.FrameRounding); + } + ImGui::SameLine(); + + const std::string not_painted = _u8L("not painted"); + const float right_w = (painted ? 0.f : ImGui::CalcTextSize(not_painted.c_str()).x + gap_s) + 3.f * frame_h + 2.f * gap_s; + const float name_w = std::max(frame_h, ImGui::GetWindowContentRegionMax().x - card_pad - ImGui::GetCursorPosX() - gap_s - right_w); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(orca.x, orca.y, orca.z, 0.2f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(orca.x, orca.y, orca.z, 0.35f)); + ImGui::AlignTextToFramePadding(); + const std::string shown = ellipsize(layer_name(layer), name_w - 2.f * style.FramePadding.x); + if (ImGui::Selectable((shown + "##name").c_str(), false, 0, ImVec2(name_w, frame_h))) + open_picker(layer.slot); + ImGui::PopStyleColor(2); + hover_tip(_u8L("Pick a different image for this layer. The paint, depth and tiling stay as they are.")); + if (!painted) { + ImGui::SameLine(); + ImGui::TextDisabled("%s", not_painted.c_str()); + } + ImGui::SameLine(); + m_imgui->disabled_begin(busy || li == 0); + if (icon_button(611, "texture_displacement_move_up.svg", frame_h, _L("Move up"), _L("Move up - applied earlier"))) { + move_slot = layer.slot; + move_to = int(li) - 1; + } + m_imgui->disabled_end(); + ImGui::SameLine(); + m_imgui->disabled_begin(busy || li + 1 >= ordered.size()); + if (icon_button(612, "texture_displacement_move_down.svg", frame_h, _L("Move down"), _L("Move down - applied later"))) { + move_slot = layer.slot; + move_to = int(li) + 2; + } + m_imgui->disabled_end(); + ImGui::SameLine(); + m_imgui->disabled_begin(busy); + if (icon_button(600 + layer.slot, "texture_displacement_cross.svg", frame_h, m_desc.at("remove_layer"), + _L("Remove this layer"))) + slot_to_remove = layer.slot; + m_imgui->disabled_end(); + ImGui::PopStyleVar(); + } + + // The three controls nearly every layer needs; everything else waits behind "More settings". + // Depth and tile size are logarithmic, so both ends of their wide ranges stay usable. + m_preview_params_dirty |= float_row("##depth", _L("Depth"), &layer.depth_mm, 0.01f, 10.f, "%.3f mm", true, card_pad); + hover_tip(_u8L("Height of the relief: how far white in the texture lifts the surface, in " + "millimetres. Black does not move it at all, unless Midlevel says otherwise.")); + m_preview_params_dirty |= float_row("##tile_size", _L("Tile size"), &layer.tiling_scale, 0.2f, 200.f, "%.2f mm", true, card_pad); + hover_tip(_u8L("How wide one copy of the texture is on the model. Smaller repeats the pattern " + "more often and makes its detail finer; with Tile off, this is the size of the " + "single copy.")); + m_preview_params_dirty |= float_row("##rotation", _L("Rotation"), &layer.rotation_deg, 0.f, 360.f, "%.0f°", false, card_pad); + hover_tip(_u8L("Turns the texture on the surface, in degrees - for lining a pattern up with an " + "edge of the model.")); + + if (m_layer_expanded[size_t(layer.slot)]) { + { + // A dashed rule between the basic and the advanced settings. + const ImVec2 p = ImGui::GetCursorScreenPos(); + const float x1 = content_rx - card_pad; + const float dash = std::round(m_imgui->scaled(0.25f)); + for (float xx = p.x; xx < x1; xx += 2.f * dash) + dl->AddLine(ImVec2(xx, p.y), ImVec2(std::min(xx + dash, x1), p.y), col_line); + ImGui::Dummy(ImVec2(1.f, 1.f)); + } + + // Midlevel: the height that means "don't move". At 0 the surface only ever bulges outwards; + // at 0.5 mid-grey is neutral and darker texels cut inwards. + m_preview_params_dirty |= float_row("##midlevel", _L("Midlevel"), &layer.midlevel, 0.f, 10.f, "%.2f", false, card_pad); + hover_tip(_u8L("Which grey stays where the surface already is. At 0 the texture only pushes " + "outwards; at 0.5 mid-grey stays put, so darker greys cut in and lighter ones " + "still push out - one image both embosses and engraves.\n\n" + "What cuts in has to fit: inside a sharp corner or through a thin wall, a deep " + "cut can pass through the other side.")); + if (layer.midlevel > 0.f && layer.depth_mm > 1.f) { + ImGui::PushTextWrapPos(content_rx - card_pad); + m_imgui->warning_text(_L("Deep inward displacement may self-intersect.")); + ImGui::PopTextWrapPos(); + } + + m_preview_params_dirty |= float_row("##smoothing", _L("Smoothing"), &layer.smoothing, 0.f, 1.f, "%.2f", false, card_pad); + hover_tip(_u8L("Blurs the image before it is used, which rounds off hard steps and removes " + "speckle from a noisy photo. Raise it if the relief looks harsh or grainy; it " + "costs fine detail.")); + + // Edge fade: the relief flattens toward the boundary of the painted area. + m_preview_params_dirty |= ImGui::Checkbox((_u8L("Edge fade") + "##edge_smoothing").c_str(), &layer.edge_smoothing); + hover_tip(_u8L("Flattens the relief as it approaches the edge of the painted area, so it " + "blends into the bare surface instead of stopping at a step.")); + ImGui::SameLine(); + m_imgui->disabled_begin(!layer.edge_smoothing); + ImGui::SetNextItemWidth(-card_pad); + m_preview_params_dirty |= ImGui::SliderFloat("##edge_amount", &layer.edge_smoothing_amount, 0.02f, 1.f, "%.2f", + ImGuiSliderFlags_AlwaysClamp); + m_imgui->disabled_end(); + hover_tip(_u8L("How far in the fade reaches, as a share of the painted area. Small values " + "soften a narrow band at the edge; 1 flattens almost all of it.")); + + // Invert and Colours share a row. + { + const float x0 = ImGui::GetCursorPosX(); + m_preview_params_dirty |= ImGui::Checkbox(_u8L("Invert").c_str(), &layer.invert); + hover_tip(_u8L("Turns the relief inside out: what stood out is cut in, and the other way " + "round. The same as using a negative of the image.")); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + 0.5f * (ImGui::GetWindowContentRegionMax().x - card_pad - x0))); + + // Only offered for a texture that actually has colour - the shipped library is grayscale, + // and a checkbox that silently does nothing on nine textures out of ten is worse than no + // checkbox. Disabled rather than hidden so it is clear the feature exists and what it wants. + const bool has_color = decode_height_texture(layer).has_color(); + bool color_enabled = layer.color_enabled && has_color; + m_imgui->disabled_begin(!has_color); + if (ImGui::Checkbox(_u8L("Colours").c_str(), &color_enabled)) { + layer.color_enabled = color_enabled; + m_preview_params_dirty = true; + } + m_imgui->disabled_end(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + m_imgui->tooltip(has_color ? + _u8L("Prints the painted area in the texture's colours as well as its " + "relief. Each colour is matched to the nearest of your loaded " + "filaments; anything you did not paint keeps the object's own.") : + _u8L("This texture is a grayscale height map, so it has no colours to " + "apply. Import a colour image to use this."), + wrap_w); + + // The rest of colour belongs to the whole stack, not to this layer, so it only appears once - + // under whichever layer turned colour on. + if (color_enabled) { + TextureDisplacementOptions &opts = mv->texture_displacement_options; + if (ImGui::Checkbox(_u8L("Mix filaments").c_str(), &opts.color_mix_enabled)) + m_preview_params_dirty = true; + hover_tip(_u8L("Interleaves two filaments to fake the colours in between, so a handful " + "of filaments can cover a photo or a gradient. An image of flat colours " + "prints the same either way. Off uses one filament per area.")); + if (opts.color_mix_enabled) { + slider_label(_L("Mix by")); + const std::string mix_z = _u8L("Layers"); + const std::string mix_xy = _u8L("Surface"); + const std::string mix_auto = _u8L("Automatic"); + const char *mix_items[] = { mix_z.c_str(), mix_xy.c_str(), mix_auto.c_str() }; + int mix_mode = int(opts.color_mix_mode); + ImGui::SetNextItemWidth(-card_pad); + if (scoped_combo("##color_mix_mode", &mix_mode, mix_items, IM_ARRAYSIZE(mix_items))) { + opts.color_mix_mode = ColorMixMode(mix_mode); + m_preview_params_dirty = true; + } + hover_tip(_u8L("Layers: the two filaments alternate between print layers, which " + "blends smoothly on upright surfaces but disappears on flat-facing " + "ones, where a whole layer is a single band.\n" + "Surface: a fine checkerboard across the surface, which works at " + "any angle but can read as texture rather than as a blend.\n" + "Automatic: layers on upright faces; flat-facing faces take the nearer " + "single filament, since a checkerboard there shows as a pattern.")); + ImGui::TextDisabled("%s", Slic3r::format(_u8L("%1% printable colours from %2% filaments"), + int(cached_palette().size()), int(m_palette_filaments.size())).c_str()); + } + if (int_row("##color_despeckle", _L("Denoise"), &opts.color_despeckle, 0, 6, "%d", card_pad)) + m_preview_params_dirty = true; + hover_tip(_u8L("Cleans up single stray triangles of the wrong colour, which detail finer " + "than the mesh leaves behind. Raise it if the result looks speckled, " + "lower it if small features are being swallowed.")); + } + } + + // Mapping, as five icons in TextureProjectionMethod's own order. + { + const float x0 = ImGui::GetCursorPosX(); + ImGui::AlignTextToFramePadding(); + ImGui::TextDisabled("%s", _u8L("Mapping").c_str()); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w)); + struct MappingIcon + { + const char *file; + wxString label; + wxString tip; + }; + const MappingIcon mappings[] = { + { "menu_obj_cube.svg", _L("Triplanar (blended)"), + _L("Triplanar - projects the texture from all three axes at once and blends between them, so a " + "patch wrapping around a sharp edge has no seam.") }, + { "menu_obj_cylinder.svg", _L("Cylindrical"), + _L("Cylindrical - wraps the texture around the painted area's own centre, for round shapes.") }, + { "menu_obj_sphere.svg", _L("Spherical"), + _L("Spherical - wraps the texture around the painted area's own centre in both directions.") }, + { "texture_displacement_map_unwrap.svg", _L("Unwrap (LSCM)"), + _L("Unwrap - flattens the painted area and maps the texture onto it with as little stretching as " + "possible. The area is cut into pieces at its sharp edges first (see Seam angle), so each " + "piece can lie flat on its own.") }, + { "texture_displacement_map_view.svg", _L("From view"), + _L("From view - projects straight onto the painted area from where you are looking, like a slide " + "projector.") }, + }; + for (int mi = 0; mi < int(IM_ARRAYSIZE(mappings)); ++mi) { + if (mi > 0) + ImGui::SameLine(0.f, gap_s); + const auto method = static_cast(mi); + if (icon_toggle(830 + mi, mappings[mi].file, layer.projection_method == method, icon_sm, mappings[mi].label, + mappings[mi].tip) && + layer.projection_method != method) { + // Capture the current view the moment "From view" is chosen, so it does something + // sensible immediately rather than projecting from a stale/default direction. + if (method == TextureProjectionMethod::ViewProjected) + capture_view_projection(layer); + layer.projection_method = method; + m_preview_params_dirty = true; + // Unwrap and its tools live in the UV editor pane, so picking it opens the pane + // (via the preview rebuild this triggers). + if (method == TextureProjectionMethod::LSCM) + m_show_uv_editor = true; + } + } + } + + if (layer.projection_method == TextureProjectionMethod::LSCM) { + // Unwrap and everything that edits it live in the UV editor pane, next to the islands they change. + // Picking this mapping opens the pane; this brings it back after it has been closed. + if (m_imgui->button(_u8L("Open UV editor"))) { + m_show_uv_editor = true; + update_uv_editor(); + } + hover_tip(_u8L("Opens the UV editor, where you can see how the texture is laid out over the " + "painted area, cut seams and move the pieces around.")); + ImGui::SameLine(); + ImGui::AlignTextToFramePadding(); + if (m_uv_editor_unwrap.empty()) + ImGui::TextDisabled("%s", _u8L("Not unwrapped yet").c_str()); + else + ImGui::TextDisabled("%s", Slic3r::format(_u8L("%1% islands"), m_uv_editor_unwrap.chart_count).c_str()); + } + + if (layer.projection_method == TextureProjectionMethod::ViewProjected) { + // Re-capture the projector from wherever the camera is now: orbit the model, press this, and + // the texture is re-laid from the new angle. + if (m_imgui->button(_u8L("Capture current view"))) { + capture_view_projection(layer); + // Selecting the visible faces *after* capturing means the projector axes are already the + // ones the selection was made against - the two describe the same viewpoint. + if (m_project_only_visible && select_visible_faces() == 0) + show_error(nullptr, _u8L("Nothing is visible from this angle - turn the model to face the " + "part you want to project onto.")); + m_preview_params_dirty = true; + update_projector(); + } + hover_tip(_u8L("Projects the texture onto the painted area from where you are looking now, like " + "a slide projector. Faces turned away from you stretch, so line the view up with " + "the surface you care about first.")); + + if (ImGui::Checkbox(_u8L("Project only on visible").c_str(), &m_project_only_visible)) { + if (m_project_only_visible && select_visible_faces() == 0) + show_error(nullptr, _u8L("Nothing is visible from this angle - turn the model to face the " + "part you want to project onto.")); + m_preview_params_dirty = true; + update_projector(); + } + hover_tip(_u8L("Paints only the faces you can actually see right now - facing you and not hidden " + "behind anything - and projects onto those. Replaces what the layer had painted.")); + + bool projector_open = m_projector_frame != nullptr && m_projector_frame->IsShown(); + if (ImGui::Checkbox(_u8L("Projection frame").c_str(), &projector_open)) + show_projector(projector_open); + hover_tip(_u8L("Opens a window you drag over the model. Whatever you can see through it is what " + "gets the texture, and its border becomes the edge of the projection.")); + + if (projector_open) { + if (int_row("##projector_opacity", _L("Opacity"), &m_projector_opacity, 20, 255, "%d", card_pad)) + m_projector_frame->set_opacity(m_projector_opacity); + hover_tip(_u8L("How solid the frame window looks while you place it. Lower to see the " + "model through it; it does not affect the result.")); + + if (m_imgui->button(_u8L("Apply projection frame"))) { + const int painted_count = apply_projection_frame(); + if (painted_count == 0) + show_error(nullptr, _u8L("Nothing of the model is inside the frame - move it over the " + "part you want to project onto.")); + else if (painted_count < 0) + show_error(nullptr, _u8L("The frame could not be applied. Make sure it overlaps the 3D view.")); + } + hover_tip(_u8L("Projects the texture through the frame from where you are looking now and " + "paints the faces inside it. Replaces what the layer had painted; the result " + "sticks to the model, so you can orbit afterwards.")); + } + + if (layer.view_project_projective) { + ImGui::AlignTextToFramePadding(); + ImGui::TextDisabled("%s", _u8L("Placed by projection frame.").c_str()); + ImGui::SameLine(); + if (m_imgui->button(_u8L("Clear"))) { + // Back to the plain axis projection, where tiling/rotation/offset mean something again - + // the matrix path deliberately ignores them. + layer.view_project_projective = false; + layer.tile_enabled = true; + m_preview_params_dirty = true; + } + } + } + + // Tile, and how it repeats. + { + const float x0 = ImGui::GetCursorPosX(); + m_preview_params_dirty |= ImGui::Checkbox((_u8L("Tile") + "##tile_enabled").c_str(), &layer.tile_enabled); + hover_tip(_u8L("Repeats the texture across the painted area. Off places one copy, like a decal, " + "at the size set by Tile size.")); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w)); + const wxString tile_na = layer.tile_enabled ? wxString() : _L("Turn Tile on to choose how the texture repeats."); + if (icon_toggle(840, "texture_displacement_tile_repeat.svg", layer.tile_method == static_cast(0), + icon_sm, _L("Repeat"), _L("Repeat"), tile_na)) { + layer.tile_method = static_cast(0); + m_preview_params_dirty = true; + } + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(841, "menu_mirror_x.svg", layer.tile_method == static_cast(1), icon_sm, + _L("Mirrored repeat"), _L("Mirrored repeat - every other tile is flipped, so edges meet seamlessly"), + tile_na)) { + layer.tile_method = static_cast(1); + m_preview_params_dirty = true; + } + } + + // Blend, and placement on the model. + { + const float x0 = ImGui::GetCursorPosX(); + ImGui::AlignTextToFramePadding(); + ImGui::TextDisabled("%s", _u8L("Blend").c_str()); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w)); + const std::string blend_add = _u8L("Add"); + const std::string blend_subtract = _u8L("Subtract"); + const std::string blend_multiply = _u8L("Multiply"); + const std::string blend_divide = _u8L("Divide"); + const char *blend_items[] = { blend_add.c_str(), blend_subtract.c_str(), blend_multiply.c_str(), blend_divide.c_str() }; + // The first layer has nothing before it to combine with - build_texture_displacement() makes it + // add regardless - so its combo shows Add and cannot be changed. + const bool base_layer = li == 0; + int blend_mode = base_layer ? 0 : static_cast(layer.blend_mode); + ImGui::SetNextItemWidth(-(card_pad + gap_s + icon_sm)); + m_imgui->disabled_begin(base_layer); + if (scoped_combo("##blend_mode", &blend_mode, blend_items, IM_ARRAYSIZE(blend_items)) && !base_layer) { + layer.blend_mode = static_cast(blend_mode); + m_preview_params_dirty = true; + } + m_imgui->disabled_end(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + m_imgui->tooltip(base_layer ? + _u8L("The base layer has nothing beneath it to combine with, so it always adds.") : + _u8L("What this layer does where it overlaps the ones below. Add and " + "Subtract pile relief on or carve it away. Multiply and Divide scale " + "what is underneath, which turns this layer into a mask over it - " + "there, Depth acts as a strength, and 1 mm leaves white areas " + "untouched."), + wrap_w); + + ImGui::SameLine(0.f, gap_s); + if (icon_toggle(842, "texture_displacement_adjust.svg", m_adjust_texture_mode, icon_sm, _L("Adjust placement"), + _L("Adjust placement - drag the handle on the model to move the texture"))) { + if (!m_adjust_texture_mode) { + update_model_object(); // flush any pending strokes before anchoring + if (update_adjust_anchor()) + m_adjust_texture_mode = true; + else + show_error(nullptr, _u8L("Paint something with this layer first.")); + } else { + m_adjust_texture_mode = false; + m_adjust_drag_handle = AdjustHandle::None; + } + } + } + } + + // "More settings" / "Fewer settings", drawn as a link. + { + const bool expanded = m_layer_expanded[size_t(layer.slot)]; + const std::string text = expanded ? _u8L("Fewer settings") : _u8L("More settings"); + const float arrow = std::round(ImGui::GetFontSize() * 0.55f); + const ImVec2 ts = ImGui::CalcTextSize(text.c_str()); + const ImVec2 p = ImGui::GetCursorScreenPos(); + if (ImGui::InvisibleButton("##more", ImVec2(arrow + gap_s + ts.x, ts.y))) { + m_layer_expanded[size_t(layer.slot)] = !expanded; + // Placement is one of the settings being hidden, so it stops with them. + if (expanded && m_adjust_texture_mode) { + m_adjust_texture_mode = false; + m_adjust_drag_handle = AdjustHandle::None; + } + } + const ImU32 c = ImGui::GetColorU32(col_link); + const float cx = p.x + 0.5f * arrow, cy = p.y + 0.5f * ts.y, hs = 0.3f * arrow; + if (expanded) + dl->AddTriangleFilled(ImVec2(cx - hs, cy + 0.5f * hs), ImVec2(cx + hs, cy + 0.5f * hs), ImVec2(cx, cy - 0.5f * hs), c); + else + dl->AddTriangleFilled(ImVec2(cx - hs, cy - 0.5f * hs), ImVec2(cx + hs, cy - 0.5f * hs), ImVec2(cx, cy + 0.5f * hs), c); + const float tx = p.x + arrow + gap_s; + dl->AddText(ImVec2(tx, p.y), c, text.c_str()); + if (ImGui::IsItemHovered()) + dl->AddLine(ImVec2(tx, p.y + ts.y), ImVec2(tx + ts.x, p.y + ts.y), c); + } + + ImGui::EndGroup(); + ImGui::Unindent(card_pad); + const float card_max_y = ImGui::GetItemRectMax().y + card_pad; + drop_target(li, layer.slot, card_min, ImVec2(content_rx, card_max_y)); + if (layer.slot == dragged_slot) + dl->AddRectFilled(card_min, ImVec2(content_rx, card_max_y), ghost_col, rounding); + dl->ChannelsSetCurrent(0); + dl->AddRectFilled(card_min, ImVec2(content_rx, card_max_y), col_card, rounding); + dl->ChannelsMerge(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + card_pad); + } else { + // A closed layer: one outlined row - grip, chevron, thumbnail, name, depth, remove. A click + // anywhere that is not one of its buttons opens it. + const float inner = std::round(m_imgui->scaled(0.15f)); + const float row_h = frame_h + 2.f * inner; + const ImVec2 p0 = ImGui::GetCursorScreenPos(); + const float row_w = content_rx - p0.x; + if (ImGui::InvisibleButton("##row", ImVec2(row_w, row_h))) + activate_slot = layer.slot; + const bool row_hovered = ImGui::IsItemHovered(); + ImGui::SetItemAllowOverlap(); // the row's own buttons, submitted after it, still take their clicks + drop_target(li, layer.slot, p0, ImVec2(p0.x + row_w, p0.y + row_h)); + if (row_hovered) + dl->AddRectFilled(p0, ImVec2(p0.x + row_w, p0.y + row_h), col_card, rounding); + dl->AddRect(p0, ImVec2(p0.x + row_w, p0.y + row_h), col_line, rounding); + + ImGui::SetCursorScreenPos(ImVec2(p0.x + inner, p0.y + inner)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(gap_s, style.ItemSpacing.y)); + grip(layer, frame_h); + ImGui::SameLine(); + { + const ImVec2 c = ImGui::GetCursorScreenPos(); + const float aw = std::round(ImGui::GetFontSize() * 0.5f), hs = 0.3f * aw; + const float cx = c.x + 0.5f * aw, cy = c.y + 0.5f * frame_h; + dl->AddTriangleFilled(ImVec2(cx - 0.5f * hs, cy - hs), ImVec2(cx - 0.5f * hs, cy + hs), ImVec2(cx + 0.5f * hs, cy), + ImGui::GetColorU32(ImGuiCol_TextDisabled)); + ImGui::Dummy(ImVec2(aw, frame_h)); + } + ImGui::SameLine(); + const float th = std::round(frame_h * 0.9f); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 0.5f * (frame_h - th)); + if (GLTexture *thumb = get_layer_thumbnail(layer)) { + if (ImGui::ImageButton((ImTextureID) (intptr_t) thumb->get_id(), ImVec2(th, th), ImVec2(0.f, 0.f), ImVec2(1.f, 1.f), 0)) + open_picker(layer.slot); + } else if (ImGui::Button("?##thumb", ImVec2(th, th))) { + open_picker(layer.slot); + } + hover_tip(_u8L("Pick a different image for this layer. The paint, depth and tiling stay as they are.")); + ImGui::SameLine(); + + char depth_text[32]; + std::snprintf(depth_text, sizeof(depth_text), "%.3f mm", layer.depth_mm); + const std::string summary = painted ? std::string(depth_text) : _u8L("not painted"); + const float sum_w = ImGui::CalcTextSize(summary.c_str()).x; + const float right_edge = ImGui::GetWindowContentRegionMax().x - inner; + const float name_w = std::max(0.f, right_edge - ImGui::GetCursorPosX() - 2.f * gap_s - sum_w - frame_h); + ImGui::SetCursorPosY(p0.y - ImGui::GetWindowPos().y + ImGui::GetScrollY() + inner); + ImGui::AlignTextToFramePadding(); + ImGui::TextUnformatted(ellipsize(layer_name(layer), name_w).c_str()); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), right_edge - frame_h - gap_s - sum_w)); + ImGui::TextDisabled("%s", summary.c_str()); + ImGui::SameLine(); + ImGui::SetCursorPosX(right_edge - frame_h); + m_imgui->disabled_begin(busy); + if (icon_button(600 + layer.slot, "texture_displacement_cross.svg", frame_h, m_desc.at("remove_layer"), _L("Remove this layer"))) + slot_to_remove = layer.slot; + m_imgui->disabled_end(); + ImGui::PopStyleVar(); + if (layer.slot == dragged_slot) + dl->AddRectFilled(p0, ImVec2(p0.x + row_w, p0.y + row_h), ghost_col, rounding); + ImGui::SetCursorScreenPos(ImVec2(p0.x, p0.y + row_h + 0.5f * style.ItemSpacing.y)); + } + + ImGui::PopID(); + } + + // The dragged layer follows the cursor as a copy of its row, held by its grip. On the foreground draw list, so + // it stays visible over the rest of the panel and anywhere the drag wanders. + if (dragged_slot >= 0) { + const auto it = std::find_if(ordered.begin(), ordered.end(), [dragged_slot](const auto *l) { return l->slot == dragged_slot; }); + if (it != ordered.end()) { + const TextureDisplacementLayer &l = **it; + ImDrawList *fg = ImGui::GetForegroundDrawList(); + const float inner = std::round(m_imgui->scaled(0.15f)); + const float row_h = frame_h + 2.f * inner; + const float list_x = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMin().x; + const ImVec2 mouse = ImGui::GetIO().MousePos; + const ImVec2 mn(mouse.x - inner - 0.5f * grip_w, mouse.y - 0.5f * row_h); + const ImVec2 mx(mn.x + (content_rx - list_x), mn.y + row_h); + fg->AddRectFilled(ImVec2(mn.x + 2.f, mn.y + 4.f), ImVec2(mx.x + 2.f, mx.y + 4.f), IM_COL32(0, 0, 0, 70), rounding); + fg->AddRectFilled(mn, mx, dark ? IM_COL32(0x3a, 0x3a, 0x40, 245) : IM_COL32(255, 255, 255, 245), rounding); + fg->AddRect(mn, mx, ImGui::GetColorU32(orca), rounding, 0, 1.5f); + + float x = mn.x + inner; + draw_drag_icon(fg, x, mn.y + inner, grip_w, frame_h, drag_tint(255)); + x += grip_w + gap_s; + const float th = std::round(frame_h * 0.9f); + if (GLTexture *thumb = get_layer_thumbnail(l)) { + const float ty = mn.y + 0.5f * (row_h - th); + fg->AddImage((ImTextureID) (intptr_t) thumb->get_id(), ImVec2(x, ty), ImVec2(x + th, ty + th)); + } + x += th + gap_s; + + char depth_text[32]; + std::snprintf(depth_text, sizeof(depth_text), "%.3f mm", l.depth_mm); + const std::string summary = slot_painted(l.slot) ? std::string(depth_text) : _u8L("not painted"); + const float sum_w = ImGui::CalcTextSize(summary.c_str()).x; + const float text_y = mn.y + 0.5f * (row_h - ImGui::GetFontSize()); + fg->AddText(ImVec2(mx.x - inner - sum_w, text_y), ImGui::GetColorU32(ImGuiCol_TextDisabled), summary.c_str()); + const std::string name = ellipsize(layer_name(l), std::max(0.f, mx.x - inner - sum_w - gap_s - x)); + fg->AddText(ImVec2(x, text_y), ImGui::GetColorU32(ImGuiCol_Text), name.c_str()); + } + } + + if (mv != nullptr) { + const bool full = mv->texture_displacement_layers.size() >= TEXTURE_DISPLACEMENT_MAX_LAYERS; + const std::string label = full ? Slic3r::format(_u8L("All %1% layers used"), TEXTURE_DISPLACEMENT_MAX_LAYERS) : + "+ " + _u8L("Add layer"); + m_imgui->disabled_begin(busy || full); + if (ImGui::Button((label + "##add_layer").c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0.f))) + add_texture_layer(); + m_imgui->disabled_end(); + } + + // ---- Mesh preparation: Pro only. Standard pins all of it and runs it from Bake. ---- + if (pro_mode()) { + ImGui::Separator(); + heading(_L("Subdivision")); + + if (ImGui::Checkbox(_u8L("Only painted area (adaptive)").c_str(), &m_subdivide_adaptive)) { + if (m_subdivide_editing) + rebuild_subdivide_preview(); // switch the wireframe between the uniform and adaptive result + m_parent.set_as_dirty(); + } + hover_tip(_u8L("Adds triangles only where you painted, instead of everywhere. On a large part with a small " + "decal that is the difference between thousands of triangles and millions, and your paint " + "survives the refinement.")); + + if (m_subdivide_adaptive) { + if (m_subdivide_target_mm <= 0.f && mv != nullptr) { + // Seed the target at about half the mesh's mean edge length, so the default already adds a + // useful amount of detail rather than landing on "no change". + const indexed_triangle_set &its = mv->mesh().its; + double sum = 0.0; + size_t cnt = 0; + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) { + sum += (its.vertices[tri[i]] - its.vertices[tri[(i + 1) % 3]]).norm(); + ++cnt; + } + m_subdivide_target_mm = cnt > 0 ? std::clamp(float(sum / double(cnt)) * 0.5f, 0.001f, 20.f) : 1.f; + } + // Live preview: rebuild the wireframe as the slider moves, not only on release. The rebuild is + // bounded by the painted region, so it stays responsive. + const auto preview_live = [this]() { + if (m_subdivide_editing) + rebuild_subdivide_preview(); + m_parent.set_as_dirty(); + }; + + if (ImGui::Checkbox(_u8L("Follow texture detail").c_str(), &m_subdivide_feature)) + preview_live(); + hover_tip(_u8L("Spends the triangles where the texture actually bends - packed along ridges and edges, " + "sparse over flat ground - instead of spreading them evenly. The same detail for fewer " + "triangles on most textures.")); + + // The edge-length target is a baseline in both modes. In feature mode it is what guarantees the + // curvature test can actually see the texture: left too coarse, a big triangle over a fine + // pattern can sample four points that all happen to land at similar heights, report no error, + // and stall before refinement ever starts. + if (float_row("##subdiv_target", m_subdivide_feature ? _L("Max edge") : _L("Target edge"), &m_subdivide_target_mm, + 0.001f, 20.f, "%.3f mm", true, 0.f)) + preview_live(); + hover_tip(m_subdivide_feature ? + _u8L("No triangle in the painted area stays larger than this, even where the texture " + "is flat. Keep it near the size of the smallest feature you want to come out.") : + _u8L("Triangles in the painted area are split until none is larger than this. Smaller " + "means finer detail and, fast, a lot more triangles.")); + + if (m_subdivide_feature) { + if (float_row("##subdiv_detail", _L("Detail"), &m_subdivide_detail_mm, 0.001f, 1.f, "%.3f mm", true, 0.f)) + preview_live(); + hover_tip(_u8L("How far the mesh may sit from the shape the texture describes, in millimetres. " + "Smaller follows fine detail and costs triangles; larger only chases the big " + "features.")); + if (float_row("##subdiv_min", _L("Min edge"), &m_subdivide_min_edge_mm, 0.001f, 20.f, "%.3f mm", true, 0.f)) + preview_live(); + hover_tip(_u8L("A floor on triangle size, so a sharp step in the texture cannot be chased " + "forever. Lower it for finer relief, raise it if the count runs away at hard " + "edges.")); + } + + // Applies in both adaptive sub-modes: it is about the step the bake puts at the paint's edge, which + // exists whether or not "Follow texture detail" is on. 0 turns the band off. + if (float_row("##subdiv_border", _L("Edge detail"), &m_subdivide_border_mm, 0.f, 5.f, "%.3f mm", false, 0.f)) + preview_live(); + hover_tip(_u8L("Triangle size along the outline of the painted area, where the relief drops back to the " + "bare surface. Lower it if that rim looks jagged; it only costs triangles along the " + "outline. 0 turns it off.")); + + // Only worth showing when a layer is actually colouring: with no colour there is no boundary for it + // to refine and the control would do nothing whatever it is set to. + if (mv != nullptr && any_layer_colors(*mv)) { + if (float_row("##subdiv_color", _L("Colour detail"), &m_subdivide_color_mm, 0.f, 5.f, "%.3f mm", false, 0.f)) + preview_live(); + hover_tip(_u8L("Triangle size where two colours meet. Each triangle prints in one filament, so a " + "colour edge can only be as sharp as the triangles along it - and nothing else " + "refines there, since the surface is flat across a change of colour. 0 turns it off.")); + } + + ImGui::TextDisabled("%s", _u8L("Triangle budget: set with Triangles, below.").c_str()); + if (m_subdivide_editing && m_subdivide_preview_tris > 0) + m_imgui->text(Slic3r::format(_u8L("Preview: %1% triangles"), m_subdivide_preview_tris)); + } else { + if (int_row("##subdiv_steps", _L("Steps"), &m_subdivide_count, 0, 5, "%d", 0.f)) { + if (m_subdivide_editing) + rebuild_subdivide_preview(); // a count of 0 clears the preview, it doesn't compute one + m_parent.set_as_dirty(); + } + hover_tip(_u8L("Splits every triangle of the model into four, this many times over. Each step " + "quadruples the count - 3 turns 100 k triangles into 6.4 M - so prefer refining " + "only the painted area unless you need the whole model finer.")); + } + + { + // Subdivide is a no-op when there is nothing to commit: 0 uniform passes, or an adaptive target that + // is not set. + const bool subdivide_ready = m_subdivide_adaptive ? (m_subdivide_target_mm > 0.f) : (m_subdivide_count >= 1); + const float half = std::floor((ImGui::GetContentRegionAvail().x - style.ItemSpacing.x) * 0.5f); + m_imgui->disabled_begin(busy); + if (ImGui::Button((m_subdivide_editing ? _u8L("Hide preview") : _u8L("Preview subdivision")).c_str(), ImVec2(half, 0.f))) { + if (m_subdivide_editing) { + m_subdivide_editing = false; + m_subdivide_preview_tris = -1; + m_subdivide_preview_glmodel.reset(); + } else { + m_subdivide_editing = true; + rebuild_subdivide_preview(); + } + m_parent.set_as_dirty(); + } + m_imgui->disabled_end(); + hover_tip(_u8L("Shows what the refinement would produce as a wireframe, without touching the model.")); + ImGui::SameLine(); + m_imgui->disabled_begin(!subdivide_ready || busy); + if (ImGui::Button(_u8L("Subdivide").c_str(), ImVec2(half, 0.f))) { + if (m_subdivide_adaptive) { + subdivide_model_adaptive(); // refines only the painted area, carrying the paint forward + } else { + subdivide_model(); // commits m_subdivide_count passes (takes its own snapshot) + // Back to 0 rather than staying at the count just applied: the mesh is now up to 4^N times + // denser, so re-previewing the same N passes on top of it is both pointless and by far the + // slowest thing this panel does. + m_subdivide_count = 0; + } + if (m_subdivide_editing) + rebuild_subdivide_preview(); + m_parent.set_as_dirty(); + } + m_imgui->disabled_end(); + hover_tip(m_subdivide_adaptive ? + _u8L("Refines the painted area to the target edge length and carries your paint onto " + "the finer mesh. The rest of the model is left as it is.") : + _u8L("Replaces the model's geometry with the subdivided mesh and clears any not-yet-baked " + "paint on it (already-baked relief is unaffected).")); + } + + // Remesh: even out uneven triangle sizes (CGAL isotropic remeshing). + ImGui::Separator(); + heading(_L("Remeshing")); + if (m_remesh_target_edge_mm <= 0.f && mv != nullptr) { + // Seed the target with the model's current mean edge length, so the default is a sensible "make + // everything about the size it already averages". + const indexed_triangle_set &its = mv->mesh().its; + double sum = 0.0; + size_t cnt = 0; + for (const stl_triangle_vertex_indices &tri : its.indices) + for (int i = 0; i < 3; ++i) { + sum += (its.vertices[tri[i]] - its.vertices[tri[(i + 1) % 3]]).norm(); + ++cnt; + } + m_remesh_target_edge_mm = cnt > 0 ? std::clamp(float(sum / double(cnt)), 0.1f, 20.f) : 1.f; + } + float_row("##remesh_edge", _L("Target edge"), &m_remesh_target_edge_mm, 0.1f, 20.f, "%.2f mm", true, 0.f); + hover_tip(_u8L("Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an " + "even mesh; this is what makes one out of an uneven import.")); + + ImGui::Checkbox((_u8L("Keep sharp edges") + "##remesh_sharp").c_str(), &m_remesh_keep_sharp_edges); + hover_tip(_u8L("Holds hard edges and open borders in place while the rest is remeshed. Without it " + "the remesher slides vertices along the surface and rounds every crisp edge off - " + "a cube comes back with wobbly edges.")); + ImGui::SameLine(); + m_imgui->disabled_begin(!m_remesh_keep_sharp_edges); + ImGui::SetNextItemWidth(-1.f); + ImGui::SliderFloat("##remesh_sharp_angle", &m_remesh_sharp_angle_deg, 5.f, 90.f, "%.0f°", ImGuiSliderFlags_AlwaysClamp); + m_imgui->disabled_end(); + hover_tip(_u8L("How sharp a fold has to be, in degrees, before the remesher treats it as an edge worth " + "keeping. Lower protects more of the model's shape; higher rebuilds more of it evenly.")); + + m_imgui->disabled_begin(mv == nullptr || busy); + if (ImGui::Button(_u8L("Remesh").c_str())) + remesh_model(); + m_imgui->disabled_end(); + hover_tip(_u8L("Rebuilds the whole model with triangles close to this edge length - splitting the big " + "ones and merging the small ones - so displacement has an even density to work with. " + "Replaces the geometry; your paint is carried onto the new triangles spatially, so it " + "survives (already-baked relief is kept too).")); + + // Settings for the whole stack rather than one layer. Standard mode pins them instead of showing them. + if (mv != nullptr) { + TextureDisplacementOptions &opts = mv->texture_displacement_options; + ImGui::Separator(); + heading(_L("Result")); + + m_preview_params_dirty |= ImGui::Checkbox(_u8L("Displace up to the border").c_str(), &opts.displace_border); + hover_tip(_u8L("Lets the relief run right to the edge of the painted area. Turn it off to hold that " + "outer ring flat, which keeps the displacement strictly inside your paint but flattens " + "the pattern at the border.")); + + m_preview_params_dirty |= ImGui::Checkbox(_u8L("Smooth result").c_str(), &opts.smooth_enabled); + hover_tip(_u8L("Smooths the geometry after the texture has been applied, to take the hard steps out of a " + "low-resolution image. Only what the displacement moved is touched. The Smoothing slider " + "on a layer is a different thing: it blurs the image before it is used.")); + if (opts.smooth_enabled) { + float percent = opts.smooth_strength * 100.f; + if (float_row("##dispsmooth", _L("Strength"), &percent, 1.f, 100.f, "%.0f %%", false, 0.f)) { + opts.smooth_strength = std::clamp(percent / 100.f, 0.01f, 1.f); + m_preview_params_dirty = true; + } + hover_tip(_u8L("How far each pass pulls a vertex towards its neighbours. High values round the " + "relief off quickly; low values need more passes but keep more of the detail.")); + if (int_row("##dispsmoothit", _L("Passes"), &opts.smooth_iterations, 1, 10, "%d", 0.f)) + m_preview_params_dirty = true; + hover_tip(_u8L("How many smoothing passes to run. More passes spread the smoothing further across " + "the surface; Strength decides how much each one moves.")); + + m_preview_params_dirty |= ImGui::Checkbox(_u8L("Ignore outer ring").c_str(), &opts.smooth_skip_border); + hover_tip(_u8L("Keeps the outer ring of the painted area out of the smoothing. Its neighbours " + "outside the paint never move, so smoothing it drags the relief down and leaves the " + "pattern half-melted at the border.")); + + // The settings above ride along with Preview/Bake. This button is for geometry that has *already* + // been baked, where there is no displacement left to fold the smoothing into. + if (m_imgui->button(_u8L("Smooth baked mesh now"))) + smooth_model(); + hover_tip(_u8L("Applies the smoothing above to the model itself, right now, within the painted area. " + "For relief that is already baked in - anything not yet baked is smoothed by Bake.")); + } + } + } + + // Shown in both modes. The pipeline switch, the two v2 experiments and the stage debugger are + // developer controls: kept, but off the panel unless this is flipped. + static constexpr bool SHOW_PIPELINE_DEV_CONTROLS = false; + if (mv != nullptr) { + TextureDisplacementOptions &opts = mv->texture_displacement_options; + ImGui::Separator(); + if (SHOW_PIPELINE_DEV_CONTROLS) { + // The classic path is the opt-in: the one-run pipeline is the default, and its resolution + // control lives in the footer next to Bake (see below). + bool classic = !opts.pipeline_v2; + if (ImGui::Checkbox(_u8L("Experimental: classic bake pipeline").c_str(), &classic)) { + opts.pipeline_v2 = !classic; + m_preview_params_dirty = true; + } + hover_tip(_u8L("Bake by moving the vertices the mesh already has, after preparing it (remesh, " + "adaptive subdivision, and a cut along sharp steps in the texture). Keeps the " + "topology, which is what colours need. The default pipeline instead refines, " + "cleans up sliver triangles, displaces and simplifies in one run; nothing needs " + "preparing first, but it does not produce colours yet.")); + } + if (opts.pipeline_v2) { + // -1 is "auto": the row shows the recommendation, greyed; editing it makes it a fixed value. + const bool auto_budget = opts.v2_max_triangles_k < 0; + int shown_k = auto_budget ? v2_recommendation(*mv).budget_k : opts.v2_max_triangles_k; + m_imgui->disabled_begin(auto_budget); + if (int_row("##v2budget", _L("Budget"), &shown_k, 0, 4000, auto_budget ? "%d k (auto)" : "%d k", 0.f)) { + opts.v2_max_triangles_k = shown_k; + m_preview_params_dirty = true; + } + m_imgui->disabled_end(); + hover_tip(_u8L("How many thousand triangles this bake may spend on the area you painted. " + "Relief already baked into the rest of the model is kept on top of it, so a " + "second bake somewhere else gets the same budget as the first. Raise it if the " + "warning below Resolution says the detail will not fit; 0 keeps every triangle " + "the refinement produced, however many that is.")); + } + if (SHOW_PIPELINE_DEV_CONTROLS && opts.pipeline_v2) { + // Keeping the relief above the plate is not a checkbox: it is unconditional, in both pipelines + // (see build_texture_displacement()). + m_preview_params_dirty |= ImGui::Checkbox(_u8L("Align mesh to texture edges").c_str(), &opts.v2_relocate); + hover_tip(_u8L("Slide vertices sideways onto the edges in the texture before displacing them. " + "Displacement can only move vertices up and down, so without this a sharp step " + "in the image lands wherever the triangles happen to be and comes out as a " + "staircase. Moving the vertices onto the step first gives a straight wall at the " + "same triangle count.")); + m_preview_params_dirty |= ImGui::Checkbox(_u8L("Clean up slivers").c_str(), &opts.v2_regularize); + hover_tip(_u8L("Collapse the thin triangles refinement inherits from the model's own " + "tessellation, before displacement samples them. A sliver's three corners " + "land on three unrelated parts of the texture, which is what makes the " + "relief look jagged.")); + } + // Below both pipelines' own settings, because it replays whichever of them is selected. + if (SHOW_PIPELINE_DEV_CONTROLS) + render_debug_stage_panel(mv); + } + + // Content height, for next frame's body size. The cursor position is scroll-compensated, so this is the + // height of everything above, whether or not it is scrolled. + m_panel_body_h = ImGui::GetCursorPosY() - style.ItemSpacing.y; + ImGui::EndChild(); + ImGui::PopStyleColor(5); + ImGui::PopStyleVar(2); + + // The layer-list changes deferred from the loop above. + if (slot_to_remove >= 0) + remove_texture_layer(slot_to_remove); + else if (move_slot >= 0) + move_texture_layer(move_slot, move_to); + else if (activate_slot >= 0) + set_active_layer(activate_slot); + // Retexturing a layer makes it the one being painted, too. + if (m_picker_open_request && m_picker_slot >= 0) + set_active_layer(m_picker_slot); + + // In this window's scope, where the popup's open request and the popup itself share one ID stack. + { + const ImVec2 win_min = ImGui::GetWindowPos(); + const ImVec2 win_sz = ImGui::GetWindowSize(); + render_texture_library_popup(win_min, ImVec2(win_min.x + win_sz.x, win_min.y + win_sz.y)); + } + + // ImGui sliders report "changed" continuously on every frame while being dragged, not just once on + // release - rebuilding the preview (a real CPU mesh recompute) on every one of those frames is what made + // dragging these sliders feel slow. Only rebuild once the mouse button that's driving the drag is + // released, i.e. once per edit instead of dozens of times per drag. + // The feature-adaptive subdivision follows the *displaced* surface (it samples depth * texture), so depth / + // tile-size / rotation / invert all change where it puts triangles. The heavy displacement preview below + // only rebuilds on release, which made the subdivide wireframe look like it ignored those edits - so + // rebuild it live here (during the drag), the same cadence its own sliders use. Cheap: it is bounded by + // the painted region. + if (m_preview_params_dirty && m_subdivide_editing && m_subdivide_adaptive && m_subdivide_feature) + rebuild_subdivide_preview(); + if (m_preview_params_dirty && (m_auto_update || !ImGui::IsMouseDown(ImGuiMouseButton_Left))) { + rebuild_preview(); + // Same edits (tile size, rotation, offset, a new texture) are what the projector window draws, so it + // refreshes on the same one-per-edit cadence. No-op while it is closed. + update_projector(); + m_preview_params_dirty = false; + } + + // ---- Footer: pinned below the body, so Bake never scrolls away. ---- + const float footer_top = ImGui::GetCursorScreenPos().y; + ImGui::Separator(); + { + const float x0 = ImGui::GetCursorPosX(); + const int base_k = mv != nullptr ? int((mv->mesh().facets_count() + 500) / 1000) : 0; + const bool v2 = mv != nullptr && mv->texture_displacement_options.pipeline_v2; + + // The triangle budget is the one subdivision control Standard mode keeps: its right value depends on + // the part rather than on the recipe (a big model, or a fine texture, simply needs more of them), and + // raising or lowering it is safe without understanding anything else. Pro's Subdivide uses it too. + ImGui::AlignTextToFramePadding(); + if (v2) { + // The one control the default pipeline needs: the edge length its refinement targets, which + // decides how much of the texture the mesh can carry. About eight texels per edge is where + // fine detail (mortar joints, knurl ridges) stops being lost between vertices. + TextureDisplacementOptions &opts = mv->texture_displacement_options; + const V2Resolution &rec = v2_recommendation(*mv); + m_imgui->text(_L("Resolution")); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w)); + // Auto: the edge (and the budget) follow the texture and the model. Off: the slider holds + // a fixed value, seeded with the recommendation so it starts from something sensible. + bool auto_res = opts.v2_refine_mm <= 0.f; + m_imgui->disabled_begin(busy); + if (ImGui::Checkbox("##v2auto", &auto_res)) { + if (auto_res) { + opts.v2_refine_mm = 0.f; + opts.v2_max_triangles_k = -1; + } else { + opts.v2_refine_mm = rec.edge_mm > 0.f ? rec.edge_mm : 0.3f; + opts.v2_max_triangles_k = rec.budget_k > 0 ? rec.budget_k : 750; + } + m_preview_params_dirty = true; + m_parent.set_as_dirty(); + } + m_imgui->disabled_end(); + hover_tip(_u8L("On: the resolution follows the size of the model and the budget is left at its " + "default. Untick to set both yourself - worth doing for a texture much finer or " + "much coarser than the part it sits on.")); + ImGui::SameLine(); + ImGui::SetNextItemWidth(x0 + panel_w - ImGui::GetCursorPosX()); + float shown = auto_res ? rec.edge_mm : opts.v2_refine_mm; + m_imgui->disabled_begin(busy || auto_res); + if (ImGui::SliderFloat("##v2edge", &shown, 0.02f, 2.f, auto_res ? "%.2f mm (auto)" : "%.2f mm", + ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic)) { + opts.v2_refine_mm = shown; + m_preview_params_dirty = true; + m_parent.set_as_dirty(); + } + m_imgui->disabled_end(); + if (auto_res && rec.edge_mm > 0.f) + hover_tip(Slic3r::format(_u8L("Chosen from the size of the model: %1$.2f mm triangles, " + "budget %2% k. Untick Auto to set them yourself."), + rec.edge_mm, rec.budget_k)); + else + hover_tip(_u8L("How fine the mesh is made under the paint, in millimetres. It has to be " + "smaller than the detail you want out of the texture - a 0.5 mm groove needs " + "triangles well under 0.5 mm. Smaller costs triangles fast: halving it needs " + "four times as many, and once they no longer fit the budget the bake simplifies " + "back down and the detail goes with it.")); + + // What this resolution costs over what is painted, against what the budget allows. Refining + // past the budget is not an error - the bake simplifies back down to it - but the result + // then carries less of the texture than the resolution asks for, and the only sign of that + // used to be a mesh that came out coarser than expected. Shown before the bake, so the + // answer is to change a number rather than to wait out a bake and redo it. + const float edge_now = auto_res ? rec.edge_mm : opts.v2_refine_mm; + const int budget_k = opts.v2_max_triangles_k < 0 ? rec.budget_k : opts.v2_max_triangles_k; + const size_t budget = size_t(std::max(0, budget_k)) * 1000; + const size_t needed = estimated_refined_triangles(*mv, edge_now); + // Only when it is clearly over: the estimate runs about 3% high where it matters and up to + // a third high at coarse resolutions, where the mesh's own triangles are already near the + // target, and a warning about a bake that would have fitted is worse than none. + if (budget > 0 && needed > budget * 5 / 4) { + // Thousands under a million: a 119 k budget shown as "0.1 M" says nothing. + const auto count = [](size_t n) { + return n >= 1000000 ? Slic3r::format("%1$.1f M", double(n) / 1000000.) : + Slic3r::format("%1% k", (n + 500) / 1000); + }; + // Wrapped to the panel, like the note under the buttons: unwrapped text runs past the + // panel's edge and takes the window's width with it. + ImGui::PushTextWrapPos(x0 + panel_w); + m_imgui->warning_text(Slic3r::format(_u8L("Needs about %1% triangles, budget %2% - the bake " + "will simplify back down and lose detail."), + count(needed), count(budget))); + ImGui::PopTextWrapPos(); + } + } else { + m_imgui->text(_L("Triangles")); + ImGui::SameLine(); + ImGui::SetCursorPosX(std::max(ImGui::GetCursorPosX(), x0 + label_w)); + ImGui::SetNextItemWidth(x0 + panel_w - ImGui::GetCursorPosX()); + m_imgui->disabled_begin(busy); + if (ImGui::SliderInt("##subdivbudget", &m_subdivide_budget_k, 10, 2000, "+%d k", + ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic)) { + if (m_subdivide_editing) + rebuild_subdivide_preview(); + m_parent.set_as_dirty(); + } + m_imgui->disabled_end(); + hover_tip(_u8L("How many thousand triangles the refinement may add to the model. The triangle " + "that fits worst is always split first, so even a run that spends the lot has " + "spent it where it shows most. Raise it if the relief still looks coarse.")); + } + + const float button_h = std::round(frame_h * 1.25f); + const float third = std::floor((panel_w - style.ItemSpacing.x) / 3.f); + if (busy) { + if (ImGui::Button((_u8L("Stop") + "##stop").c_str(), ImVec2(third, button_h))) + wxGetApp().plater()->get_ui_job_worker().cancel_all(); + hover_tip(_u8L("Stops the bake. Whatever it had already finished stays on the model, and can be undone.")); + } else { + if (ImGui::Button((_u8L("Close") + "##close").c_str(), ImVec2(third, button_h))) + m_parent.reset_all_gizmos(); + hover_tip(_u8L("Closes the tool without baking. Your paint, layers and settings stay with the model.")); + } + + ImGui::SameLine(); + const bool can_bake = !busy && mv != nullptr && mv->is_texture_displacement_painted(); + const std::string bake_label = m_prepare_in_progress ? _u8L("Preparing...") : + m_bake_in_progress ? _u8L("Baking...") : + into_u8(m_desc.at("bake")); + ImGui::PushStyleColor(ImGuiCol_Button, orca); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGuiWrapper::COL_ORCA_HOVER); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, orca); + ImGui::PushStyleColor(ImGuiCol_Border, orca); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f)); + m_imgui->push_bold_font(); + m_imgui->disabled_begin(!can_bake); + if (ImGui::Button((bake_label + "##bake").c_str(), ImVec2(x0 + panel_w - ImGui::GetCursorPosX(), button_h))) { + // Standard mode's Bake is the whole pipeline (remesh -> refine -> displace); Pro's is only the + // displacement, because there the user has already prepared the mesh with the controls above. + if (pro_mode()) + bake(); + else + bake_standard(); + } + m_imgui->disabled_end(); + m_imgui->pop_bold_font(); + ImGui::PopStyleColor(5); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) + m_imgui->tooltip(mv != nullptr && !mv->is_texture_displacement_painted() ? + (m_seam_edit_mode ? _u8L("Nothing is painted yet. The UV editor's seam tool is on, so " + "strokes on the model mark seams instead of painting - turn " + "it off in the pane to paint.") : + _u8L("Nothing is painted yet.")) : + pro_mode() ? + _u8L("Turn the painted height maps into real geometry, by moving the vertices that are " + "already there. Use Subdivide first if the mesh is too coarse to show the detail.") : + _u8L("Turn the painted height maps into real geometry. The mesh is remeshed to an even " + "density and refined where the texture bends first, so the detail has vertices to " + "land on - all in one step."), + wrap_w); + + // What Bake will produce, and which layers it will skip. + if (mv != nullptr) { + const std::string base_count = base_k > 0 ? Slic3r::format(_u8L("%1% k"), base_k) : + std::to_string(mv->mesh().facets_count()); + std::string note = v2 ? Slic3r::format(_u8L("Model: %1% triangles - the bake refines to the resolution above, up to its budget"), base_count) : + pro_mode() ? Slic3r::format(_u8L("Bake moves existing vertices - the model stays at %1% triangles"), base_count) : + Slic3r::format(_u8L("Bake result up to ~%1% k triangles"), base_k + m_subdivide_budget_k); + if (mv->is_texture_displacement_painted()) { + std::vector skipped; + for (const TextureDisplacementLayer &l : mv->texture_displacement_layers) + if (!slot_painted(l.slot)) + skipped.push_back(layer_name(l)); + if (skipped.size() > 2) + note += ", " + Slic3r::format(_u8L("%1% layers not painted, skipped"), skipped.size()); + else if (!skipped.empty()) + note += ", " + Slic3r::format(_u8L("%1% not painted, skipped"), + skipped.size() == 2 ? skipped[0] + ", " + skipped[1] : skipped[0]); + } + ImGui::PushTextWrapPos(x0 + panel_w); + ImGui::TextDisabled("%s", note.c_str()); + ImGui::PopTextWrapPos(); + } + } + m_panel_footer_h = ImGui::GetCursorScreenPos().y - footer_top; + + GizmoImguiEnd(); + ImGuiWrapper::pop_toolbar_style(); + + // Drawn last, over everything, via the foreground draw list: the +/- add-remove sign next to the 3D + // cursor. Still inside the gizmo's ImGui frame here, which is what render_paint_cursor_hint() needs. + render_paint_cursor_hint(); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp b/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp new file mode 100644 index 0000000000..705408b153 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp @@ -0,0 +1,946 @@ +#ifndef slic3r_GLGizmoTextureDisplacement_hpp_ +#define slic3r_GLGizmoTextureDisplacement_hpp_ + +#include "GLGizmoPainterBase.hpp" +#include "libslic3r/TextureBake/TextureBakeDebug.hpp" +#include "libslic3r/TextureDisplacement.hpp" +#include "slic3r/GUI/GLModel.hpp" +#include "slic3r/GUI/GLTexture.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/IconManager.hpp" +#include "slic3r/GUI/TextureLibrary.hpp" + +#include +#include +#include +#include +#include + +namespace Slic3r::GUI { + +class TextureProjectorFrame; + +// Paint-style gizmo that assigns one or more texture-displacement "layers" (see +// libslic3r/TextureDisplacement.hpp) to painted areas of a model, and can bake the result into +// real mesh geometry. See the project plan for the overall architecture; in short: +// - each layer owns its own independent paint mask (ModelVolume::texture_displacement_facets), +// reusing the same TriangleSelector/FacetsAnnotation machinery as every other paint gizmo - +// only one layer is "active" (paintable) at a time, selected in the panel below; +// - "Bake" runs build_texture_displacement() in a background job and commits the result exactly +// like the Emboss/SVG "project on surface" gizmo does. +class GLGizmoTextureDisplacement : public GLGizmoPainterBase +{ +public: + GLGizmoTextureDisplacement(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + + // The whole of mesh preparation - remesh, carry the paint across, refine where the texture bends - + // as one pure function over plain data: no ModelVolume, no Model, no GUI, no undo. That is what lets + // TextureDisplacementPrepareJob run it on the job worker instead of on the UI thread, where CGAL's + // remesher and a several-hundred-thousand-triangle refinement together freeze the window for tens + // of seconds with nothing to look at and no way to cancel. + // + // `progress` is called with 0..100 and aborts the run when it returns false; an aborted run reports + // an empty result. An empty result is also how "nothing needed doing" is reported - see + // TextureDisplacementPrepareResult. + static TextureDisplacementPrepareResult prepare_mesh(const indexed_triangle_set &base, + const TextureDisplacementFacetsData &masks, + const std::vector &layers, + const TextureDisplacementPrepareParams ¶ms, + const std::vector &palette, + const DisplacementProgressFn &progress, + // Optional step capture: receives the mesh + // after the remesh and after the refinement, + // so a debug run can show the whole recipe. + BakeStageRecorder *debug = nullptr); + // The volume's eight texture-displacement masks, gathered into the array every pure function here + // (and every job input) takes. + static TextureDisplacementFacetsData facets_data_of(const ModelVolume &mv); + + using PaletteEntry = PrintableColor; + + // The printable palette: the loaded filaments (clamped to the sixteen mmu_segmentation_facets can + // address), plus - when `mixing` - every pair of them at evenly spaced ratios. + // + // Mixes are averaged in **CIELAB**, not RGB and not subtractively: two filaments interleaved too + // finely to resolve are averaged by the eye, which is what a perceptual space models. Yellow and + // blue banded together read as a desaturated grey-green, and that is what the preview must promise + // - blending them subtractively would show a green the printer cannot produce this way. + // + // How many ratios depends on how many filaments there are, so the palette stays bounded: the + // quantizer's lookup cube costs one DeltaE00 per cell per entry to fill, and with sixteen + // filaments there are already plenty of colours without mixing any of them. + static std::vector make_palette(const std::vector &filaments, bool mixing); + + // Maps an image colour to the closest entry of `palette`, perceptually (CIEDE2000 over CIELAB - a + // plain RGB distance picks visibly wrong filaments, most obviously between a saturated colour and + // a grey of similar brightness). + // + // Precomputed into a lookup cube rather than matched per call: the subdivision's colour criterion + // samples up to seven points per triangle and re-samples both children of every split, so a live + // match would dominate the refinement. The returned closure owns the cube, so it is safe to hand + // to a worker thread and outlives the palette it was built from. + static ColorQuantizeFn make_palette_quantizer(const std::vector &palette); + + // Turns a palette index plus a position into the filament to print there, interleaving the two + // filaments of a mixed entry per `mode`. `layer_height` sizes the Z bands; `cell_mm` the dither + // cells. See ColorResolveFn for why this is separate from the quantizer. + static ColorResolveFn make_mix_resolver(const std::vector &palette, ColorMixMode mode, + float layer_height, float cell_mm); + + // Everything the jobs need to colour with, for the current volume: palette, mix mode, layer + // height, despeckle. Empty when no layer is actually colouring. + TextureColorSettings color_settings_for(const ModelVolume &mv); + + // The printable palette for the current filaments and mixing setting, rebuilt only when either + // actually changes - see the definition for why that caching is not optional. + const std::vector &cached_palette(); + std::vector m_palette_cache; + std::vector m_palette_filaments; + bool m_palette_mixing = false; + ColorQuantizeFn m_palette_quantizer; + + // The loaded filaments, clamped to the sixteen mmu_segmentation_facets can address. + static std::vector filament_palette(); + // The print's layer height, which sizes ColorMixMode::ZBands. Falls back to 0.2 mm if it cannot be + // read - a wrong band size is a cosmetic error, not a reason to refuse to colour anything. + static float print_layer_height(); + // The Z band height, in mm. One print layer is the ideal, but the interleave is realised per + // *facet*: a band thinner than the mesh can resolve does not dither, it beats against the triangle + // grid and comes out as broad horizontal stripes - and since MMU segmentation reads facet colour, + // it does so in the print too, not only on screen. The refinement edge is chosen from the model's + // diagonal and knows nothing about the layer height, so the band is rounded up to a whole number of + // layers at least two facet rows tall: still exact on the printer, and representable by the mesh + // that has to carry it. Used by both the bake settings and the preview shader, so the two agree. + float color_band_mm(const ModelVolume &mv); + + // The Normal preview's triangles, grouped by the filament they will print in. Colour is per facet + // and there are at most sixteen filaments, so the mesh is uploaded once with its index buffer + // sorted by colour and drawn as one GLModel::render(range) per group - which needs no per-vertex + // colour attribute, and so no change to GLModel's vertex layouts. + // + // The *index buffer* is what gets reordered, never m_preview_its: the paint overlay and the + // wireframe index into that by the volume's own triangle numbering (the bake is + // topology-preserving), and permuting it would silently misplace both. + struct PreviewColorRun + { + std::pair range; // into the GLModel's index buffer, in elements + ColorRGBA color; + }; + std::vector m_preview_color_runs; + // True if any of the volume's layers would actually colour something: colour turned on, and a + // texture that has colour to give. What decides whether a palette is captured into a job at all, + // and so whether the colour criterion and the mmu write ever run. + static bool any_layer_colors(const ModelVolume &mv); + + void render_painter_gizmo() override; + + // Intercepts mouse input while "Adjust Texture" mode is on (dragging the on-canvas offset/ + // rotation handles instead of painting); otherwise forwards to the normal painting handling. + bool on_mouse(const wxMouseEvent &mouse_event) override; + +protected: + void on_render_input_window(float x, float y, float bottom_limit) override; + std::string on_get_name() const override; + + wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override; + + std::string get_gizmo_entering_text() const override { return _u8L("Entering Texture displacement painting"); } + std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Texture displacement painting"); } + std::string get_action_snapshot_name() const override { return _u8L("Texture displacement editing"); } + + // The panel's Paint / Erase toggle swaps what the two buttons do, so the right button always does the + // opposite of the left. Shift still erases in both modes (GLGizmoPainterBase::gizmo_event()). + EnforcerBlockerType get_left_button_state_type() const override { return m_erase_mode ? EnforcerBlockerType::NONE : EnforcerBlockerType::ENFORCER; } + EnforcerBlockerType get_right_button_state_type() const override { return m_erase_mode ? EnforcerBlockerType::ENFORCER : EnforcerBlockerType::NONE; } + +private: + bool on_init() override; + void update_model_object() override; + void update_from_model_object(bool first_update) override; + void on_opening() override {} + void on_shutdown() override; + PainterGizmoType get_painter_type() const override; + + // Phase 1 restricts the texture layer list to the first model-part volume of the current + // object (the common single-volume case); multi-part objects only get texture layers on + // their first part until a later phase. Returns nullptr if there is no model part. + ModelVolume* texture_volume(); + const ModelVolume* texture_volume() const; + + void add_texture_layer(); + void remove_texture_layer(int slot); + // Moves the layer in `slot` to position `to_index` of the slot-ordered stack (an insertion index, + // 0..layer count), which is the order blend modes apply in. Layers keep their data; what moves is + // the slot each one occupies, so their paint masks move with them on every model part. + void move_texture_layer(int slot, int to_index); + // Exchanges everything two slots hold - layer definition, paint masks, panel caches. No snapshot and + // no selector reload; move_texture_layer() does both once around a run of these. + void swap_layer_slots(int slot_a, int slot_b); + void set_active_layer(int slot); // flushes the previous layer's edits, then reloads selectors + // `own_snapshot` false when the caller has already taken an undo step that is meant to cover the + // displacement too - see bake_standard(). + void bake(bool own_snapshot = true); + + // Standard (0) vs Pro (1), driven by the two-position slider in the panel header. + // + // Pro is the panel as it has always been: every geometry-preparation control is visible and the + // user drives Remesh, Subdivide and Bake themselves, in whatever order they like. Standard hides + // all of that, pins it to one fixed recipe, and folds it into the Bake button - paint, press Bake, + // done - so the common case does not require knowing that a height map can only move vertices that + // already exist. Nothing about Pro changed when Standard was added. + int m_panel_mode = 0; + bool pro_mode() const { return m_panel_mode != 0; } + // Pins every control Standard mode hides to its preset value. Idempotent, called each frame while + // Standard is active so what Preview shows is always what Bake will do. Returns true if it actually + // changed something, so the caller can invalidate the preview. + bool apply_standard_mode_presets(ModelVolume *mv); + // Standard mode's Bake: remesh to an even density, refine where the texture bends, then displace. + // The order matters and is the whole reason this is one button - a height map can only move + // existing vertices, so the mesh has to be prepared first, and remeshing after painting would drop + // the paint if it were not carried across (see prepare_mesh()). + void bake_standard(); + + // Queues one prepare_mesh() run on the job worker and commits its result when it lands. Every + // mesh-preparation button goes through here - Pro's Remesh, Pro's adaptive Subdivide and Standard's + // Bake differ only in which stages `params` enables and in what happens afterwards: + // - `snapshot_name` is the single undo step the commit opens. With `then_bake` it is also the step + // the displacement job that follows commits into, rather than pushing its own - an undo landing + // between the two would leave a mesh carrying every added triangle and no relief on it, and + // baking again from there would prepare it a second time. + // - `unchanged_msg`, when not empty, is shown if the run had nothing to do. Standard's Bake passes + // nothing: a mesh that already meets the criteria is not an error there, it just goes straight + // on to the displacement. + void queue_prepare(const TextureDisplacementPrepareParams ¶ms, const std::string &snapshot_name, + bool then_bake, const std::string &unchanged_msg); + // Set from queue_prepare() until its job's result has been committed. Distinct from + // m_bake_in_progress because Standard's Bake sets both in turn, and because every button that would + // read or replace the mesh has to stay disabled for the whole of it. + bool m_prepare_in_progress = false; + + // How one layer's paint sits on the pre-subdivision mesh, precise enough to carry across the + // refinement without rounding each source triangle to wholly painted or not. + // + // Rounding is what made the outline of a painted region come out ragged: a source triangle near a + // smooth brush boundary is wholly painted essentially at random, so "painted iff the source was + // full" turns a clean curve into a noisy fringe of isolated painted and unpainted triangles - and + // once the border band refines the mesh there, that fringe is reproduced faithfully instead of + // being blurred away by coarse geometry. + struct LayerPaintMap + { + std::vector full; // per source triangle: covered edge to edge + std::vector part_start; // CSR offsets into `part`, size (source tris + 1) + std::vector> part; // painted pieces of partly covered source triangles + bool empty() const { return full.empty(); } + }; + // Rebuilds every layer's mask on a subdivided mesh from `source` (new triangle -> the input triangle + // it descends from) and the pre-subdivision coverage in `paint`. + static TextureDisplacementFacetsData masks_after_subdivision( + const TriangleMesh &new_mesh, const std::vector &source, + const std::array &paint); + // False means the remesh failed or changed nothing (CGAL signals failure by handing the input back), + // and `out` must not be used. `target_edge_mm` is a request rather than a promise: it is clamped + // against the part's surface area first, because CGAL's cost grows with the square of 1/target. + static bool plan_remesh(const indexed_triangle_set &src, float target_edge_mm, float sharp_angle_deg, + indexed_triangle_set &out); + + // Marks every facet of every model-part volume as painted for the currently active layer - + // "whole model" as an alternative to brushing/clicking every triangle by hand. + void select_whole_model(); + + // The mesh raycasters are built one per model-part volume, in that order; this is the texture + // volume's slot among them, or -1 if it has none (no selection, or the lists disagree). + int texture_volume_raycaster_index() const; + + // Paints exactly the facets currently visible from the camera onto the active layer, replacing + // whatever that layer had painted. "Visible" is two tests: the facet faces the camera, and its + // centroid is not hidden behind other geometry (a real raycast, so a concave part's far inner + // wall is correctly excluded). When `uv_clip` is given (the projection frame's matrix), facets + // whose centroid falls outside the frame's uv unit square are skipped first - which both clips + // the selection to the frame and spares the raycast for everything outside it. Costs one ray + // query per surviving facet, so it is a one-shot action, never a per-frame one. Returns the + // number of facets selected. + int select_visible_faces(const std::array *uv_clip = nullptr); + + // When set, "Capture current view" also re-selects the visible faces, so the viewpoint the + // projector was captured from and the area it projects onto stay the same. Independent of the + // projection frame below: this takes every visible facet, the frame clips to its rectangle. + // Off by default, because turning it on replaces whatever the layer had painted. + bool m_project_only_visible = false; + + // The projection-frame overlay for a ViewProjected layer: a semi-transparent window dragged over + // the 3D view whose border becomes the projection's edge. Created lazily and owned here; hidden + // rather than destroyed when closed, so reopening keeps it where the user left it. + TextureProjectorFrame *m_projector_frame = nullptr; + int m_projector_opacity = 140; + // What the overlay's texture was last built from, so repeated updates don't rebuild the bitmap + // from unchanged pixels. Same shape as the m_thumbnail_source/m_thumbnail_smoothing pair above. + const void *m_projector_tex_source = nullptr; + float m_projector_tex_smoothing = -1.f; + void show_projector(bool show); + // Pushes the active layer's texture into the overlay. Cheap, and a no-op while it is hidden. + void update_projector(); + // Reads the overlay's rectangle and commits it as the layer's projection: builds the exact + // projective local->uv matrix from the camera and that rectangle, turns tiling off so the border + // is a hard edge, and repaints the layer with the visible facets inside the frame. Returns the + // number of facets selected, or -1 if the frame could not be used at all. + int apply_projection_frame(); + + // Uniformly subdivides the volume's mesh (see libslic3r::subdivide_mesh_uniform()) so a + // low-poly input model has enough vertices to actually show texture-displacement detail. + // A real, committed geometry change (like Bake), so it needs its own snapshot; unlike Bake it + // has no target region, so any not-yet-baked paint on the volume is dropped rather than + // remapped (texture-displacement paint has no remap-across-topology-change support yet). + void subdivide_model(); + + // The layer height map's width / height, for apply_uv_transform()'s non-square handling. 1 when + // there is no usable texture. + static float layer_texture_aspect(const TextureDisplacementLayer &layer); + + // Returns a cached GPU thumbnail of layer's texture (decoding + uploading it the first time it + // is requested, or whenever its image_data changes), or nullptr if it has no usable texture. + // Panel-sized: box-filtered down to THUMBNAIL_MAX_PX, which is right for a list row and wrong for + // anything the shader samples - see get_layer_height_texture(). + GLTexture *get_layer_thumbnail(const TextureDisplacementLayer &layer); + + // The same texture at full resolution, for the fast-preview shader. One slot, shared by whichever + // layer is active, because that is the only one the preview shader ever shades. + GLTexture *get_layer_height_texture(const TextureDisplacementLayer &layer); + // The layer's colour texture for the fast preview's per-fragment quantization. Null when the + // layer is not colouring or its texture is grayscale. + GLTexture *get_layer_color_texture(const TextureDisplacementLayer &layer); + + // A texture from the picker's library (see slic3r/GUI/TextureLibrary.hpp), read and uploaded + // once and then kept for the gizmo's lifetime. The decoded bytes are held alongside the GPU + // thumbnail so that picking the texture can hand the layer this very same image_data buffer - + // which both avoids re-reading the file and lets decode_height_texture()'s own cache (keyed by + // exactly this pointer) hit immediately on the first bake/preview. + struct LibraryTexture + { + std::shared_ptr> image_data; + std::unique_ptr thumbnail; + }; + const LibraryTexture *get_library_texture(const std::string &path); + + // The texture library: a popup grid of thumbnails beside the panel, shipped textures and the user's + // own under separate headings, with a tile that imports an image from disk. Opened for + // m_picker_slot by a click on a layer's thumbnail or name. `panel_min`/`panel_max` are the panel + // window's screen rectangle, which the popup is placed against. + void render_texture_library_popup(const ImVec2 &panel_min, const ImVec2 &panel_max); + int m_picker_slot = -1; + bool m_picker_open_request = false; + void set_layer_texture(TextureDisplacementLayer &layer, const TextureLibraryEntry &entry); + void import_custom_texture(TextureDisplacementLayer &layer); + + // Paint / Erase, from the panel. See get_left_button_state_type(). + bool m_erase_mode = false; + // Per slot: whether the layer's card shows every setting or only Depth, Tile size and Rotation. + // Panel state only, not saved with the project. + std::array m_layer_expanded{}; + + // "Adjust Texture" mode: instead of painting, dragging an on-canvas handle changes the active + // layer's offset. The handle is a flat panel lying in the paint patch's own tangent plane + // (a "pan" - drag anywhere on it for free 2D movement), plus two arrows along the patch's + // own U/V axes that constrain the drag to just that one axis for precise nudging. Anchored to + // the centroid/average-normal of the active layer's current paint patch (see + // libslic3r::compute_layer_paint_anchor()), so nothing is drawn if it has nothing painted yet. + // + // NOTE: the drag direction/sign below is this session's best-effort reasoning about which way + // the texture should appear to move as the handle is dragged - it could not be visually + // confirmed while writing it (no way to render/see pixels in this environment), so it may + // need a one-line sign flip once actually tested. + bool update_adjust_anchor(); // recomputes m_adjust_anchor_pos/normal; false if nothing painted + bool on_mouse_adjust_texture(const wxMouseEvent &mouse_event); + void render_adjust_texture_gizmo(); + // Draws a small '+'/'-' next to the mouse over the 3D view while painting/selecting, so it is + // obvious whether the next stroke adds paint (default) or erases it (Shift). Uses ImGui's + // foreground draw list, so it must be called from inside the gizmo's ImGui frame. + void render_paint_cursor_hint(); + // Mesh-local tangent-plane basis at m_adjust_anchor_normal, matching project_planar()'s + // dominant-axis convention so dragging on-canvas maps consistently onto offset. + void adjust_tangent_basis(Vec3f &u_axis, Vec3f &v_axis) const; + + // The plane a drag is measured against: the paint patch's anchor, lifted clear of the surface. + // Deliberately *fixed* - independent of the layer's offset - so that moving the handle cannot + // move the plane the handle's own motion is derived from, which would be a feedback loop. + Vec3f adjust_plane_point() const; + + // Where the handle is actually drawn, in mesh-local coordinates. This is NOT just the patch's + // centroid: the handle *represents the texture's placement*, so it has to travel as `offset` + // changes. Pinning it to the centroid is why dragging it looked broken - the texture slid but + // the handle stayed put. Undoing apply_uv_transform()'s scale and rotation turns the layer's + // offset back into a displacement in mm within the patch's tangent plane, which is what gets + // added to the anchor here. That is exactly consistent with the drag arithmetic in + // on_mouse_adjust_texture(): the handle then tracks the cursor 1:1, and sits back on the anchor + // precisely when offset is zero. + Vec3f adjust_handle_center(const TextureDisplacementLayer &layer) const; + + // The layer painted by the active slot, or nullptr if that slot has no layer yet. + TextureDisplacementLayer *active_layer(); + const TextureDisplacementLayer *active_layer() const; + + // Recomputes m_preview_glmodel from the volume's current (unbaked) paint state, using the same + // build_texture_displacement() algorithm as Bake. Called whenever the paint mask changes + // (stroke end, layer switch, undo/redo reload, post-bake refresh) rather than every frame - + // this is real mesh work (PNG sampling, vertex welding), not something to redo per paint stroke + // drag sample or idle repaint. With several painted layers this can be slow, so the actual + // computation runs in a background TextureDisplacementPreviewJob; this function only queues + // it and returns immediately, and m_preview_glmodel is updated later when it completes. + void rebuild_preview(); + void render_preview_mesh(); + + // Alternate, GPU-only preview: perturbs shading normals from the active layer's height texture + // instead of actually moving vertices, using the resources/shaders/*/texture_displacement_shaded.* + // shader. Faster than the true-displacement preview (no CPU meshing at all - just a per-vertex + // paint-weight buffer built at the same cadence as rebuild_preview()) but only shows the *active* + // layer, and the relief it shows is a shading illusion, not real geometry - "Bake" always produces + // the true, exact result either way. + void rebuild_shaded_preview_mesh(); + void render_shaded_preview_mesh(); + + // Feeds the active layer's painted patch + LSCM unwrap (if it's using that projection method) + // into Plater's docked UV-editor pane and shows it, or hides the pane if the active layer + // isn't using LSCM (or nothing is painted). Called whenever something that could change what + // the pane should show happens: paint changes, layer switch, projection method change, bake, + // and on shutdown (to hide it). + void update_uv_editor(); + + // Applies one island edit reported by the UV editor's drag/rotate gestures to the active layer. + // Deltas are incremental (see UVEditorCanvas::IslandEditFn); `finished` ends the gesture, which + // is when - and only when - the 3D preview is rebuilt, since doing that per mouse-move would + // queue a mesh recompute for every pixel of a drag. + void on_island_edited(int island, const Vec2f &offset_delta, float rotation_delta, float scale_factor, bool finished); + // Applies a committed vertex/edge edit from the UV editor's Vertex/Edge modes: each entry is an + // unwrapped-vertex index and its new raw-unwrap coordinate. Maps the unwrapped index to a mesh + // vertex and stores a per-vertex UV override on the layer (see lscm_uv_overrides), then rebuilds the + // preview so the baked geometry follows. + void on_uv_vertex_edited(const std::vector> &edits); + // UV-editor sub-element select mode, mirrored into the canvas: 0 = Island, 1 = Vertex, 2 = Edge. + int m_uv_select_mode = 0; + // One affine per island (columns: x basis, y basis, translation), mapping the unwrap's raw mm + // coordinates to texture UVs - the same type as UVEditorCanvas::IslandTransform, spelled out + // here so this header needn't drag in wxGLCanvas/glad. Cheap to recompute (it is per *island*, + // not per vertex), which is what lets an island drag update the pane without re-uploading a + // single vertex. + std::vector> uv_editor_island_transforms(const TextureDisplacementLayer &layer); + // Handles a toolbar command forwarded from the UV pane that needs the layer data the canvas + // doesn't hold (average island scale, cut island). Takes the command as an int (a cast of + // UVEditorCanvas::Command) so this header needn't pull in glad/wxGLCanvas via the canvas header. + void on_uv_command(int cmd, float value); + // Pane commands, queued by on_uv_command() and run from the panel render: pane clicks arrive in wx event + // handlers, outside the 3D canvas's GL frame, and several of these rebuild GPU meshes. + std::vector> m_uv_command_queue; + void process_uv_commands(); + void run_uv_command(int cmd, float value); + // Sends the UV editor pane what its controls show (see UVEditorCanvas::PaneState). + void push_uv_pane_state(); + // The panel's view modes: 0 Normal, 1 Fast, 2 Checker, 3 Distortion. Shared by the View row and the pane's + // background buttons, so both switch views the same way. + void apply_view_mode(int mode); + // The pane header's thumbnail of the active layer's texture, rebuilt only when its image changes. + static constexpr int UV_THUMB_PX = 64; + const void *m_uv_thumb_source = nullptr; + std::vector m_uv_thumb_rgb; + // Splits one unwrap chart in two by marking the mesh edges that straddle the plane through its + // 3D centroid, perpendicular to its longest axis, as seams (#17). The re-unwrap then separates it. + void cut_island(TextureDisplacementLayer &layer, int chart); + + // Captures the current camera's right/up axes into the layer's projector (#6), transformed into + // the volume's local space so the projection is stable as the object is later moved/rotated. + void capture_view_projection(TextureDisplacementLayer &layer); + + // Manual seam marking (#9): a mode where clicking the model toggles the nearest mesh edge in the + // active layer's lscm_seam_edges, so the unwrap can be cut exactly where the user wants - the + // Blender "mark seam" workflow. Painting is suppressed while it is on. + bool m_seam_edit_mode = false; + GLModel m_seam_glmodel; // the current seam edges, highlighted on the mesh + bool on_mouse_seam(const wxMouseEvent &mouse_event); + void toggle_seam_at(const Vec2d &mouse_pos); + void rebuild_seam_overlay(); + void render_seam_overlay(); + // The mesh edge nearest the mouse, in the volume's own vertex indices, or {-1,-1} if the ray misses. + // Factored out of toggle_seam_at() so the same pick can drive a live hover highlight (below) that + // shows which edge a click would toggle - the "I don't know how it works" feedback the user hit. + std::pair seam_edge_at(const Vec2d &mouse_pos) const; + std::pair m_seam_hover_edge{ -1, -1 }; + // The vertex a click would pick in shortest-path mode, so the target is visible on hover the same + // way the edge is in normal mode. -1 when nothing is under the cursor (or not in path mode). + int m_seam_hover_vertex = -1; + GLModel m_seam_hover_glmodel; + void rebuild_seam_hover_overlay(); + + // Shortest-path seam marking, for dense meshes where clicking every single triangle edge is + // tedious: in this sub-mode a click picks the nearest vertex, and the next click marks every edge + // on the shortest surface path between the two as a seam - so a whole seam line is drawn with two + // clicks. The end vertex becomes the next start, so a multi-segment seam chains click by click. + bool m_seam_path_mode = false; + int m_seam_path_anchor = -1; // mesh vertex the path starts from, or -1 + GLModel m_seam_anchor_glmodel; // the anchor's incident edges, highlighted + int seam_vertex_at(const Vec2d &mouse_pos) const; // nearest mesh vertex under the cursor + void mark_seam_path(int v_from, int v_to); // seam every edge on the shortest path + void rebuild_seam_anchor_overlay(); + // Set while an island gesture is in flight, so the undo snapshot is taken once at the start of + // the drag (capturing the state *before* it) rather than on every motion event. + bool m_island_drag_active = false; + + // Which of the up to TEXTURE_DISPLACEMENT_MAX_LAYERS paint masks the brush currently writes + // into. Always a valid slot index (0 by default) so the base class's per-volume selector + // machinery always has something to work with, even before any texture has been added - + // painting into a slot with no texture assigned is harmless, it just has no visible/bake + // effect until a texture is added to that slot. + int m_active_layer_slot = 0; + // Set when m_triangle_selectors could not be loaded from the stored paint masks, because a mask + // was recorded against a different topology: TriangleSelector::deserialize() rejects that and + // returns without a word, leaving the selector empty even though the mask is not. While this is + // set, an *empty* selector says nothing about the paint, so update_model_object() must not flush + // one back - serializing it over the mask destroys the user's paint for good, and the bake then + // reports "nothing is painted" about the data the flush had just deleted. + // + // Deliberately not a blanket refusal to flush: once the user paints, the selector holds real + // content again and writing it back is exactly right - it replaces the unusable mask with one + // recorded against the current mesh. So only the empty-over-non-empty case is held back. + bool m_selectors_stale = false; + bool m_bake_in_progress = false; + + // When set, the true-displacement geometry is rebuilt on every parameter change (live), instead of + // only once the slider being dragged is released. On by default so painting/added textures show + // straight away without needing to nudge a slider first. + bool m_auto_update = true; + + // Subdivision is now count-based (split the whole mesh 1..5 times) rather than a target edge + // length, and is previewed as a wireframe before it is committed: nothing is written to the model + // until "Apply". While previewing, the would-be subdivided mesh is drawn as a wireframe overlay so + // the added density is visible; "Done" ends the preview without touching the model. The normal + // "Show mesh wireframe" toggle is left alone, so a wireframe the user already had on stays on. + // 0 is a real value meaning "no subdivision": it previews nothing and Apply is a no-op. Apply + // snaps the slider back to it, because each pass quadruples the triangle count - leaving the + // count where it was would immediately re-preview N more passes on top of the mesh that was just + // committed, i.e. the most expensive thing the panel can do, on every Apply. + int m_subdivide_count = 1; + bool m_subdivide_editing = false; + int m_subdivide_preview_tris = -1; // triangle count of the previewed result, shown in the panel + GLModel m_subdivide_preview_glmodel; + void rebuild_subdivide_preview(); + void render_subdivide_preview(); + + // Adaptive subdivision: refine only the painted area, down to a target edge length, via + // conformal longest-edge bisection (subdivide_mesh_adaptive()). Unlike the count-based uniform + // path it does not touch the unpainted rest of the model, and - because it is driven by the paint + // - it can carry that paint forward across the topology change (children of a painted triangle + // are painted), so the region survives the subdivision instead of being dropped. + bool m_subdivide_adaptive = false; + float m_subdivide_target_mm = 0.f; // 0 = not yet seeded; filled from the mesh on first show + // Feature-adaptive sub-mode: put the triangles where the *displaced surface* bends (texture + // curvature) rather than spreading them evenly. `detail_mm` is the chord-error tolerance ("Detail" + // slider: how far the true surface may sit off the flat triangle before it is split); the target + // above stays in play as a coarse baseline ("Max edge"), and `min_edge_mm` is the hard floor + // ("Min edge"). See subdivide_mesh_adaptive(). + bool m_subdivide_feature = false; + float m_subdivide_detail_mm = 0.05f; + float m_subdivide_min_edge_mm = 0.1f; + // Edge length the band straddling the paint's boundary is refined to (0 = leave it alone). Applies + // in both adaptive sub-modes, because it is not a texture-detail criterion: the bake steps the + // surface from full displacement to zero across that boundary whatever the texture is doing, and + // the chord-error test cannot see that step at all - its sampler has no per-point paint test, so + // just outside the paint it goes on reporting the same smooth height field. Without this the + // transition keeps the input's density and the rim of an unpainted island comes out as a ring of + // large, steeply tilted triangles. See collect_paint_region() and subdivide_mesh_adaptive(). + float m_subdivide_border_mm = 0.4f; + // Edge length triangles straddling a *colour* boundary are refined to (0 = ignore colour). Its own + // control rather than a share of "Detail (mm)" because the two measure different things: Detail is + // a chord error in mm of surface deviation, this is a triangle size in mm along a step the chord + // test cannot see at all - the height field is perfectly smooth across a change of filament, so + // without this a colour boundary lands on whatever triangles the relief happened to need, which on + // a flat surface is none. Only ever costs anything where a boundary actually runs. + float m_subdivide_color_mm = 0.3f; + // How many thousand triangles refinement may *add* (the mesh's own count is added on before it is + // passed as subdivide_mesh_adaptive()'s absolute cap, so the control still means something on a + // dense model). Refinement is worst-error-first, so hitting the budget still yields the best mesh + // that many triangles can buy - and it is what keeps a fine "Detail" over a noisy texture from + // turning into an out-of-memory, or an unrenderable preview wireframe. + // + // The default used to be 1500 (i.e. +1.5 M triangles), which is what made Standard mode's Bake + // take minutes: every stage after the subdivision - the displacement itself, the convex hull, the + // GLModel upload, and the re-slice changed_object() triggers - then runs on a mesh two orders of + // magnitude denser than the input. 750k is still far finer than any FDM nozzle resolves at the + // 0.02 mm detail tolerance Standard uses, and the slider goes to 2000 for anyone who wants more. + int m_subdivide_budget_k = 750; + void subdivide_model_adaptive(); + // Fills `region` (per current-mesh triangle, a REFINE_* bitmask) from the union of every layer's + // painted area plus the band straddling its edge. If `paint` is non-null, also fills the per-layer + // coverage map the subdivision carries forward - the expensive half, skipped by the live preview, + // which only needs the region. Returns false when nothing is painted at all. + static bool collect_paint_region(const TriangleMesh &mesh, const TextureDisplacementFacetsData &facets, + std::vector ®ion, + std::array *paint); + + // Runs the volume's TextureDisplacementOptions smoothing over the *already committed* geometry, + // restricted to the painted area. The same settings are folded into Preview/Bake automatically; + // this is the escape hatch for relief that has already been baked in, where there is no + // displacement pass left to attach them to. Topology-preserving, so unlike subdivide and remesh it + // keeps every paint channel - including texture displacement - exactly as it was. + void smooth_model(); + + // Isotropic remeshing (CGAL) to even out wildly varying triangle sizes so displacement has a + // consistent density to work with. Target edge length in mm; 0 means "not yet initialised", filled + // with the mesh's mean edge length the first time the control is shown. Like subdivide, it replaces + // the geometry, but unlike subdivide it keeps every paint channel: prepare_mesh() carries the + // texture-displacement masks across spatially, which is also what lets Standard mode remesh *after* + // the user has painted. + float m_remesh_target_edge_mm = 0.f; + // Dihedral angle above which an edge counts as a hard feature and is held fixed by the remesher. + // Off by default would round every sharp edge off, so this is on; 0 disables the protection. + float m_remesh_sharp_angle_deg = 40.f; + bool m_remesh_keep_sharp_edges = true; + void remesh_model(); + + // ---- Bake stage debug view ---- + // + // A bake is a chain of stages that each rewrite the whole mesh, so when the result looks wrong the + // only useful question is which stage made it wrong. "Capture stages" runs the same recipe Bake + // runs, keeps every intermediate mesh, and draws the selected one through the ordinary + // true-displacement preview - so this needs no rendering code of its own. + // + // The run commits nothing: TextureDisplacementDebugJob never touches the Model. + std::vector m_debug_stages; + // Which stage is on screen. -1 means the debug view is off and the live preview owns + // m_preview_glmodel again; rebuild_preview() checks this before replacing it. + int m_debug_stage = -1; + bool m_debug_in_progress = false; + // The open / non-manifold counts come from a sort over every half-edge, which on a multi-million + // triangle stage costs more than the stage did. On by default because a stage that tore the mesh + // is exactly what this exists to find. + bool m_debug_check_topology = true; + + // World-millimetre area of everything painted on `mv`, cached on the mesh and the paint generation: + // it is what the refinement has to cover, so it is what says whether a budget can pay for a + // resolution. 0 when nothing is painted. + double painted_area_mm2(const ModelVolume &mv); + double m_painted_area_mm2 = 0.; + std::string m_painted_area_key; + // Triangles the refinement needs to reach `edge_mm` over that area. Bisection converges to four of + // them to a square of the target edge - measured within 3% on a test model over a 5x range of + // resolutions - but the real count depends on the shape of the triangles it starts from, so this + // is only ever used to say a budget is clearly too small, never as a promise of what will come out. + size_t estimated_refined_triangles(const ModelVolume &mv, float edge_mm); + + // The default pipeline's automatic resolution/budget for the volume, cached on what it depends on. + const V2Resolution &v2_recommendation(const ModelVolume &mv); + V2Resolution m_v2_rec; + std::string m_v2_rec_key; + + // Queues the capture run. Uses Standard mode's recipe (remesh, refine, displace) unless Pro mode + // has already prepared the mesh or the experimental pipeline is on, either of which has nothing + // to prepare. + void run_stage_debug(); + // Puts stage `index` on screen. A stage over the memory cap has counts but no geometry and is + // skipped. + void show_debug_stage(int index); + // Drops the captured stages and hands m_preview_glmodel back to the live preview. + void exit_debug_view(); + // The panel: capture button, stage list, and what each stage produced. + void render_debug_stage_panel(ModelVolume *mv); + + // Live, pre-bake preview of the true displaced geometry (built by the same algorithm Bake + // uses). Empty/uninitialized whenever nothing is painted yet, in which case the gizmo falls + // back to the standard paint-mask overlay like every other painting gizmo. + GLModel m_preview_glmodel; + // Set while a layer parameter slider has changed since the last rebuild_preview() call but the + // mouse button driving the drag hasn't been released yet - see on_render_input_window(). + bool m_preview_params_dirty = false; + + // See rebuild_shaded_preview_mesh()/render_shaded_preview_mesh(). Off by default: the Normal + // (true-displacement) view shows the real geometry Bake will produce, across every layer, so it is + // the honest first impression. The cheap, instant-updating Fast view is one click away in the View + // row for painting on a heavy model. + bool m_use_shaded_preview = false; + // Set from the UV editor's per-move island edits instead of rebuilding the (potentially large) shaded + // mesh synchronously inside that mouse handler - doing the rebuild there stalled both the UV pane + // and the 3D view. The rebuild is instead coalesced to once per 3D frame (render_painter_gizmo). + bool m_shaded_preview_dirty = false; + GLModel m_shaded_preview_glmodel; + + // Translucent tint over the active layer's painted triangles, drawn on top of whichever preview + // is showing. The base painter's own opaque paint highlight (render_triangles()) cannot be used + // in either preview mode - it is coincident with the surface and simply covers it - so the only + // paint feedback the gizmo had was the relief itself, which meant erasing showed nothing at all + // until the stroke ended and the whole preview rebuilt. This is that feedback: cheap (the painted + // patch only), translucent (the preview stays visible through it) and rebuilt live during a + // stroke. + GLModel m_paint_overlay_glmodel; + // The islands selected in the UV editor, tinted on the model so the pane's selection can be seen + // in place. Rebuilt whenever the pane's selection differs from the one it was built for. + GLModel m_island_overlay_glmodel; + std::vector m_island_overlay_selection; + void rebuild_island_overlay(const std::vector &selection); + void render_island_overlay(); + // Set on every paint event, cleared when the overlay is rebuilt in render_painter_gizmo(). Kept + // separate from m_shaded_preview_dirty so a stroke refreshes only the small painted patch per frame, + bool m_paint_overlay_dirty = false; + void rebuild_paint_overlay(); + void render_paint_overlay(GLModel &overlay); + // Every *other* layer's paint, muted, so all layers stay visible while one is edited. Rebuilt only when that + // paint, the active layer or the preview it is lifted onto changes (m_other_paint_key). + GLModel m_other_paint_glmodel; + std::string m_other_paint_key; + void rebuild_other_paint_overlay(); + // Whether render_shaded_preview_mesh() would actually draw something. Checked before the real volume + // is hidden: with no layer, no texture or no shader the shaded path draws nothing, and hiding the + // volume for it left the model invisible. + bool shaded_preview_ready() const; + // Whether the current displacement mesh carries a precomputed per-vertex uv (LSCM) that the shader + // should sample at directly, rather than projecting in-shader. Set by rebuild_shaded_preview_mesh(). + bool m_shaded_preview_uses_vertex_uv = false; + // The projection frame handed to the preview shader, captured when the mesh is built. Cylindrical and + // Spherical are reconstructed in the fragment shader (there is no per-vertex uv for them) and wrap + // around the whole patch, which no fragment can work out for itself. See layer_projection_frame(). + int m_shaded_projection_mode = 0; + Vec3f m_shaded_patch_center = Vec3f::Zero(); + Vec3f m_shaded_patch_axis = Vec3f::UnitZ(); + // The palette the fast preview's per-triangle filament indices were built against, captured when + // the mesh was. Empty when the active layer is not colouring, which is what tells the shader to + // fall back to the model's own colour. Held rather than re-read at draw time so the indices baked + // into the mesh can never be resolved against a different set of filaments than they were computed + // from - loading a filament mid-session would otherwise recolour a stale preview at random. + std::vector m_shaded_preview_palette; + + // GPU island drag: while an island is dragged in the UV editor, the displacement mesh is baked once (with + // the dragged island's vertices flagged, v_normal.y = 1) and then moved purely through the shader's + // island_delta uniform - one uniform update per mouse move, no rebuild - so it tracks the cursor + // as smoothly as Adjust placement. m_shaded_active_chart is the dragged island (or -1); + // m_shaded_active_face flags the dragged islands' *triangles*, indexed by painted-patch face; + // m_shaded_baked_active_xf is that island's placement baked into the current mesh, against which the + // live delta is measured; m_shaded_island_delta is the resulting final-uv-space affine handed to the + // shader (identity except mid-drag). + // + // Per triangle rather than per vertex deliberately: a seam vertex belongs to every chart touching + // it, so flagging the dragged chart's base vertices also flagged the corners its neighbours use. + // island_active is an interpolated varying, so those neighbouring triangles then had island_delta + // applied too - dragging one island moved every adjacent island's texture while the editor, which + // is per chart, correctly moved only the one. A triangle belongs to exactly one chart. + int m_shaded_active_chart = -1; + std::vector m_shaded_active_face; + Eigen::Matrix m_shaded_baked_active_xf = Eigen::Matrix::Identity(); + Eigen::Matrix m_shaded_island_delta = Eigen::Matrix::Identity(); + // Flags `charts`' triangles in m_shaded_active_face, sized to `patch_face_count` (the painted patch + // the displacement mesh is being built from). Cleared if the unwrap carries no face map. + void compute_shaded_active_faces(const std::vector &charts, size_t patch_face_count); + + // The set of islands the current UV-editor drag moves together: the pane's multi-selection unioned + // with each selected island's join group (see build_island_move_set()). Populated at drag start and + // cleared when it finishes. A move applies the same offset to every island in it; rotate/scale act + // only on the primary. Empty when no move drag is in flight. + std::vector m_island_move_set; + // All islands that must move with `primary`: the pane's multi-selection plus, for each of those, the + // charts sharing its join group in `layer`. Always contains `primary`. + std::vector build_island_move_set(const TextureDisplacementLayer &layer, int primary) const; + // The join-group id of chart `c`: its explicit entry in `groups`, or `c` itself (its own singleton) + // when unset. Two charts move together iff this matches. + static int island_group_of(const std::vector &groups, int c); + // Merges chart `b`'s join group into chart `a`'s (materialising `groups` to `chart_count` first). + static void join_island_groups(std::vector &groups, int a, int b, int chart_count); + // Final per-vertex texture uv for the projections the shader can't reconstruct itself - LSCM (an + // unwrap) and ViewProjected (a projector plane the shader doesn't know). One entry per patch/base + // vertex, already through apply_uv_transform(). Empty for Triplanar/Cylindrical/Spherical, which + // the shader projects on its own. Shared by the shaded preview and the UV-check overlay. + std::vector compute_layer_vertex_uvs(const indexed_triangle_set &patch, + const TextureDisplacementLayer &layer) const; + // The same, but three UVs per patch triangle (corner 0..2 of triangle i at 3i..3i+2). This is what + // the flat, unshared-vertex preview meshes actually want: under LSCM a seam vertex has a different + // UV in each island it borders, so collapsing to one per vertex handed a triangle at an unjoined + // seam its neighbour's placement - one visibly skewed triangle per face. Every other projection is + // single-valued per point, so there a corner's UV is just its vertex's. + std::vector compute_layer_corner_uvs(const indexed_triangle_set &patch, + const TextureDisplacementLayer &layer) const; + // The in-shader projection for `layer` (0 Triplanar, 1 Cylindrical, 2 Spherical) plus, for the two + // wrapping ones, the patch centroid and cylinder axis they wrap around - in the texture frame the + // shaders project in. Taken from the bake's own texture_displacement_patch_frame(), so a preview + // can never wrap around a different centre, or pick a different axis, than the bake will. + int layer_projection_frame(const indexed_triangle_set &local_patch, const TextureDisplacementLayer &layer, + Vec3f ¢er, Vec3f &axis) const; + // `patch` with its vertices moved into world millimetres - the space the bake maps the texture in + // (see build_texture_displacement()). Returned by value because the caller usually still needs the + // original: the patch doubles as render geometry, which is drawn through the volume's own matrix. + indexed_triangle_set patch_in_world(const indexed_triangle_set &patch) const; + + // UV-check overlay drawn over the painted patch to sanity-check the unwrap (#13/#14). Built by + // rebuild_uvcheck_mesh(), drawn by render_uvcheck_mesh() with the "texture_displacement_uvcheck" + // shader. Checker works for any projection; Distortion needs the per-vertex LSCM uv. + enum class UVCheckMode { None, Checker, Distortion }; + UVCheckMode m_uv_check_mode = UVCheckMode::None; + GLModel m_uvcheck_glmodel; + bool m_uvcheck_uses_vertex_uv = false; + // As m_shaded_projection_mode and friends, for the Checker overlay. + int m_uvcheck_projection_mode = 0; + Vec3f m_uvcheck_patch_center = Vec3f::Zero(); + Vec3f m_uvcheck_patch_axis = Vec3f::UnitZ(); + void rebuild_uvcheck_mesh(); + void render_uvcheck_mesh(); + + // The UV editor pane is opened only on the user's explicit request (this toggle in the panel), + // never automatically just because a patch exists - auto-popping it whenever there was "a + // selection to process" is exactly what the user asked to stop. update_uv_editor() keeps the pane + // hidden unless this is set. Reset on gizmo shutdown so reopening the gizmo doesn't reopen the pane. + bool m_show_uv_editor = false; + // The unwrap is expensive, so it is recomputed only when the user explicitly asks for it (the + // "Unwrap" button), not on every paint stroke or slider nudge. This is set by that button and + // consumed by the next update_uv_editor() call, which is the only path that re-solves the unwrap; + // every other call merely refreshes the cheap per-island affine transforms over the existing one. + bool m_uv_unwrap_pending = false; + // Set alongside m_uv_unwrap_pending only by the Unwrap button, so the connected-net auto-layout runs + // on a genuine re-unwrap but not on a refresh re-solve (a vertex-edit commit or undo), which must + // leave island placements untouched. + bool m_uv_apply_connected_net = false; + // Signature of the per-vertex UV overrides last reflected in the pane. When it changes without the + // user pressing Unwrap - a vertex/edge edit committing, or an undo/redo reverting one - the pane + // is re-solved so its geometry follows, even though a plain edit otherwise never re-solves (#Feat2). + size_t m_uv_overrides_sig = 0; + // What the UV pane's background currently holds, so update_uv_editor() only re-uploads it when the + // choice actually changes (the height texture is large; re-sending it every stroke would be waste). + enum class UVBackground { None, Height, Checker }; + UVBackground m_uv_editor_bg = UVBackground::None; + float m_uv_editor_bg_smoothing = -1.f; // smoothing the height backdrop was uploaded at + const void *m_uv_editor_bg_image = nullptr; // the layer image it was uploaded from + // Per-chart distortion heatmap colour for the UV pane (#7/#14), computed once when the unwrap is + // re-solved (relative stretch doesn't change when islands are merely moved), fed to the canvas only + // while the Distortion check mode is on. Empty otherwise. + std::vector m_uv_editor_distortion_colors; + void compute_uv_editor_distortion_colors(const indexed_triangle_set &patch); + + // Plain triangle-edge overlay on the mesh (#8), toggled independently of the check modes. + bool m_wireframe_overlay = false; + GLModel m_wireframe_overlay_glmodel; + size_t m_wireframe_overlay_vcount = 0; // topology signature, so it rebuilds only on a real change + void rebuild_wireframe_overlay(); // from the base mesh (shaded/paint mode) + void build_wireframe_from_its(const indexed_triangle_set &its); // from an explicit mesh, no early-out + void refresh_wireframe(); // pick base vs displaced source for the current view + void render_wireframe_overlay(); + // The displaced preview geometry the last preview job produced, kept so the wireframe overlay can be + // drawn on the raised surface actually shown in the true-displacement view (#: "wireframe in real mode"). + indexed_triangle_set m_preview_its; + // Raised on every rebuild_preview() call; a background TextureDisplacementPreviewJob's result + // is only applied if this hasn't moved on since the job was queued (see rebuild_preview()), + // so a burst of edits can't have an earlier, now-stale job clobber a later one's result. + // + // Shared with the worker thread (hence the atomic) so a running job can notice mid-computation + // that it has been superseded and abort, instead of running to completion for a result that will + // only be discarded on arrival. + std::shared_ptr> m_preview_generation = std::make_shared>(0); + // At most one preview job is ever queued. The UI job worker is a single FIFO queue shared with + // Bake (and with arrange/orient/send), and rebuild_preview() is called on every stroke end, every + // slider release and - with "Auto update" on - every frame of a slider drag. Queuing one full + // displacement per call built a backlog that took minutes to drain: the preview appeared frozen, + // and a Bake pressed afterwards sat behind the whole queue. So a request made while a job is in + // flight is recorded here and issued once that job settles, collapsing any number of edits into a + // single follow-up run. + bool m_preview_job_running = false; + bool m_preview_job_pending = false; + void queue_preview_job(); + + // Per-slot GPU thumbnail cache for the layer list panel, keyed by the image_data pointer that + // was current the last time each thumbnail was built (see get_layer_thumbnail()). + std::array, TEXTURE_DISPLACEMENT_MAX_LAYERS> m_thumbnails; + std::array m_thumbnail_source{}; + // The smoothing each cached thumbnail was built at, so a smoothing change re-uploads it. + std::array m_thumbnail_smoothing{}; + + // Full-resolution height texture for the preview shader, keyed the same way (see + // get_layer_height_texture()). A smoothing change re-uploads it, so the fast preview shows the + // blur the bake will apply. + std::unique_ptr m_height_tex; + const void *m_height_tex_source = nullptr; + float m_height_tex_smoothing = -1.f; + + // The same, for the layer's *colour*, which the fast preview quantizes per fragment so it shows + // the image at texel resolution rather than at the mesh's. Null for a grayscale texture. + std::unique_ptr m_color_tex; + const void *m_color_tex_source = nullptr; + float m_color_tex_smoothing = -1.f; + + // Library textures the picker has shown at least once, keyed by file path (see LibraryTexture). + std::map m_library_textures; + + // Everything the *unwrap* depends on. update_uv_editor() runs from rebuild_preview(), i.e. on + // every stroke end and every slider release - but depth/tiling/rotation/offset/blend change + // none of this, so re-extracting the patch and re-solving on those edits would be pure waste. + // Held as the real values rather than a hash: TriangleSplittingData has an exact operator==, so + // there is no reason to accept a hash's (however unlikely) chance of showing a stale unwrap. + struct UVEditorState + { + int slot = -1; + const void *image_data = nullptr; + float seam_angle = -1.f; + float padding = -2.f; + TriangleSelector::TriangleSplittingData facets; + // Manual/auto seam edges also change the unwrap, so a change here must force a re-solve just + // like the facets do (marking a seam leaves the paint mask untouched). + std::vector> seam_edges; + + bool operator==(const UVEditorState &other) const + { + return slot == other.slot && image_data == other.image_data && seam_angle == other.seam_angle && + padding == other.padding && facets == other.facets && seam_edges == other.seam_edges; + } + }; + UVEditorState m_uv_editor_state; + // Bounds of the UVs last handed to the pane, purely so the panel can show where the unwrap + // actually landed - it is packed in mm and then divided by the tile size, so it is easy for it + // to end up far outside the texture's first tile without any of that being visible. + Vec2f m_uv_editor_bbox_min = Vec2f::Zero(); + Vec2f m_uv_editor_bbox_max = Vec2f::Zero(); + // The unwrap m_uv_editor_state produced, kept so that changing tiling/rotation/offset only costs + // re-running apply_uv_transform() over it, not another extraction and solve. + PatchUnwrap m_uv_editor_unwrap; + + // When set, the panel is a free-floating window the user can drag anywhere (with a title bar to + // grab), instead of being pinned to the right of the gizmo toolbar. Persisted across gizmo + // open/close within a session, so the choice sticks while working. + bool m_undocked = false; + + // Smooth scrolling for the panel body (everything between the header and the pinned Bake footer). + // ImGui jumps a fixed number of lines per wheel notch, which on tall layer cards reads as a hard + // jolt rather than a scroll. The wheel is intercepted (ImGuiWindowFlags_NoScrollWithMouse) and + // moves a *target* offset instead; the real scroll is eased toward it over the following frames. + float m_panel_scroll_target = 0.f; + float m_panel_scroll_applied = -1.f; // what the easing wrote last frame; <0 until the first one + // Last frame's body content height and footer height. The body is a child window that has to be + // given its height before its content is laid out, so it is sized from the previous frame: as tall + // as its content, capped so the footer still fits above the bottom of the canvas. + float m_panel_body_h = 0.f; + float m_panel_footer_h = 0.f; + + // See the "Adjust Texture" block of private methods above. + bool m_adjust_texture_mode = false; + bool m_adjust_anchor_valid = false; + Vec3f m_adjust_anchor_pos = Vec3f::Zero(); // mesh-local + Vec3f m_adjust_anchor_normal = Vec3f::UnitZ(); // mesh-local + + // Pan: free drag anywhere on the flat panel, moves offset along both axes. AxisU/AxisV: drag + // the corresponding arrow, moves offset along only that one axis. + enum class AdjustHandle { None, Pan, AxisU, AxisV }; + AdjustHandle m_adjust_drag_handle = AdjustHandle::None; + Vec2f m_adjust_drag_start_offset = Vec2f::Zero(); + // Anchor-relative planar position (see project_planar()) of the point under the mouse at the + // moment the current drag started; every subsequent frame's delta is measured against this, + // rather than accumulated frame-to-frame, to avoid drift. + Vec2f m_adjust_drag_start_planar = Vec2f::Zero(); + + // Lazily-built unit quad (the pan panel) and unit line-with-arrowhead (reused, rotated, for + // both the U and V axis arrows), transformed into place at render time. + GLModel m_adjust_panel_glmodel; + GLModel m_adjust_arrow_glmodel; + + std::map m_desc; + + // Icons for the panel's icon buttons (tools, views, mapping, tiling, layer actions). Loaded through IconManager with + // the same colour/monochrome variants the main toolbar uses, so an inactive button shows the icon in + // the theme's normal (grey) foreground colour and an active one shows it in its original colours - + // matching the toolbar's selected/unselected look. Uploaded once on first panel render. + IconManager m_panel_icons; + std::map m_panel_icon_map; // file name -> [normal, colour, disabled] + bool m_panel_icons_tried = false; + void ensure_panel_icons(); +}; + +} // namespace Slic3r::GUI + +#endif // slic3r_GLGizmoTextureDisplacement_hpp_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index dc51518acc..40c272fcb7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -23,6 +23,7 @@ //#include "slic3r/GUI/Gizmos/GLGizmoHollow.hpp" #include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp" #include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp" #include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp" #include "slic3r/GUI/Gizmos/GLGizmoEmboss.hpp" #include "slic3r/GUI/Gizmos/GLGizmoSVG.hpp" @@ -171,6 +172,13 @@ void GLGizmosManager::switch_gizmos_icon_filename() case(EType::FuzzySkin): gizmo->set_icon_filename(m_is_dark ? "toolbar_fuzzy_skin_paint_dark.svg" : "toolbar_fuzzy_skin_paint.svg"); break; + case(EType::TextureDisplacement): + // One shared icon in both themes (no dedicated dark variant yet) - but it must still be + // *this* gizmo's icon. Handing it the fuzzy-skin one here quietly replaced the icon set at + // construction, so the toolbar ended up showing two identical fuzzy-skin buttons after any + // light/dark switch. + gizmo->set_icon_filename("toolbar_texture_displacement.svg"); + break; case(EType::MeshBoolean): gizmo->set_icon_filename(m_is_dark ? "toolbar_meshboolean_dark.svg" : "toolbar_meshboolean.svg"); break; @@ -228,6 +236,8 @@ bool GLGizmosManager::init() m_gizmos.emplace_back(new GLGizmoSeam(m_parent, m_is_dark ? "toolbar_seam_dark.svg" : "toolbar_seam.svg", EType::Seam)); m_gizmos.emplace_back(new GLGizmoFuzzySkin(m_parent, m_is_dark ? "toolbar_fuzzy_skin_paint_dark.svg" : "toolbar_fuzzy_skin_paint.svg", EType::FuzzySkin)); m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, m_is_dark ? "mmu_segmentation_dark.svg" : "mmu_segmentation.svg", EType::MmSegmentation)); + // One shared icon (no dedicated dark variant yet); it recolours acceptably in both themes. + m_gizmos.emplace_back(new GLGizmoTextureDisplacement(m_parent, "toolbar_texture_displacement.svg", EType::TextureDisplacement)); m_gizmos.emplace_back(new GLGizmoEmboss(m_parent, m_is_dark ? "toolbar_text_dark.svg" : "toolbar_text.svg", EType::Emboss)); m_gizmos.emplace_back(new GLGizmoSVG(m_parent)); m_gizmos.emplace_back(new GLGizmoMeasure(m_parent, m_is_dark ? "toolbar_measure_dark.svg" : "toolbar_measure.svg", EType::Measure)); @@ -550,6 +560,8 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p return dynamic_cast(m_gizmos[Cut].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); else if (m_current == FuzzySkin) return dynamic_cast(m_gizmos[FuzzySkin].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); + else if (m_current == TextureDisplacement) + return dynamic_cast(m_gizmos[TextureDisplacement].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); else if (m_current == MeshBoolean) return dynamic_cast(m_gizmos[MeshBoolean].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); else if (m_current == BrimEars) @@ -563,6 +575,7 @@ bool GLGizmosManager::is_paint_gizmo() return m_current == EType::FdmSupports || m_current == EType::MmSegmentation || m_current == EType::FuzzySkin || + m_current == EType::TextureDisplacement || m_current == EType::Seam; } @@ -1531,6 +1544,8 @@ std::string get_name_from_gizmo_etype(GLGizmosManager::EType type) return "Color Painting"; case GLGizmosManager::EType::FuzzySkin: return "Fuzzy Skin Painting"; + case GLGizmosManager::EType::TextureDisplacement: + return "Texture Displacement"; default: return ""; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 2a4afac16d..2903b38777 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -84,6 +84,7 @@ public: Seam, FuzzySkin, MmSegmentation, + TextureDisplacement, Emboss, Svg, Measure, diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 3ccbc6745a..fe5ddc9fa0 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -2631,7 +2631,11 @@ void ImGuiWrapper::push_toolbar_style(const float scale) ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 10 ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 0.00f)); // 11 ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, COL_GREEN_LIGHT); // 12 - ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.00f, 1.00f, 1.00f, 1.00f));//13 + // The checkbox/radio frame behind this is drawn fully transparent (see FrameBg above, + // alpha 0), showing the light window background through it - a white check mark there is + // invisible. Dark mode doesn't have this problem (its window background is dark), so only + // this branch needs a check mark color with real contrast against a light background. + ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(0.f, 156 / 255.f, 136 / 255.f, 1.00f));//13 ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(0.42f, 0.42f, 0.42f, 1.00f)); ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(0.93f, 0.93f, 0.93f, 1.00f)); ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(0.93f, 0.93f, 0.93f, 1.00f)); diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.cpp b/src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.cpp new file mode 100644 index 0000000000..25a6eeb301 --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.cpp @@ -0,0 +1,212 @@ +#include "TextureDisplacementBakeJob.hpp" + +#include + +#include "libslic3r/Model.hpp" +#include "libslic3r/format.hpp" +#include "libslic3r/TriangleSelector.hpp" + +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/GUI_ObjectList.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/NotificationManager.hpp" +#include "slic3r/GUI/Plater.hpp" +#include "slic3r/Utils/UndoRedo.hpp" + +namespace Slic3r::GUI { + +TextureDisplacementBakeJob::TextureDisplacementBakeJob(TextureDisplacementBakeInput &&input, std::function on_finished) + : m_input(std::move(input)), m_on_finished(std::move(on_finished)) +{ +} + +void TextureDisplacementBakeJob::process(Ctl &ctl) +{ + const std::string status = _u8L("Baking texture displacement"); + ctl.update_status(1, status); + + // Only ever touches m_input (captured by value before this job was queued) and local state - + // never the live Model - so this is safe to run concurrently with the UI thread. + // + // The progress hook matters for more than cosmetics: the framework's progress notification only + // grows a close button once it reaches 100%, so a job that reports 0 and nothing else leaves an + // uncloseable notification pinned on screen. It also carries the Cancel button's effect into the + // bake, which on a subdivided mesh can run for several seconds. + // Colour, when any layer asks for it, is computed in the same pass as the displacement: both need + // the same per-layer projection and UV work, and doing it twice would double the expensive part. + TextureColorRequest color_request; + TextureColorRequest *color = nullptr; + if (!m_input.color.empty()) { + color_request.quantize = GLGizmoTextureDisplacement::make_palette_quantizer(m_input.color.palette); + if (!m_input.color.palette_pure.empty()) + color_request.quantize_pure = GLGizmoTextureDisplacement::make_palette_quantizer(m_input.color.palette_pure); + color_request.resolve = GLGizmoTextureDisplacement::make_mix_resolver( + m_input.color.palette, m_input.color.mix_mode, m_input.color.layer_height, + m_input.color.dither_cell_mm); + color_request.despeckle_passes = m_input.color.despeckle_passes; + color_request.out_triangle = &m_triangle_color; + if (color_request.quantize) + color = &color_request; + } + + int last_reported = 1; + m_result = TriangleMesh(build_texture_displacement( + m_input.base_mesh, m_input.layers, m_input.facets_data, m_input.options, + [&ctl, &status, &last_reported](int percent) { + if (ctl.was_canceled()) + return false; + // The notification repaints (and wakes the idle loop) on every call, so only push a + // message when the displayed integer percentage actually moves. + if (percent > last_reported) { + last_reported = percent; + ctl.update_status(percent, status); + } + return true; + }, + color, m_input.volume_to_world, nullptr, &m_stats)); + + // Always finish at 100: this is what closes the notification. Reported even on cancel, where + // build_texture_displacement() returns an empty mesh and finalize() commits nothing. + ctl.update_status(100, status); +} + +void TextureDisplacementBakeJob::finalize(bool canceled, std::exception_ptr &eptr) +{ + struct OnExit + { + std::function fn; + ~OnExit() { if (fn) fn(); } + } on_exit{m_on_finished}; + + if (canceled || eptr || m_result.empty()) + return; + + // A bake that moved nothing - no layer could be sampled, or every sample was zero - must not be + // committed: committing is what clears the baked layers' paint, so the user would see the painted + // region simply vanish with no relief in its place and no idea why. Keep the paint and say so. + { + const indexed_triangle_set &out = m_result.its; + bool unchanged = out.indices.size() == m_input.base_mesh.indices.size() && + out.vertices.size() == m_input.base_mesh.vertices.size(); + for (size_t i = 0; unchanged && i < out.vertices.size(); ++i) + unchanged = (out.vertices[i] - m_input.base_mesh.vertices[i]).cwiseAbs().maxCoeff() < 1e-5f; + if (unchanged) { + show_error(nullptr, _u8L("The bake produced no displacement, so nothing was changed and the paint was kept. " + "Check that the painted layer has a texture and a non-zero depth.")); + return; + } + } + + Plater *plater = wxGetApp().plater(); + + const auto commit = [this, plater]() { + ModelVolume *volume = get_model_volume(m_input.volume_id, plater->model().objects); + if (volume == nullptr) + return; + + volume->set_mesh(std::move(m_result)); + volume->set_new_unique_id(); + volume->calculate_convex_hull(); + + // Colour lands in mmu_segmentation_facets, merged *over* whatever is already painted there + // rather than replacing it: a triangle the texture does not colour keeps its existing filament, + // and one the user never painted at all stays at NONE, which already means "the volume's own + // filament". That is what confines the effect to the painted area without having to invent a + // colour for everything outside it. Safe to index straight onto the new mesh - the bake is + // topology-preserving, so triangle i is still triangle i. + if (!m_triangle_color.empty() && m_triangle_color.size() == volume->mesh().its.indices.size()) { + TriangleSelector selector(volume->mesh()); + const TriangleSelector::TriangleSplittingData &existing = volume->mmu_segmentation_facets.get_data(); + if (!existing.bitstream.empty()) + selector.deserialize(existing, false); + for (size_t i = 0; i < m_triangle_color.size(); ++i) + if (m_triangle_color[i] > 0) + selector.set_facet(int(i), EnforcerBlockerType(m_triangle_color[i])); + volume->mmu_segmentation_facets.set(selector); + } + + // Clear the paint mask of every layer that was actually baked so a repeat bake (or the paint + // overlay) doesn't act on triangles that no longer represent the same unbaked surface. The + // texture layer definitions themselves are left untouched so the user can keep sculpting with + // the same textures. + // + // A mask the bake did *not* consume only still means what it did if the topology is unchanged, + // which is true of the classic path (it moves existing vertices) but not of the one-run + // pipeline, which rebuilds and then simplifies the mesh. A mask left behind against the old + // topology is exactly what makes the gizmo reload an empty selector over a non-empty mask and + // then erase it on the next flush - see GLGizmoTextureDisplacement::update_from_model_object(). + const bool topology_changed = m_input.base_mesh.indices.size() != volume->mesh().its.indices.size(); + for (int slot = 0; slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++slot) { + const auto it = std::find_if(m_input.layers.begin(), m_input.layers.end(), + [slot](const TextureDisplacementLayer &l) { return l.slot == slot; }); + if (topology_changed || (it != m_input.layers.end() && !it->empty())) + volume->texture_displacement_facet(slot).reset(); + } + + ModelObject *object = volume->get_object(); + if (object == nullptr) + return; + + if (ObjectList *obj_list = wxGetApp().obj_list()) { + const ModelObjectPtrs &objs = plater->model().objects; + auto it = std::find(objs.begin(), objs.end(), object); + if (it != objs.end()) + obj_list->update_info_items(size_t(it - objs.begin())); + } + + plater->changed_object(*object); + }; + + // Standard mode's Bake is remesh -> subdivide -> displace under a single snapshot, and this job runs + // long after that snapshot's scope has closed. Adding one here would put an undo step *between* the + // subdivision and the displacement: the first Undo would land on a mesh carrying every added + // triangle and no relief at all, and pressing Bake again from there would subdivide that mesh a + // second time. So the caller says who owns the undo step. + if (m_input.take_snapshot) { + Plater::TakeSnapshot snapshot(plater, _u8L("Bake texture displacement"), UndoRedo::SnapshotType::GizmoAction); + commit(); + } else { + commit(); + } + + // The refinement went finer than the budget could keep: the simplification had to take detail back + // out to fit, so what was baked carries less of the texture than the resolution asked for. Said + // here, with the numbers, because it is the only place that knows them - and not as an error + // dialog: the result is a usable mesh, just not the one the settings described. + if (m_stats.budget_limited) { + // Thousands under a million, so a small budget is not reported as "0.1 M". + const auto count = [](size_t n) { + return n >= 1000000 ? Slic3r::format("%1$.1f M", double(n) / 1000000.) : + Slic3r::format("%1% k", (n + 500) / 1000); + }; + wxGetApp().notification_manager()->push_notification( + NotificationType::CustomNotification, NotificationManager::NotificationLevel::WarningNotificationLevel, + Slic3r::format(_u8L("The triangle budget limited the detail: this resolution needs %1% triangles, " + "the budget kept %2%. Raise Budget or use a coarser Resolution for the full detail."), + count(m_stats.triangles_refined), count(m_stats.triangles_budget))); + } +} + +void queue_texture_displacement_bake(const ModelVolume &volume, const TextureColorSettings &color, + std::function on_finished, bool take_snapshot) +{ + TextureDisplacementBakeInput input; + input.color = color; + input.take_snapshot = take_snapshot; + input.volume_id = volume.id(); + input.base_mesh = volume.mesh().its; + input.layers = volume.texture_displacement_layers; + input.options = volume.texture_displacement_options; + input.volume_to_world = texture_displacement_volume_to_world(volume); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + input.facets_data[size_t(i)] = volume.texture_displacement_facet(i).get_data(); + + + auto &worker = wxGetApp().plater()->get_ui_job_worker(); + queue_job(worker, std::make_unique(std::move(input), std::move(on_finished))); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp b/src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp new file mode 100644 index 0000000000..187df3d0e7 --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementBakeJob.hpp @@ -0,0 +1,70 @@ +#ifndef slic3r_TextureDisplacementBakeJob_hpp_ +#define slic3r_TextureDisplacementBakeJob_hpp_ + +#include +#include + +#include "libslic3r/Color.hpp" +#include "libslic3r/ObjectID.hpp" +#include "libslic3r/TextureDisplacement.hpp" +#include "libslic3r/TriangleMesh.hpp" + +#include "Job.hpp" + +namespace Slic3r::GUI { + +// Everything process() needs, captured by value on the main thread when the job is queued so the +// worker thread never touches the live Model concurrently with the UI (mirrors how EmbossJob's +// DataBase is captured before process() runs). +struct TextureDisplacementBakeInput +{ + ObjectID volume_id; + indexed_triangle_set base_mesh; + std::vector layers; + TextureDisplacementFacetsData facets_data; + TextureDisplacementOptions options; + // Mesh coordinates -> world millimetres. Captured here with everything else so the worker never + // reaches back into the live Model for it. See build_texture_displacement(). + Transform3d volume_to_world = Transform3d::Identity(); + // Captured on the main thread. Empty unless some layer is colouring, in which case the bake also + // writes the volume's mmu_segmentation_facets - the same per-triangle filament assignment the MMU + // paint gizmo writes - alongside the displaced geometry. + TextureColorSettings color; + // Whether this job pushes its own undo step when it commits. False when the caller has already + // taken one that is meant to cover the displacement as well - Standard mode's Bake, which remeshes + // and subdivides first and has to undo as a single action. + bool take_snapshot = true; +}; + +// Bakes a volume's painted texture-displacement layers into real mesh geometry in the background, +// then commits the result on the main thread - mirrors EmbossJob's UpdateJob/update_volume() +// bake-and-commit pattern (see EmbossJob.cpp). +class TextureDisplacementBakeJob : public Job +{ +public: + TextureDisplacementBakeJob(TextureDisplacementBakeInput &&input, std::function on_finished); + + void process(Ctl &ctl) override; + void finalize(bool canceled, std::exception_ptr &eptr) override; + +private: + TextureDisplacementBakeInput m_input; + TriangleMesh m_result; + // What the bake spent, for the message it leaves behind when the budget capped the detail. + TextureBakeStats m_stats; + // Per triangle of m_result: the filament to print it in, as an EnforcerBlockerType value + // (0 = leave alone). Empty unless a layer asked for colour. See TextureColorRequest. + std::vector m_triangle_color; + std::function m_on_finished; +}; + +// Captures `volume`'s current mesh/layers/paint data and queues a TextureDisplacementBakeJob on +// the app's UI job worker. `on_finished` is always called once the job settles (success, failure, +// or cancellation), so the caller can clear its own "bake in progress" UI state. Must be called +// from the main thread. +void queue_texture_displacement_bake(const ModelVolume &volume, const TextureColorSettings &color, + std::function on_finished, bool take_snapshot = true); + +} // namespace Slic3r::GUI + +#endif // slic3r_TextureDisplacementBakeJob_hpp_ diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.cpp b/src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.cpp new file mode 100644 index 0000000000..97958ead9d --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.cpp @@ -0,0 +1,113 @@ +#include "TextureDisplacementDebugJob.hpp" + +#include "libslic3r/Model.hpp" + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/Plater.hpp" + +namespace Slic3r::GUI { + +TextureDisplacementDebugJob::TextureDisplacementDebugJob( + TextureDisplacementDebugInput &&input, std::function)> on_finished) + : m_input(std::move(input)), m_on_finished(std::move(on_finished)) +{ +} + +void TextureDisplacementDebugJob::process(Ctl &ctl) +{ + const std::string status = _u8L("Capturing bake stages"); + ctl.update_status(1, status); + + // Only ever touches m_input (captured by value before this job was queued) and local state - and, + // unlike the bake job, never writes anything back either. + int last_reported = 1; + const auto report = [&ctl, &status, &last_reported](int percent) { + if (ctl.was_canceled()) + return false; + if (percent > last_reported) { + last_reported = percent; + ctl.update_status(percent, status); + } + return true; + }; + + BakeStageRecorder recorder; + recorder.enable(true); + recorder.set_check_topology(m_input.check_topology); + recorder.set_mesh_cap(m_input.mesh_cap); + + indexed_triangle_set mesh = m_input.base_mesh; + TextureDisplacementFacetsData masks = m_input.facets_data; + + // The default pipeline can only move vertices the mesh already has, so its recipe starts with the + // preparation - which is where "first it remeshes, then it refines" actually happens. The + // experimental pipeline refines as part of the bake and has nothing to prepare. + if (m_input.run_prepare && !m_input.options.pipeline_v2) { + const TextureDisplacementPrepareResult prepared = + GLGizmoTextureDisplacement::prepare_mesh(mesh, masks, m_input.layers, m_input.prepare_params, + m_input.color.palette, + // Preparation is roughly half the run; the bake + // takes the progress bar from there. + [&report](int pct) { return report(1 + pct / 2); }, + &recorder); + if (ctl.was_canceled()) + return; + // An empty result means nothing needed doing, which is not a failure - the bake below simply + // runs on the mesh as it stands. paint_lost means the remesh dropped every layer's paint, so + // there is nothing left to displace and the stages recorded so far are the whole story. + if (prepared.paint_lost) { + m_stages = recorder.take(); + ctl.update_status(100, status); + return; + } + if (!prepared.mesh.indices.empty()) { + mesh = prepared.mesh; + masks = prepared.masks; + } + } + + build_texture_displacement(mesh, m_input.layers, masks, m_input.options, + [&report](int pct) { return report(50 + pct / 2); }, + /* color */ nullptr, m_input.volume_to_world, &recorder); + + m_stages = recorder.take(); + ctl.update_status(100, status); // always finish at 100: this is what closes the notification +} + +void TextureDisplacementDebugJob::finalize(bool canceled, std::exception_ptr &eptr) +{ + if (!m_on_finished) + return; + // The handler must run on every outcome - the caller uses it to clear its in-progress latch, and + // an empty vector is its signal that nothing usable came back. + if (canceled || eptr) + m_on_finished({}); + else + m_on_finished(std::move(m_stages)); +} + +void queue_texture_displacement_debug(const ModelVolume &volume, const TextureColorSettings &color, + const TextureDisplacementPrepareParams &prepare_params, + bool run_prepare, bool check_topology, + std::function)> on_finished) +{ + TextureDisplacementDebugInput input; + input.volume_id = volume.id(); + input.base_mesh = volume.mesh().its; + input.layers = volume.texture_displacement_layers; + input.options = volume.texture_displacement_options; + input.prepare_params = prepare_params; + input.run_prepare = run_prepare; + input.check_topology = check_topology; + input.color = color; + input.volume_to_world = texture_displacement_volume_to_world(volume); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + input.facets_data[size_t(i)] = volume.texture_displacement_facet(i).get_data(); + + auto &worker = wxGetApp().plater()->get_ui_job_worker(); + queue_job(worker, std::make_unique(std::move(input), std::move(on_finished))); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.hpp b/src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.hpp new file mode 100644 index 0000000000..0e7ca5c8a2 --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementDebugJob.hpp @@ -0,0 +1,82 @@ +#ifndef slic3r_TextureDisplacementDebugJob_hpp_ +#define slic3r_TextureDisplacementDebugJob_hpp_ + +#include +#include + +#include "libslic3r/ObjectID.hpp" +#include "libslic3r/TextureBake/TextureBakeDebug.hpp" +#include "libslic3r/TextureDisplacement.hpp" +#include "libslic3r/TriangleMesh.hpp" + +#include "Job.hpp" + +namespace Slic3r { +class ModelVolume; +} + +namespace Slic3r::GUI { + +// Runs a bake with stage capture on and commits nothing. +// +// A bake is a chain of stages that each rewrite the whole mesh - remesh, refine, displace, smooth, or +// for the experimental pipeline subdivide, regularize, relocate, displace, decimate, repair - and when +// the result looks wrong the only useful question is which of them made it wrong. This runs the same +// recipe the Bake button runs, keeps every intermediate mesh, and hands them back for the gizmo to +// step through. +// +// Deliberately separate from TextureDisplacementBakeJob rather than a flag on it: this must never +// touch the Model, and keeping the committing path free of a "but not this time" branch is what +// guarantees that. +struct TextureDisplacementDebugInput +{ + ObjectID volume_id; + indexed_triangle_set base_mesh; + std::vector layers; + TextureDisplacementFacetsData facets_data; + TextureDisplacementOptions options; + // The preparation stages - remesh and adaptive refinement. Only the default pipeline uses them; + // the experimental one refines as part of the bake and ignores this entirely. + TextureDisplacementPrepareParams prepare_params; + bool run_prepare = true; + // Mesh coordinates -> world millimetres, as the bake gets it. The captured stages are brought + // back into mesh coordinates before they are handed over, so the gizmo can draw them directly. + Transform3d volume_to_world = Transform3d::Identity(); + // Only the quantizer is used, and only by the refinement's colour criterion - the debug run + // produces no colour of its own. + TextureColorSettings color; + + // The edge scan behind the open / non-manifold counts is a sort over every half-edge, which on a + // multi-million triangle stage costs more than the stage did. On by default because a stage that + // tore the mesh is exactly what this exists to find. + bool check_topology = true; + // Stages above this keep their counts but not their geometry - see BakeStageRecorder. + size_t mesh_cap = 4'000'000; +}; + +class TextureDisplacementDebugJob : public Job +{ +public: + TextureDisplacementDebugJob(TextureDisplacementDebugInput &&input, + std::function)> on_finished); + + void process(Ctl &ctl) override; + void finalize(bool canceled, std::exception_ptr &eptr) override; + +private: + TextureDisplacementDebugInput m_input; + std::vector m_stages; + std::function)> m_on_finished; +}; + +// Captures `volume`'s current mesh, layers and paint and queues one debug run. `on_finished` always +// runs exactly once on the UI thread, with an empty vector if the run was cancelled or threw, so the +// caller can clear its own in-progress state. Must be called from the main thread. +void queue_texture_displacement_debug(const ModelVolume &volume, const TextureColorSettings &color, + const TextureDisplacementPrepareParams &prepare_params, + bool run_prepare, bool check_topology, + std::function)> on_finished); + +} // namespace Slic3r::GUI + +#endif // slic3r_TextureDisplacementDebugJob_hpp_ diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.cpp b/src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.cpp new file mode 100644 index 0000000000..4494594c7d --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.cpp @@ -0,0 +1,117 @@ +#include "TextureDisplacementPrepareJob.hpp" + +#include +#include + +#include "libslic3r/Model.hpp" +#include "libslic3r/TriangleSelector.hpp" + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/GUI_ObjectList.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/Plater.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp" +#include "slic3r/Utils/UndoRedo.hpp" + +namespace Slic3r::GUI { + +TextureDisplacementPrepareJob::TextureDisplacementPrepareJob( + TextureDisplacementPrepareInput &&input, std::function on_finished) + : m_input(std::move(input)), m_on_finished(std::move(on_finished)) +{ +} + +void TextureDisplacementPrepareJob::process(Ctl &ctl) +{ + const std::string status = _u8L("Preparing mesh for texture displacement"); + ctl.update_status(1, status); + + // Only ever touches m_input (captured by value before this job was queued) and local state - never + // the live Model - so this is safe to run concurrently with the UI thread. + // + // The progress hook is not just cosmetic: the framework's notification only grows a close button + // once it reaches 100%, and below that it shows Cancel, which is wired through here. Reporting is + // throttled to whole percentage points because every call repaints the notification and wakes the + // idle loop. + int last_reported = 1; + m_result = GLGizmoTextureDisplacement::prepare_mesh(m_input.base_mesh, m_input.masks, m_input.layers, + m_input.params, m_input.color.palette, + [&ctl, &status, &last_reported](int percent) { + if (ctl.was_canceled()) + return false; + if (percent > last_reported) { + last_reported = percent; + ctl.update_status(percent, status); + } + return true; + }); + + ctl.update_status(100, status); // always finish at 100: this is what closes the notification +} + +void TextureDisplacementPrepareJob::finalize(bool canceled, std::exception_ptr &eptr) +{ + TextureDisplacementPrepareOutcome outcome = TextureDisplacementPrepareOutcome::Failed; + struct OnExit + { + std::function fn; + const TextureDisplacementPrepareOutcome *outcome; + ~OnExit() { if (fn) fn(*outcome); } + } on_exit{m_on_finished, &outcome}; + + if (canceled || eptr) + return; + if (m_result.paint_lost) { + outcome = TextureDisplacementPrepareOutcome::PaintLost; + return; + } + if (m_result.mesh.indices.empty()) { + outcome = TextureDisplacementPrepareOutcome::Unchanged; + return; + } + + Plater *plater = wxGetApp().plater(); + ModelVolume *volume = get_model_volume(m_input.volume_id, plater->model().objects); + // The lookup doubles as a staleness check: anything that replaces a volume's mesh also gives it a + // new id (set_new_unique_id()), so a prepare computed from a mesh that has since been replaced - + // by an undo, another bake, or a boolean - simply fails to find its volume and commits nothing. + if (volume == nullptr) + return; + ModelObject *object = volume->get_object(); + if (object == nullptr) + return; + + { + Plater::TakeSnapshot snapshot(plater, m_input.snapshot_name, UndoRedo::SnapshotType::GizmoAction); + + // The four standard paint channels ride across on ModelVolume's own spatial remap. The eight + // texture-displacement masks do not go through it - prepare_mesh() has already carried them, + // exactly, from the source triangles the refinement records - so they are put back after + // restore_painting(), which resets every extra facet before remapping the channels it knows. + std::optional saved_painting = volume->save_painting(); + volume->set_mesh(TriangleMesh(std::move(m_result.mesh))); + volume->set_new_unique_id(); + volume->calculate_convex_hull(); + volume->restore_painting(saved_painting); + for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i) + volume->texture_displacement_facet(i).set_data(std::move(m_result.masks[size_t(i)])); + + if (ObjectList *obj_list = wxGetApp().obj_list()) { + const ModelObjectPtrs &objs = plater->model().objects; + auto it = std::find(objs.begin(), objs.end(), object); + if (it != objs.end()) + obj_list->update_info_items(size_t(it - objs.begin())); + } + plater->changed_object(*object); + } + outcome = TextureDisplacementPrepareOutcome::Committed; +} + +void queue_texture_displacement_prepare(TextureDisplacementPrepareInput &&input, + std::function on_finished) +{ + auto &worker = wxGetApp().plater()->get_ui_job_worker(); + queue_job(worker, std::make_unique(std::move(input), std::move(on_finished))); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.hpp b/src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.hpp new file mode 100644 index 0000000000..efe6a8ce75 --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementPrepareJob.hpp @@ -0,0 +1,77 @@ +#ifndef slic3r_TextureDisplacementPrepareJob_hpp_ +#define slic3r_TextureDisplacementPrepareJob_hpp_ + +#include +#include +#include + +#include "Job.hpp" + +#include "libslic3r/Color.hpp" +#include "libslic3r/ObjectID.hpp" +#include "libslic3r/TextureDisplacement.hpp" +#include "libslic3r/TriangleMesh.hpp" + +namespace Slic3r { +class ModelVolume; +} + +namespace Slic3r::GUI { + +// Getting a mesh ready to receive displacement - the isotropic remesh, carrying the paint onto it, and +// the adaptive refinement - off the UI thread. +// +// All three used to run inline behind a wxBusyCursor, which on any part big enough to matter meant tens +// of seconds with the window not repainting and no way to stop it: CGAL's remesher is single threaded +// and its cost grows with the square of 1/target_edge, and the refinement that follows spends a budget +// of hundreds of thousands of triangles. Indistinguishable from a hang, and reported as one. +// +// The work itself is GLGizmoTextureDisplacement::prepare_mesh(), which is pure - it takes an +// indexed_triangle_set and the layers' masks and returns new ones, touching no Model and no GUI - so all +// this job adds is the worker thread, the progress notification with its Cancel button, and the commit. +enum class TextureDisplacementPrepareOutcome +{ + Committed, // the volume now carries the prepared mesh and the paint carried onto it + Unchanged, // nothing needed doing - the mesh already met the criteria; the model was not touched + PaintLost, // the remesh landed but no layer's paint survived it, so nothing was committed + Failed, // cancelled, threw, or the volume went away while the job ran +}; + +struct TextureDisplacementPrepareInput +{ + ObjectID volume_id; + indexed_triangle_set base_mesh; + TextureDisplacementFacetsData masks; + std::vector layers; + TextureDisplacementPrepareParams params; + // Captured on the main thread. Empty when no layer is colouring, in which case the refinement + // skips the colour criterion entirely. Only the *quantizer* is used here: refinement follows + // perceived colour, never the interleaving that realises a mix. + TextureColorSettings color; + // The undo step the commit opens. Standard mode's Bake names it after the bake, because the + // displacement job that follows commits into this same step rather than pushing its own. + std::string snapshot_name; +}; + +class TextureDisplacementPrepareJob : public Job +{ + TextureDisplacementPrepareInput m_input; + TextureDisplacementPrepareResult m_result; + std::function m_on_finished; + +public: + TextureDisplacementPrepareJob(TextureDisplacementPrepareInput &&input, + std::function on_finished); + + void process(Ctl &ctl) override; + void finalize(bool canceled, std::exception_ptr &eptr) override; +}; + +// `on_finished` runs on the UI thread once the result has been committed (or found not to need +// committing), and always runs exactly once. +void queue_texture_displacement_prepare(TextureDisplacementPrepareInput &&input, + std::function on_finished); + +} // namespace Slic3r::GUI + +#endif // slic3r_TextureDisplacementPrepareJob_hpp_ diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.cpp b/src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.cpp new file mode 100644 index 0000000000..1845314f0d --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.cpp @@ -0,0 +1,66 @@ +#include "TextureDisplacementPreviewJob.hpp" + +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp" + +namespace Slic3r::GUI { + +TextureDisplacementPreviewJob::TextureDisplacementPreviewJob(TextureDisplacementPreviewInput &&input, uint64_t generation, + std::shared_ptr> current_generation, + std::function on_finished) + : m_input(std::move(input)), m_generation(generation), m_current_generation(std::move(current_generation)), + m_on_finished(std::move(on_finished)) +{ +} + +void TextureDisplacementPreviewJob::process(Ctl &ctl) +{ + // No ctl.update_status() anywhere in here on purpose - see the class comment. A preview is + // invisible bookkeeping; the only thing on screen should be the preview itself. + + // Only ever touches m_input (captured by value before this job was queued) and local state - + // never the live Model - so this is safe to run concurrently with the UI thread. + TextureColorRequest color_request; + TextureColorRequest *color = nullptr; + if (!m_input.color.empty()) { + color_request.quantize = GLGizmoTextureDisplacement::make_palette_quantizer(m_input.color.palette); + if (!m_input.color.palette_pure.empty()) + color_request.quantize_pure = GLGizmoTextureDisplacement::make_palette_quantizer(m_input.color.palette_pure); + color_request.resolve = GLGizmoTextureDisplacement::make_mix_resolver( + m_input.color.palette, m_input.color.mix_mode, m_input.color.layer_height, + m_input.color.dither_cell_mm); + color_request.despeckle_passes = m_input.color.despeckle_passes; + color_request.out_triangle = &m_result.triangle_color; + if (color_request.quantize) + color = &color_request; + } + + m_result.mesh = build_texture_displacement(m_input.base_mesh, m_input.layers, m_input.facets_data, + m_input.options, + [this, &ctl](int) { + // Bail the moment this preview stops being the current + // one; build_texture_displacement() then returns an + // empty mesh and finalize() drops it. + return !ctl.was_canceled() && + (!m_current_generation || + m_current_generation->load() == m_generation); + }, + color, m_input.volume_to_world); +} + +void TextureDisplacementPreviewJob::finalize(bool canceled, std::exception_ptr &eptr) +{ + if (!m_on_finished) + return; + // The handler must run on *every* outcome, cancellation included, because the caller uses it to + // clear its "a job is in flight" latch. Returning early on `canceled` - which is what a cancel_all() + // from Plater (project load/close, app exit) delivers - left that latch stuck true and no preview + // was ever queued again for the rest of the session. An empty result is the caller's signal that + // nothing usable came back; it already handles that. + if (canceled || eptr) + m_on_finished(TextureDisplacementPreviewResult{}, m_generation); + else + m_on_finished(std::move(m_result), m_generation); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp b/src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp new file mode 100644 index 0000000000..312cf6593e --- /dev/null +++ b/src/slic3r/GUI/Jobs/TextureDisplacementPreviewJob.hpp @@ -0,0 +1,82 @@ +#ifndef slic3r_TextureDisplacementPreviewJob_hpp_ +#define slic3r_TextureDisplacementPreviewJob_hpp_ + +#include +#include +#include +#include +#include + +#include "libslic3r/Color.hpp" +#include "libslic3r/TextureDisplacement.hpp" +#include "libslic3r/TriangleMesh.hpp" + +#include "Job.hpp" + +namespace Slic3r::GUI { + +// Everything process() needs, captured by value on the main thread when the job is queued - +// mirrors TextureDisplacementBakeInput, but a preview never writes back to the Model. +struct TextureDisplacementPreviewInput +{ + indexed_triangle_set base_mesh; + std::vector layers; + TextureDisplacementFacetsData facets_data; + TextureDisplacementOptions options; + // Mesh coordinates -> world millimetres, so the preview is displaced in the same space the bake + // is and the two cannot disagree. See build_texture_displacement(). + Transform3d volume_to_world = Transform3d::Identity(); + // Empty unless a layer is colouring, in which case the preview reports the filament per triangle + // alongside the mesh, so the Normal view shows what the bake will produce - interleaving included. + TextureColorSettings color; +}; + +// A preview result: the displaced mesh, and - when the input carried a palette - one filament index +// per triangle (an EnforcerBlockerType value; 0 means "no colour from the texture"). +struct TextureDisplacementPreviewResult +{ + indexed_triangle_set mesh; + std::vector triangle_color; +}; + +// Computes the true (unbaked) displaced-mesh preview in the background. With several painted +// layers this is real, non-trivial CPU work (PNG sampling, per-layer vertex welding), which used +// to run synchronously on every paint stroke and parameter tweak and made editing feel slow with +// more than one or two layers. Unlike Bake, this never touches the live Model - a preview is +// purely informational, there is nothing to commit. +// +// Deliberately reports no status: the Job framework turns the first update_status() call into an +// on-screen progress notification, and a preview firing one on every stroke and slider release +// buried the user in notifications that only closed at 100%. +class TextureDisplacementPreviewJob : public Job +{ +public: + // `generation` is an opaque token the caller controls (typically an incrementing counter): + // on_finished should only actually be applied by the caller if it still matches the caller's + // current generation when the job completes, so that a burst of edits queuing several of + // these jobs in a row can't have an earlier, now-stale result clobber a later one that + // finishes first. + // + // `current_generation` is the caller's live counter, shared with the worker thread. The job + // polls it *while computing* and aborts as soon as it no longer matches - so a preview that has + // already been superseded stops burning CPU instead of running to completion for a result that + // will only be thrown away. That matters because the UI job worker runs one job at a time in FIFO + // order: without it, a Bake queued behind a handful of stale previews waits for every one of them. + TextureDisplacementPreviewJob(TextureDisplacementPreviewInput &&input, uint64_t generation, + std::shared_ptr> current_generation, + std::function on_finished); + + void process(Ctl &ctl) override; + void finalize(bool canceled, std::exception_ptr &eptr) override; + +private: + TextureDisplacementPreviewInput m_input; + uint64_t m_generation; + std::shared_ptr> m_current_generation; + TextureDisplacementPreviewResult m_result; + std::function m_on_finished; +}; + +} // namespace Slic3r::GUI + +#endif // slic3r_TextureDisplacementPreviewJob_hpp_ diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 4ece1eee84..08da15d3e3 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1997,6 +1997,126 @@ bool MainFrame::can_reslice() const return (m_plater != nullptr) && !m_plater->model().objects.empty(); } +namespace { +// Orca: stable key persisted by the "remember last print action" preference. Reordering PrintSelectType +// must not silently remap a saved preference, so the key never derives from the enum value. +const char* print_select_type_key(MainFrame::PrintSelectType type) +{ + switch (type) { + case MainFrame::ePrintAll: return "print_all"; + case MainFrame::ePrintPlate: return "print_plate"; + case MainFrame::eExportSlicedFile: return "export_sliced_file"; + case MainFrame::eExportAllSlicedFile: return "export_all_sliced_file"; + case MainFrame::eExportGcode: return "export_gcode"; + case MainFrame::eSendGcode: return "send_gcode"; + case MainFrame::eSendToPrinter: return "send_to_printer"; + case MainFrame::eSendToPrinterAll: return "send_to_printer_all"; + case MainFrame::ePrintMultiMachine: return "print_multi_machine"; + case MainFrame::eUploadGcode: break; // Orca: no dropdown entry, never selectable + } + return ""; +} + +// Orca: single source for the print button and print dropdown labels +wxString print_select_type_label(MainFrame::PrintSelectType type) +{ + switch (type) { + case MainFrame::ePrintAll: return _L("Print all"); + case MainFrame::ePrintPlate: return _L("Print plate"); + case MainFrame::eExportSlicedFile: return _L("Export plate sliced file"); + case MainFrame::eExportAllSlicedFile: return _L("Export all sliced file"); + case MainFrame::eExportGcode: return _L("Export G-code file"); + case MainFrame::eSendGcode: return _L_CONTEXT("Print", "Verb"); + case MainFrame::eSendToPrinter: return _L("Send"); + case MainFrame::eSendToPrinterAll: return _L("Send all"); + case MainFrame::ePrintMultiMachine: return _L("Send to Multi-device"); + case MainFrame::eUploadGcode: break; // Orca: no dropdown entry, never selectable + } + return _L("Print plate"); +} +} // namespace + +std::vector MainFrame::available_print_actions() const +{ + std::vector actions; + const auto preset_bundle = wxGetApp().preset_bundle; + const bool use_printer_agents = wxGetApp().app_config->get_bool("use_printer_agents"); + + if (preset_bundle && !preset_bundle->is_bbl_vendor() && !use_printer_agents) { + // ThirdParty actions + actions.push_back(eSendGcode); + // Orca: when the printer accepts a .gcode.3mf (the "Support 3MF as gcode" option), + // also offer exporting the sliced .gcode.3mf bundle + const auto* use_3mf_opt = preset_bundle->printers.get_edited_preset().config.option("use_3mf"); + if (use_3mf_opt != nullptr && use_3mf_opt->value) + actions.push_back(eExportSlicedFile); + actions.push_back(eExportGcode); + return actions; + } + + // Orca Slicer actions + bool support_send = true; + bool support_print_all = true; + if (preset_bundle && !preset_bundle->use_bbl_network() && !use_printer_agents) { + support_send = false; // All 3rd print hosts do not have the send options + + const auto& cfg = preset_bundle->printers.get_edited_preset().config; + const auto* host_type_opt = cfg.option>("host_type"); + // Only simply print support uploading all plates + support_print_all = host_type_opt != nullptr && host_type_opt->value == PrintHostType::htSimplyPrint; + } + + actions.push_back(ePrintPlate); + if (support_print_all) + actions.push_back(ePrintAll); + if (support_send) { + actions.push_back(eSendToPrinter); + actions.push_back(eSendToPrinterAll); + } + if (enable_multi_machine) + actions.push_back(ePrintMultiMachine); + actions.push_back(eExportSlicedFile); + actions.push_back(eExportAllSlicedFile); + actions.push_back(eExportGcode); + return actions; +} + +void MainFrame::select_print_action(PrintSelectType select_type) +{ + m_print_btn->SetLabel(print_select_type_label(select_type)); + m_print_select = select_type; + remember_print_select(select_type); + m_print_enable = get_enable_print_status(); + m_print_btn->Enable(m_print_enable); + this->Layout(); + fit_tab_labels(); // ORCA on label change +} + +void MainFrame::remember_print_select(PrintSelectType select_type) +{ + if (!wxGetApp().app_config->get_bool("remember_print_action")) + return; + // AppConfig is marked dirty here and flushed by the regular autosave + wxGetApp().app_config->set("last_print_action", print_select_type_key(select_type)); +} + +bool MainFrame::get_remembered_print_select(PrintSelectType& out) const +{ + if (!wxGetApp().app_config->get_bool("remember_print_action")) + return false; + const std::string saved = wxGetApp().app_config->get("last_print_action"); + if (saved.empty()) + return false; + // Orca: only restore an action the current printer actually offers in the dropdown + for (PrintSelectType type : available_print_actions()) { + if (saved == print_select_type_key(type)) { + out = type; + return true; + } + } + return false; +} + wxBoxSizer* MainFrame::create_side_tools() { enable_multi_machine = wxGetApp().is_enable_multi_machine(); @@ -2016,6 +2136,14 @@ wxBoxSizer* MainFrame::create_side_tools() m_print_btn = new SideButton(print_panel, _L("Print plate"), ""); m_print_option_btn = new SideButton(print_panel, "", "sidebutton_dropdown", 0, 14); + // Orca: restore the last used print/export action if the user opted to remember it + PrintSelectType remembered_print_select; + if (get_remembered_print_select(remembered_print_select)) { + m_print_select = remembered_print_select; + m_print_btn->SetLabel(print_select_type_label(remembered_print_select)); + fit_tab_labels(); // ORCA on label change + } + auto slice_sizer = new wxBoxSizer(wxHORIZONTAL); slice_sizer->Add(m_slice_option_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(1)); slice_sizer->Add(m_slice_btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(1)); @@ -2178,193 +2306,15 @@ wxBoxSizer* MainFrame::create_side_tools() m_print_option_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { SidePopup* p = new SidePopup(this); - - if (wxGetApp().preset_bundle - && !wxGetApp().preset_bundle->is_bbl_vendor() - && !wxGetApp().app_config->get_bool("use_printer_agents")) { - // ThirdParty Buttons - SideButton* export_gcode_btn = new SideButton(p, _L("Export G-code file"), ""); - export_gcode_btn->SetCornerRadius(0); - export_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Export G-code file")); - m_print_select = eExportGcode; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change + for (PrintSelectType type : available_print_actions()) { + SideButton* btn = new SideButton(p, print_select_type_label(type), ""); + btn->SetCornerRadius(0); + btn->Bind(wxEVT_BUTTON, [this, p, type](wxCommandEvent&) { + select_print_action(type); p->Dismiss(); }); - - // upload and print - SideButton* send_gcode_btn = new SideButton(p, _L_CONTEXT("Print", "Verb"), ""); - send_gcode_btn->SetCornerRadius(0); - send_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L_CONTEXT("Print", "Verb")); - m_print_select = eSendGcode; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - p->append_button(send_gcode_btn); - - // Orca: when the printer accepts a .gcode.3mf (the "Support 3MF as gcode" option), - // also offer exporting the sliced .gcode.3mf bundle - const auto& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; - const auto* use_3mf_opt = printer_config.option("use_3mf"); - if (use_3mf_opt != nullptr && use_3mf_opt->value) { - SideButton* export_sliced_file_btn = new SideButton(p, _L("Export plate sliced file"), ""); - export_sliced_file_btn->SetCornerRadius(0); - export_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Export plate sliced file")); - m_print_select = eExportSlicedFile; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - p->append_button(export_sliced_file_btn); - } - - p->append_button(export_gcode_btn); + p->append_button(btn); } - else { - //Orca Slicer Buttons - SideButton* print_plate_btn = new SideButton(p, _L("Print plate"), ""); - print_plate_btn->SetCornerRadius(0); - - SideButton* send_to_printer_btn = new SideButton(p, _L("Send"), ""); - send_to_printer_btn->SetCornerRadius(0); - - SideButton* export_sliced_file_btn = new SideButton(p, _L("Export plate sliced file"), ""); - export_sliced_file_btn->SetCornerRadius(0); - - SideButton* export_all_sliced_file_btn = new SideButton(p, _L("Export all sliced file"), ""); - export_all_sliced_file_btn->SetCornerRadius(0); - - print_plate_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Print plate")); - m_print_select = ePrintPlate; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - SideButton* print_all_btn = new SideButton(p, _L("Print all"), ""); - print_all_btn->SetCornerRadius(0); - print_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Print all")); - m_print_select = ePrintAll; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - send_to_printer_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Send")); - m_print_select = eSendToPrinter; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - SideButton* send_to_printer_all_btn = new SideButton(p, _L("Send all"), ""); - send_to_printer_all_btn->SetCornerRadius(0); - send_to_printer_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Send all")); - m_print_select = eSendToPrinterAll; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - export_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Export plate sliced file")); - m_print_select = eExportSlicedFile; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - export_all_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Export all sliced file")); - m_print_select = eExportAllSlicedFile; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - - bool support_send = true; - bool support_print_all = true; - - const auto preset_bundle = wxGetApp().preset_bundle; - if (preset_bundle) { - if (preset_bundle->use_bbl_network() || wxGetApp().app_config->get_bool("use_printer_agents")) { - // BBL network support everything - } else { - support_send = false; // All 3rd print hosts do not have the send options - - auto cfg = preset_bundle->printers.get_edited_preset().config; - const auto host_type = cfg.option>("host_type")->value; - - // Only simply print support uploading all plates - support_print_all = host_type == PrintHostType::htSimplyPrint; - } - } - - p->append_button(print_plate_btn); - if (support_print_all) { - p->append_button(print_all_btn); - } - if (support_send) { - p->append_button(send_to_printer_btn); - p->append_button(send_to_printer_all_btn); - } - if (enable_multi_machine) { - SideButton* print_multi_machine_btn = new SideButton(p, _L("Send to Multi-device"), ""); - print_multi_machine_btn->SetCornerRadius(0); - print_multi_machine_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Send to Multi-device")); - m_print_select = ePrintMultiMachine; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - p->append_button(print_multi_machine_btn); - } - p->append_button(export_sliced_file_btn); - p->append_button(export_all_sliced_file_btn); - SideButton* export_gcode_btn = new SideButton(p, _L("Export G-code file"), ""); - export_gcode_btn->SetCornerRadius(0); - export_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Export G-code file")); - m_print_select = eExportGcode; - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - fit_tab_labels(); // ORCA on label change - p->Dismiss(); - }); - p->append_button(export_gcode_btn); - } - p->Popup(m_print_btn); } ); @@ -4224,38 +4174,22 @@ void MainFrame::on_config_changed(DynamicPrintConfig* config) const void MainFrame::set_print_button_to_default(PrintSelectType select_type) { - if (select_type == PrintSelectType::ePrintPlate) { - m_print_btn->SetLabel(_L("Print plate")); - m_print_select = ePrintPlate; - if (m_print_enable) - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - } else if (select_type == PrintSelectType::eSendGcode) { - m_print_btn->SetLabel(_L_CONTEXT("Print", "Verb")); - m_print_select = eSendGcode; - if (m_print_enable) - m_print_enable = get_enable_print_status() && can_send_gcode(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - } else if (select_type == PrintSelectType::eExportGcode) { - m_print_btn->SetLabel(_L("Export G-code file")); - m_print_select = eExportGcode; - if (m_print_enable) - m_print_enable = get_enable_print_status() && can_send_gcode(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - } else if (select_type == PrintSelectType::eExportSlicedFile) { - m_print_btn->SetLabel(_L("Export plate sliced file")); - m_print_select = eExportSlicedFile; - if (m_print_enable) - m_print_enable = get_enable_print_status(); - m_print_btn->Enable(m_print_enable); - this->Layout(); - } else { - // unsupport - return; - } + // Orca: keep the user's remembered print/export action instead of resetting it to the computed + // default. get_remembered_print_select() already rejects anything this printer does not offer. + PrintSelectType remembered; + if (get_remembered_print_select(remembered)) + select_type = remembered; + + if (select_type == eUploadGcode) + return; // unsupported: no dropdown entry exists for this action + + m_print_btn->SetLabel(print_select_type_label(select_type)); + m_print_select = select_type; + // get_enable_print_status() already applies can_send_gcode() to the actions that need it + if (m_print_enable) + m_print_enable = get_enable_print_status(); + m_print_btn->Enable(m_print_enable); + this->Layout(); } void MainFrame::add_to_recent_projects(const wxString& filename) diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index dce12c3fc1..0033f41a18 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -13,6 +13,7 @@ #include #include +#include #include "GUI_Utils.hpp" #include "Event.hpp" @@ -430,6 +431,14 @@ public: // Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig void on_config_changed(DynamicPrintConfig* cfg) const ; void set_print_button_to_default(PrintSelectType select_type); + // Orca: the print/export actions the current printer offers, in the order the dropdown lists them. + // The dropdown is built from this, and a remembered action is only restored if it appears here. + std::vector available_print_actions() const; + // Orca: apply an action picked from the print dropdown to the print button + void select_print_action(PrintSelectType select_type); + // Orca: remember the user's preferred print/export action across sessions (see "remember_print_action" preference) + void remember_print_select(PrintSelectType select_type); + bool get_remembered_print_select(PrintSelectType& out) const; bool can_save() const; bool can_save_as() const; diff --git a/src/slic3r/GUI/MarkdownTip.cpp b/src/slic3r/GUI/MarkdownTip.cpp index 7ffeae9e36..a22f4da87f 100644 --- a/src/slic3r/GUI/MarkdownTip.cpp +++ b/src/slic3r/GUI/MarkdownTip.cpp @@ -98,10 +98,7 @@ void MarkdownTip::LoadStyle() ph /= "tooltip/styled.html"; _data_dir = false; } - auto url = ph.string(); - std::replace(url.begin(), url.end(), '\\', '/'); - url = "file:///" + url; - _tipView->LoadURL(from_u8(url)); + _tipView->LoadURL(file_url_from_path(ph)); _lastTip.clear(); } diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 2ee875901c..e6172135a6 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -11,6 +11,7 @@ #include "MainFrame.hpp" #include "Tab.hpp" #include "libslic3r/Config.hpp" +#include "libslic3r/PrintBase.hpp" #include "format.hpp" #include @@ -3084,7 +3085,9 @@ bool NotificationManager::push_notification_data(std::unique_ptractivate_existing(notification.get())) { if (m_initialized && m_imgui_ready) { - if (notification->get_type() == NotificationType::SlicingWarning) { + // Precise Seam already aggregates all causes; replace it on repeated warning events. + if (notification->get_type() == NotificationType::SlicingWarning && + notification->get_data().sub_msg_id != PrintStateBase::SlicingPreciseSeamWarning) { m_pop_notifications.back()->append(notification->get_data().ori_text); } else { m_pop_notifications.back()->update(notification->get_data()); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index b0b7e891c4..a20dc50877 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -546,7 +546,8 @@ void ObjectDataViewModel::UpdateBitmapForNode(ObjectDataViewModelNode *node) { bool is_volume_node = node->GetType() & itVolume; int vol_type = static_cast(node->GetVolumeType()); - is_volume_node &= (vol_type >= int(ModelVolumeType::MODEL_PART) && vol_type <= int(ModelVolumeType::SUPPORT_ENFORCER)); + // Extended range to include Precise Seam modifier types + is_volume_node &= (vol_type >= int(ModelVolumeType::MODEL_PART) && vol_type <= int(ModelVolumeType::PRECISE_SEAM_NEUTRAL)); if (!node->has_warning_icon() && !node->has_lock()) { node->SetBitmap(is_volume_node ? ( diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 382a9176b9..0fc8ce9c6e 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -286,7 +286,7 @@ bool OpenGLManager::init_gl(bool popup_error) bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); if (!valid_version) { - BOOST_LOG_TRIVIAL(error) << "Found opengl version <= 3.2"<< std::endl; + BOOST_LOG_TRIVIAL(error) << "Found opengl version < 2.0"<< std::endl; // Complain about the OpenGL version. if (popup_error) { wxString message = from_u8((boost::format( diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1ed98dcba1..2622fdbc28 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -103,6 +103,7 @@ #include "Selection.hpp" #include "GLToolbar.hpp" #include "GUI_Preview.hpp" +#include "UVEditorCanvas.hpp" #include "3DBed.hpp" #include "PartPlate.hpp" #include "Camera.hpp" @@ -286,6 +287,30 @@ static void set_config_values(DynamicPrintConfig *config, const std::string &key } } +// Orca: a calibration print sets pressure advance explicitly to 0 on each extruder variant that +// has it disabled, so the value stored in the printer does not skew the result. Variants with +// pressure advance enabled keep their own value. +static void zero_pressure_advance_where_disabled(DynamicPrintConfig *filament_config) +{ + auto enable_pa = filament_config->option("enable_pressure_advance"); + auto pa = filament_config->option("pressure_advance"); + auto adaptive_pa = filament_config->option("adaptive_pressure_advance"); + if (!enable_pa || !pa || !adaptive_pa || pa->empty() || adaptive_pa->empty()) + return; + // All variant keys share the variant count; widen a short one rather than index past it. + if (pa->size() < enable_pa->size()) + pa->resize(enable_pa->size()); + if (adaptive_pa->size() < enable_pa->size()) + adaptive_pa->resize(enable_pa->size()); + for (size_t variant = 0; variant < enable_pa->size(); ++variant) { + if (enable_pa->get_at(variant)) + continue; + enable_pa->values[variant] = true; + pa->values[variant] = 0.0; + adaptive_pa->values[variant] = false; + } +} + bool Plater::has_illegal_filename_characters(const wxString& wxs_name) { std::string name = into_u8(wxs_name); @@ -605,15 +630,50 @@ private: bool m_enabled{false}; }; +// The nozzle rows are set in the small body font their "T1" prefix and diameter readout use, so the +// combos of a row drop from the Body_14 they are created with to match, instead of towering over +// the labels next to them. +static void use_nozzle_row_font(ComboBox *combo) +{ + // A read-only combo draws its value with the font of the TextInput it is built on, and its + // dropped list carries a font of its own. + combo->SetFont(Label::Body_10); + combo->GetDropDown().SetFont(Label::Body_10); + + // A row is as tall as the tags of the variant switch: a line of Body_10 text plus the 3 points of + // padding they put above and below it. TextInput::messureSize() instead sizes a combo as its + // (hidden) text control plus 8, and on macOS that control's best height is a fixed 16 points + // whatever font it carries, so the box would keep the height of the Body_14 it was created with. + // Handing the control the height the row asks for, less those 8 points, keeps messureSize()'s own + // arithmetic landing on the small box however often it re-measures. + const int row_height = combo->GetTextExtent("0.4 mm").y + 2 * combo->FromDIP(3); + auto *text_ctrl = combo->GetTextCtrl(); + text_ctrl->SetFont(Label::Body_10); + text_ctrl->SetInitialSize(wxSize(text_ctrl->GetBestSize().x, row_height - 8)); + + combo->SetMinSize(wxSize(combo->GetMinSize().x, row_height)); + combo->SetSize(wxSize(combo->GetSize().x, row_height)); +} + struct ExtruderGroup : StaticBox { + // One nozzle row: the tool prefix ("T1"…"Tn", shown only when the group lists several + // extruders) plus the nozzle readout and flow combo of a single extruder. Rows are appended on + // demand and never destroyed, so an event handler may capture its row index for the lifetime + // of the group. + struct NozzleRow + { + Label * prefix = nullptr; + Label * diameter_label = nullptr; // read-only nozzle diameter of this extruder + ComboBox * flow = nullptr; + }; + ExtruderGroup(wxWindow * parent, int index, wxString const &title); wxBoxSizer * sizer = nullptr; HoverLabel * hover_label = nullptr; wxStaticText* ams_label{nullptr}; ScalableButton * btn_edit = nullptr; ComboBox * combo_diameter = nullptr; - ComboBox * combo_flow = nullptr; AMSPreview * ams[4] = {nullptr}; wxStaticText *ams_not_installed_msg{nullptr}; ScalableButton * btn_up{nullptr}; @@ -627,6 +687,23 @@ struct ExtruderGroup : StaticBox std::vector ams_1; wxString diameter; + std::vector rows; // rows[0] always exists, one row per extruder when multi + size_t nozzle_row_count = 0; // rows currently shown + wxBoxSizer * row_columns[2] = {}; // row i is dealt into column i % 2 + int group_index = -1; // ctor index, the extruder a single-row group edits + + // Show `count` nozzle rows, one per extruder, each prefixed with T when count > 1. + void SetNozzleRowCount(size_t count); + size_t NozzleRowCount() const { return nozzle_row_count; } + // Nozzle diameter readout of the shown rows, one value per extruder. A listing card cannot edit + // it: the diameter belongs to the machine variant the printer preset selects, not to the extruder. + void SetRowDiameters(const std::vector &diameters); + + NozzleRow create_nozzle_row(); + // Widths the prefix and diameter labels of the visible rows so that the flow combos of a column + // line up. + void update_row_widths(); + void set_ams_count(int n4, int n1) { if (n4 == ams_n4 && n1 == ams_n1) @@ -657,7 +734,12 @@ struct ExtruderGroup : StaticBox btn_up->msw_rescale(); btn_down->msw_rescale(); combo_diameter->Rescale(); - combo_flow->Rescale(); + for (const NozzleRow &row : rows) { + row.prefix->SetFont(Label::Body_10.Bold()); + row.diameter_label->SetFont(Label::Body_10); + row.flow->Rescale(); + } + update_row_widths(); for (int i = 0; i < 4; ++i) ams[i]->msw_rescale(); } @@ -668,6 +750,10 @@ struct ExtruderGroup : StaticBox hover_label->sys_color_changed(); if (btn_edit) btn_edit->SetBackgroundColour(extruder_group_chip_bg()); + for (const NozzleRow &row : rows) { + row.prefix->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + row.diameter_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + } Refresh(); } }; @@ -691,11 +777,12 @@ struct Sidebar::priv ScalableButton * btn_edit_printer = nullptr; ScalableButton * btn_connect_printer = nullptr; - // Nozzle diameter + // Printer variant switch, titled "Variant": the combo lists the variants (nozzle sizes) of the + // current machine model and picking one switches the printer preset. StaticBox * panel_nozzle_dia = nullptr; Label * label_nozzle_title= nullptr; ComboBox * combo_nozzle_dia = nullptr; - Label * label_nozzle_type = nullptr; + Label * label_nozzle_type = nullptr; // read-only nozzle material, one-row layouts only // Printer - bed StaticBox * panel_printer_bed = nullptr; @@ -809,6 +896,8 @@ struct Sidebar::priv // otherwise reuses the app_config-cached option when the machine's nozzle config is unchanged. std::optional get_nozzle_options(MachineObject* obj, int extruder_count, bool support_multi_nozzle, bool is_manual); bool switch_diameter(bool single); + // Switch to the printer preset offering `diameter`. + bool switch_diameter_to(const wxString &diameter); void update_sync_status(const MachineObject* obj); // Filament Track Switch (H2-family accessory): true only when the connected printer is the @@ -918,11 +1007,19 @@ void Sidebar::priv::layout_printer(bool isBBL, bool isDual) int extruder_count = 0; const bool has_flow_variant = cfg.support_different_extruders(extruder_count); - panel_nozzle_dia->Show(!has_flow_variant); - extruder_single_sizer->Show(has_flow_variant); + // ORCA: a non-Bambu printer with several extruders lists one nozzle row per tool; Bambu's own + // multi-extruder printers keep the left/right pair above. + const bool multi_extruder_rows = !preset_bundle.is_bbl_vendor() && extruder_count > 1; + + // The variant box switches the machine variant. The card below lists the nozzles when there + // are flow variants to choose or several extruders to show; otherwise the box says it all. + panel_nozzle_dia->Show(true); + extruder_single_sizer->Show(has_flow_variant || multi_extruder_rows); + single_extruder->SetNozzleRowCount(multi_extruder_rows ? size_t(extruder_count) : 1); } else { panel_nozzle_dia->Show(false); extruder_single_sizer->Show(false); + single_extruder->SetNozzleRowCount(1); } // ORCA ensure printer section is visible after changing printer from printer selection dialog @@ -1319,7 +1416,7 @@ public: }; ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title) - : StaticBox(parent) + : StaticBox(parent), group_index(index) { SetFont(Label::Body_10); SetForegroundColour(wxColour("#CECECE")); @@ -1332,29 +1429,13 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title hover_label = new HoverLabel(this, title); hover_label->SetPosition(wxPoint(FromDIP(PRINTER_PANEL_RADIUS), 0)); // position it without putting in a sizer so it will look like title - // Nozzle + // Nozzle. Only the dual left/right cards show this combo: it is how they ask which nozzle the + // project should print with. Every other card reads the diameter out as text. auto combo_diameter = new ComboBox(this, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); this->combo_diameter = combo_diameter; combo_diameter->SetToolTip(_L("Diameter")); - - // Flow - auto combo_flow = new ComboBox(this, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); - combo_flow->GetDropDown().SetUseContentWidth(true); - combo_flow->Bind(wxEVT_COMBOBOX, [index, combo_flow](wxCommandEvent &evt) { - auto printer_tab = dynamic_cast(wxGetApp().get_tab(Preset::TYPE_PRINTER)); - NozzleVolumeType volume_type = NozzleVolumeType(intptr_t(combo_flow->GetClientData(evt.GetInt()))); - printer_tab->set_extruder_volume_type(index, volume_type); - auto plater = GUI::wxGetApp().plater(); - if (plater) { - // A new Flow type invalidates the per-filament volume choices stored on the - // plates for this extruder; rewrite them so the next apply/grouping sees the - // selected volume instead of a stale one. - plater->update_filament_volume_map(index, static_cast(volume_type)); - plater->update_machine_sync_status(); - } - }); - this->combo_flow = combo_flow; - combo_flow->SetToolTip(_L("Flow")); + combo_diameter->Show(index >= 0); + use_nozzle_row_font(combo_diameter); // AMS auto ams_panel = new wxPanel(this, wxID_ANY); @@ -1440,10 +1521,6 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title btn_down->Hide(); wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); - - hsizer->Add(combo_diameter, 1, wxRIGHT, FromDIP(5)); - hsizer->Add(combo_flow , 1); vsizer->AddSpacer(FromDIP(16)); // spacing for title and control if (index < 0) { @@ -1452,14 +1529,137 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title vsizer->Add(ams_panel, 0, wxEXPAND | wxLEFT | wxRIGHT , FromDIP(5)); vsizer->AddSpacer(FromDIP(2)); } - vsizer->Add(hsizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5)); + // Nozzle rows. The first one is the only one for a printer whose nozzles are not listed + // individually; a multi-extruder printer grows one row per tool (see SetNozzleRowCount). + // The rows are dealt into two columns, which halves the height of a long tool list; the second + // column empties itself when there is a single row, so a one-row card still spans the width. + auto rows_sizer = new wxBoxSizer(wxHORIZONTAL); + for (wxBoxSizer *&column : row_columns) { + column = new wxBoxSizer(wxVERTICAL); + rows_sizer->Add(column, 1, wxEXPAND); + } + vsizer->Add(rows_sizer, 0, wxEXPAND); + sizer = vsizer; // the floating filament-switch icon positions itself against this card SetSizer(vsizer); + SetNozzleRowCount(1); + Layout(); AMSCountPopupWindow::UpdateAMSCount(index < 0 ? 0 : index, this); } +ExtruderGroup::NozzleRow ExtruderGroup::create_nozzle_row() +{ + const size_t row_index = rows.size(); + NozzleRow row; + + row.prefix = new Label(this, Label::Body_10.Bold()); + row.prefix->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + row.prefix->SetLabelText(wxString::Format("T%d", int(row_index) + 1)); + row.prefix->Hide(); + + row.diameter_label = new Label(this, Label::Body_10); + row.diameter_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + row.diameter_label->Hide(); + + auto combo_flow = new ComboBox(this, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); + combo_flow->GetDropDown().SetUseContentWidth(true); + combo_flow->Bind(wxEVT_COMBOBOX, [this, row_index, combo_flow](wxCommandEvent &evt) { + // A one-row card edits the extruder it was created for, a multi-row card one extruder per row. + const int index = nozzle_row_count > 1 ? int(row_index) : group_index; + auto printer_tab = dynamic_cast(wxGetApp().get_tab(Preset::TYPE_PRINTER)); + NozzleVolumeType volume_type = NozzleVolumeType(intptr_t(combo_flow->GetClientData(evt.GetInt()))); + printer_tab->set_extruder_volume_type(index, volume_type); + auto plater = GUI::wxGetApp().plater(); + if (plater) { + // A new Flow type invalidates the per-filament volume choices stored on the + // plates for this extruder; rewrite them so the next apply/grouping sees the + // selected volume instead of a stale one. + plater->update_filament_volume_map(index, static_cast(volume_type)); + plater->update_machine_sync_status(); + } + }); + combo_flow->SetToolTip(_L("Flow")); + row.flow = combo_flow; + use_nozzle_row_font(combo_flow); + + auto row_sizer = new wxBoxSizer(wxHORIZONTAL); + row_sizer->Add(row.prefix, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(3)); + if (row_index == 0) + row_sizer->Add(combo_diameter, 1, wxRIGHT, FromDIP(5)); + row_sizer->Add(row.diameter_label, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(5)); + row_sizer->Add(row.flow, 1); + // Row-major: T1 T2 on the first line, T3 T4 on the second, and so on. + row_columns[row_index % 2]->Add(row_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(5)); + + return row; +} + +void ExtruderGroup::update_row_widths() +{ + // Measured from the rows on screen rather than fixed, so no gap is reserved for a "T10" or a + // "0.25 mm" that no row carries while the flow combos of a column still line up. + wxSize prefix_width(0, -1); + wxSize diameter_width(0, -1); + for (const NozzleRow &row : rows) { + if (row.prefix->IsShown()) + prefix_width.x = std::max(prefix_width.x, row.prefix->GetTextExtent(row.prefix->GetLabelText()).x); + if (row.diameter_label->IsShown()) + diameter_width.x = std::max(diameter_width.x, row.diameter_label->GetTextExtent(row.diameter_label->GetLabelText()).x); + } + for (const NozzleRow &row : rows) { + row.prefix->SetMinSize(prefix_width); + row.diameter_label->SetMinSize(diameter_width); + } +} + +void ExtruderGroup::SetRowDiameters(const std::vector &diameters) +{ + for (size_t i = 0; i < std::min(nozzle_row_count, diameters.size()); ++i) { + // Spelled like the calibration dialogs spell a nozzle diameter, "0.4 mm". + const wxString text = from_u8(get_diameter_string(diameters[i])) + " mm"; + rows[i].diameter_label->SetLabelText(text); + rows[i].diameter_label->SetToolTip(text); + } + update_row_widths(); + Layout(); +} + +void ExtruderGroup::SetNozzleRowCount(size_t count) +{ + const size_t row_count = std::min(count, size_t(MAXIMUM_EXTRUDER_NUMBER)); + if (row_count == nozzle_row_count) + return; + nozzle_row_count = row_count; + + // Every row names its tool as soon as there is more than one, so a single-nozzle card keeps the + // plain "Nozzle" look. A row is shown by showing its widgets: a sizer item holding a sub-sizer + // reports itself as shown while any of its windows is, so hiding the sub-sizer alone would + // leave the row in the layout. + for (size_t i = 0; i < row_count; ++i) { + if (i >= rows.size()) + rows.push_back(create_nozzle_row()); + rows[i].prefix->Show(row_count > 1); + rows[i].diameter_label->Show(group_index < 0); // the dual left/right cards show combo_diameter + // The flow combo's own visibility is decided with its choices, see update_extruder_variant. + } + for (size_t i = row_count; i < rows.size(); ++i) { + rows[i].prefix->Hide(); + rows[i].diameter_label->Hide(); + rows[i].flow->Hide(); + } + + // The rows just changed: re-measure them, then let the card and its containers give it the new room. + update_row_widths(); + Layout(); + if (wxWindow *parent = GetParent()) { + parent->Layout(); + if (wxWindow *grand_parent = parent->GetParent()) + grand_parent->Layout(); + } +} + void ExtruderGroup::update_ams() { static AMSinfo info4; @@ -1588,11 +1788,24 @@ bool Sidebar::priv::switch_diameter(bool single) diameter = diameter_left; } } - + + return switch_diameter_to(diameter); +} + +bool Sidebar::priv::switch_diameter_to(const wxString &diameter) +{ // ORCA: Check if the selected diameter matches the current nozzle diameter in the config Preset& printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset(); + // The combo lists printer variants, and the variant of a mixed-nozzle machine ("0.4+0.6") is no + // single extruder's diameter, so the preset's own variant answers first. + const std::string &printer_variant = printer_preset.config.opt_string("printer_variant"); + if (printer_variant == diameter.ToStdString()) { + return true; + } + // A named variant ("0.4 High Flow") shares its diameter with the standard profile, which selecting + // the plain diameter switches back to, so only a preset naming no variant is kept by its diameter. auto* nozzle_diameter = dynamic_cast(printer_preset.config.option("nozzle_diameter")); - if (nozzle_diameter && nozzle_diameter->size() > 0) { + if (printer_variant.empty() && nozzle_diameter && nozzle_diameter->size() > 0) { auto current_nozzle_dia = get_diameter_string(nozzle_diameter->values[0]); // If the selected diameter is the same as current nozzle, don't switch profiles if (current_nozzle_dia == diameter.ToStdString()) { @@ -2686,7 +2899,8 @@ Sidebar::Sidebar(Plater *parent) p->combo_nozzle_dia->wxEvtHandler::ProcessEvent(evt); }); - p->label_nozzle_title = new Label(p->panel_nozzle_dia, _L("Nozzle"), LB_PROPAGATE_MOUSE_EVENT); + // "Variant", not "Nozzle": picking one switches the printer preset (see panel_nozzle_dia). + p->label_nozzle_title = new Label(p->panel_nozzle_dia, _L("Variant"), LB_PROPAGATE_MOUSE_EVENT); p->label_nozzle_title->SetFont(Label::Body_10); p->combo_nozzle_dia = new ComboBox(p->panel_nozzle_dia, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); @@ -2695,12 +2909,15 @@ Sidebar::Sidebar(Plater *parent) p->combo_nozzle_dia->SetMinSize(FromDIP(wxSize(PRINTER_PANEL_SIZE.GetWidth() - 4, 26))); // requires a static value in here p->combo_nozzle_dia->SetMaxSize(FromDIP(wxSize(PRINTER_PANEL_SIZE.GetWidth() - 4, 26))); // using -1 with wxEXPAND has issues p->combo_nozzle_dia->Bind(wxEVT_COMBOBOX, [this](auto &e) { - auto evt_combo = (*p->single_extruder).combo_diameter; - evt_combo->SetSelection(e.GetSelection()); - wxCommandEvent evt(wxEVT_COMBOBOX, evt_combo->GetId()); - evt.SetEventObject(evt_combo); - evt.SetInt(e.GetSelection()); - wxPostEvent(evt_combo, evt); + // This box is the machine-variant selector, so it switches the printer preset directly + // instead of feeding an extruder card's combo. Deferred, because switching preset + // rebuilds this very combo. + const wxString diameter = p->combo_nozzle_dia->GetValue(); + p->combo_nozzle_dia->CallAfter([this, diameter]() { + p->is_switching_diameter = true; + p->switch_diameter_to(diameter); + p->is_switching_diameter = false; + }); e.Skip(); }); // ORCA paint whole combobox on focus @@ -3490,7 +3707,7 @@ void Sidebar::update_all_preset_comboboxes() wxString url = from_u8(PrintHost::get_print_host_webui(&cfg)); wxString apikey; if(url.empty()) - url = wxString::Format("file://%s/web/orca/missing_connection.html", from_u8(resources_dir())); + url = file_url_from_path(boost::filesystem::path(resources_dir()) / "web/orca/missing_connection.html"); else { const auto host_type = cfg.option>("host_type")->value; if (cfg.has("printhost_apikey") && (host_type != htSimplyPrint)) @@ -3680,8 +3897,16 @@ void Sidebar::update_presets(Preset::Type preset_type) auto diameters = wxGetApp().preset_bundle->printers.diameters_of_selected_printer(); auto diameter = printer_preset.config.opt_string("printer_variant"); auto extruder_max_nozzle_count = printer_preset.config.option("extruder_max_nozzle_count"); - auto update_extruder_variant = [printer_model, extruders_def, extruders, nozzle_volumes_def, nozzle_volumes, extruder_variants,diameter,extruder_max_nozzle_count](ExtruderGroup & extruder, int index) { - extruder.combo_flow->Clear(); + auto update_extruder_variant = [printer_model, extruders_def, extruders, nozzle_volumes_def, nozzle_volumes, extruder_variants,diameter,extruder_max_nozzle_count](ExtruderGroup & extruder, size_t row, int index) { + ComboBox *combo_flow = extruder.rows[row].flow; + combo_flow->Clear(); + // A profile may leave the per-extruder lists shorter than the nozzle count (they are + // padded when the printer is loaded, but a hand-written preset need not be). + if (index >= int(extruder_variants->values.size()) || index >= int(extruders->values.size()) || + index >= int(nozzle_volumes->values.size())) { + combo_flow->Hide(); + return; + } auto type = extruders_def->enum_labels[extruders->values[index]]; int select = -1; for (size_t i = 0; i < nozzle_volumes_def->enum_labels.size(); ++i) { @@ -3691,26 +3916,41 @@ void Sidebar::update_presets(Preset::Type preset_type) if (boost::algorithm::contains(extruder_variants->values[index], type + " " + nozzle_volumes_def->enum_labels[i]) || (extruder_max_nozzle_count->get_at(index) > 1 && extruder_max_nozzle_count->get_at(index) != ConfigOptionIntsNullable::nil_value() && nozzle_volumes_def->enum_keys_map->at(nozzle_volumes_def->enum_values[i]) == nvtHybrid)) { - if (nozzle_volumes_def->enum_keys_map->at(nozzle_volumes_def->enum_values[i]) == NozzleVolumeType::nvtHighFlow &&(diameter == "0.2" || + auto cur_volume_type = nozzle_volumes_def->enum_keys_map->at(nozzle_volumes_def->enum_values[i]); + // Defensive: profiles restrict E3D to 0.4 / 0.6; keep it out elsewhere. + if (cur_volume_type == NozzleVolumeType::nvtE3DHighFlow && diameter != "0.4" && diameter != "0.6") + continue; + if (cur_volume_type == NozzleVolumeType::nvtHighFlow && (diameter == "0.2" || is_skip_high_flow_printer(printer_model))) continue; - if (nozzle_volumes->values[index] == i) - select = extruder.combo_flow->GetCount(); - extruder.combo_flow->Append(_L(nozzle_volumes_def->enum_labels[i]), {}, (void*)i); + // The client data is the enum value, not the label position: E3D High Flow is 5 + // but sits at position 4, and a position would write an invalid type. + if (nozzle_volumes->values[index] == cur_volume_type) + select = combo_flow->GetCount(); + combo_flow->Append(_L(nozzle_volumes_def->enum_labels[i]), {}, (void*)(intptr_t)cur_volume_type); } } if (select == -1) - select = extruder.combo_flow->GetCount() - 1; - extruder.combo_flow->SetSelection(select); + select = combo_flow->GetCount() - 1; + combo_flow->SetSelection(select); + // No flow variant for this extruder: the diameter keeps the whole row. + combo_flow->Show(combo_flow->GetCount() > 0); }; - auto update_extruder_diameter = [&diameters, &nozzle_diameter](int extruder_index,ExtruderGroup & extruder) { + auto update_extruder_diameter = [&diameters, &nozzle_diameter, &diameter](int extruder_index,ExtruderGroup & extruder) { extruder.combo_diameter->Clear(); + if (extruder_index >= int(nozzle_diameter->values.size())) + return; int select = -1; // ORCA get the actual nozzle diameter from printer config auto nozzle_dia = get_diameter_string(nozzle_diameter->values[extruder_index]); + // Named variants such as "0.4HS" and "0.4 High Flow" share a physical diameter. + // Retain the variant selection unless the diameter was customized. + const bool keep_variant = diameter.substr(0, diameter.find_first_not_of("0123456789.")) == nozzle_dia && + std::find(diameters.begin(), diameters.end(), diameter) != diameters.end(); + const std::string &selected_variant = keep_variant ? diameter : nozzle_dia; // ORCA try to add nozzle diameter from config if list is empty. fixes blank nozzle combo box when preset has no alias - if(diameters[0].empty() && !nozzle_dia.empty()){ + if(!diameters.empty() && diameters[0].empty() && !nozzle_dia.empty()){ diameters[0] = nozzle_dia; } // Orca: Check if the actual nozzle diameter exists in the list, if not add it as a custom option @@ -3718,7 +3958,7 @@ void Sidebar::update_presets(Preset::Type preset_type) diameters.push_back(nozzle_dia); } for (size_t i = 0; i < diameters.size(); ++i) { - if (diameters[i] == nozzle_dia) + if (diameters[i] == selected_variant) select = extruder.combo_diameter->GetCount(); extruder.combo_diameter->Append(diameters[i], {}); } @@ -3726,14 +3966,15 @@ void Sidebar::update_presets(Preset::Type preset_type) extruder.diameter = nozzle_dia; }; auto image_path = get_cur_select_bed_image(); - if (is_dual_extruder) { + const bool multi_extruder_rows = p->single_extruder->NozzleRowCount() > 1; + if (is_dual_extruder && !multi_extruder_rows) { std::string printer_type = printer_preset.get_printer_type(wxGetApp().preset_bundle); p->left_extruder->SetTitle(_L(DevPrinterConfigUtil::get_toolhead_display_name(printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase))); p->right_extruder->SetTitle(_L(DevPrinterConfigUtil::get_toolhead_display_name(printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase))); AMSCountPopupWindow::UpdateAMSCount(0, p->left_extruder); AMSCountPopupWindow::UpdateAMSCount(1, p->right_extruder); - update_extruder_variant(*p->left_extruder, 0); - update_extruder_variant(*p->right_extruder, 1); + update_extruder_variant(*p->left_extruder, 0, 0); + update_extruder_variant(*p->right_extruder, 0, 1); //if (!p->is_switching_diameter) { update_extruder_diameter(0, *p->left_extruder); update_extruder_diameter(1, *p->right_extruder); @@ -3741,15 +3982,27 @@ void Sidebar::update_presets(Preset::Type preset_type) p->image_printer_bed->SetBitmap(create_scaled_bitmap(image_path, this, PRINTER_THUMBNAIL_SIZE.GetHeight())); } else { AMSCountPopupWindow::UpdateAMSCount(0, p->single_extruder); - update_extruder_variant(*p->single_extruder, 0); + for (size_t row = 0; row < p->single_extruder->NozzleRowCount(); ++row) + update_extruder_variant(*p->single_extruder, row, int(row)); //if (!p->is_switching_diameter) update_extruder_diameter(0, *p->single_extruder); + // The card reads the nozzles out, the variant box above is what switches the machine. + p->single_extruder->SetRowDiameters(nozzle_diameter->values); + if (multi_extruder_rows) { + // The hidden left/right cards keep mirroring the first extruders' diameters: the + // device sync path (a connected Bambu printer or a printer agent) still reads them. + update_extruder_diameter(0, *p->left_extruder); + update_extruder_diameter(1, *p->right_extruder); + } // ORCA sync unified nozzle combo box p->combo_nozzle_dia->Clear(); for (size_t i = 0; i < diameters.size(); ++i) p->combo_nozzle_dia->Append(diameters[i], {}); - p->combo_nozzle_dia->SetSelection((*p->single_extruder).combo_diameter->GetSelection()); + // Prefer the variant the preset names: a mixed-nozzle machine reads "0.4+0.6", which is + // no single extruder's diameter. + const int variant = p->combo_nozzle_dia->FindString(diameter); + p->combo_nozzle_dia->SetSelection(variant != wxNOT_FOUND ? variant : (*p->single_extruder).combo_diameter->GetSelection()); // ORCA update nozzle type const auto& full_config = wxGetApp().preset_bundle->full_config(); @@ -6864,6 +7117,13 @@ struct Plater::priv GLToolbar collapse_toolbar; Preview *preview; AssembleView* assemble_view { nullptr }; + // Docked/resizable 2D pane showing GLGizmoTextureDisplacement's LSCM unwrap of a painted + // patch; a sibling AUI pane alongside "sidebar"/"main", not part of the view3D/preview/ + // assemble_view sizer - see its registration below and Plater::get_uv_editor_canvas(). The + // pane hosts the panel (toolbar + canvas + status line); uv_editor_canvas is its inner canvas, + // cached so the gizmo can reach it directly. + UVEditorPanel* uv_editor_panel { nullptr }; + UVEditorCanvas* uv_editor_canvas { nullptr }; bool first_enter_assemble{ true }; std::unique_ptr notification_manager; @@ -7113,6 +7373,8 @@ struct Plater::priv void undo(); void redo(); + // True, and tells the user, while a background job is working on the model - see the definition. + bool undo_redo_blocked_by_job(); void undo_redo_to(size_t time_to_load); // BBS: backup @@ -7566,6 +7828,26 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) .BottomDockable(false) .BestSize(wxSize(39 * wxGetApp().em_unit(), 90 * wxGetApp().em_unit()))); + // UV editor pane for GLGizmoTextureDisplacement's LSCM unwrap preview - a resizable/dockable + // sibling of "sidebar"/"main" like everything else registered on this same AUI manager, not a + // change to the view3D/preview/assemble_view sizer above. Hidden by default: only relevant + // while that gizmo is active with a layer using the "Unwrap (LSCM)" projection method (see + // Plater::show_uv_editor()), so it stays out of the way of everyone else's window layout. + uv_editor_panel = new UVEditorPanel(q); + uv_editor_canvas = uv_editor_panel->canvas(); + m_aui_mgr.AddPane(uv_editor_panel, wxAuiPaneInfo() + .Name("uv_editor") + .Caption(_L("UV Editor")) + .Right() + .Hide() + .BestSize(wxSize(40 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()))); + // Closing the pane with its own X has to reach the gizmo, or its next update would simply show the pane again. + q->Bind(wxEVT_AUI_PANE_CLOSE, [this](wxAuiManagerEvent &evt) { + evt.Skip(); + if (evt.GetPane() != nullptr && evt.GetPane()->window == uv_editor_panel && uv_editor_canvas != nullptr) + uv_editor_canvas->run_command(UVEditorCanvas::Command::PaneClosed); + }); + auto* panel_sizer = new wxBoxSizer(wxHORIZONTAL); panel_sizer->Add(view3D, 1, wxEXPAND | wxALL, 0); panel_sizer->Add(preview, 1, wxEXPAND | wxALL, 0); @@ -7607,6 +7889,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) BOOST_LOG_TRIVIAL(info) << "Removed floating AUI state from saved window layout for Wayland"; } + // The UV editor is a transient, gizmo-driven pane (see show_uv_editor()); a saved layout + // from a session that happened to close with it open would otherwise restore it visible on + // startup, with nothing painted in it. Force it hidden here so it only ever appears when the + // texture-displacement gizmo asks for it. + if (wxAuiPaneInfo &uv_pane = m_aui_mgr.GetPane("uv_editor"); uv_pane.IsOk()) + uv_pane.Hide(); + sidebar_layout.is_collapsed = !sidebar.IsShown(); } @@ -14749,8 +15038,25 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot taken: " << snapshot_name << ", Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info(); } +// A background job holds the model it is working on: the texture displacement bake, for one, hands its +// result to the volume when it finishes, and it was queued against the geometry as it was at the time. +// Undoing while it runs restores an older state under it - a different transform, a different mesh - +// and the result then lands on geometry it was never computed for. Undo and redo therefore wait for +// the job, and say so rather than doing nothing. +bool Plater::priv::undo_redo_blocked_by_job() +{ + if (m_worker.is_idle()) + return false; + notification_manager->push_notification(NotificationType::CustomNotification, + NotificationManager::NotificationLevel::RegularNotificationLevel, + _u8L("Cannot undo or redo while an operation is running. Stop it first.")); + return true; +} + void Plater::priv::undo() { + if (this->undo_redo_blocked_by_job()) + return; const std::vector &snapshots = this->undo_redo_stack().snapshots(); auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time())); // BBS: undo-redo until modify record @@ -14768,6 +15074,8 @@ void Plater::priv::undo() void Plater::priv::redo() { + if (this->undo_redo_blocked_by_job()) + return; const std::vector &snapshots = this->undo_redo_stack().snapshots(); auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time())); // BBS: undo-redo until modify record @@ -15749,6 +16057,11 @@ void Plater::import_model_id(wxString download_info) //wxString sError = error.what(); } + // The name comes from the link: reduce it to a plain file name inside the download folder. + filename = from_u8(sanitize_file_basename(into_u8(filename))); + if (filename.empty()) + filename = "untitled.3mf"; + bool download_ok = false; int retry_count = 0; const int max_retries = 3; @@ -15790,51 +16103,28 @@ void Plater::import_model_id(wxString download_info) msg = _L("Preparing 3MF file..."); - //gets the number of files with the same name - std::vector vecFiles; - bool is_already_exist = false; - - target_path = fs::path(wxGetApp().app_config->get("download_path")); - try - { - vecFiles.clear(); - wxString extension = fs::path(filename.wx_str()).extension().c_str(); - - - //check file suffix - if (!extension.Contains(".3mf")) { - msg = _L("Download failed; unknown file format."); - return; - } - - auto name = filename.substr(0, filename.length() - extension.length() - 1); - - for (const auto& iter : boost::filesystem::directory_iterator(target_path)) - { - if (boost::filesystem::is_directory(iter.path())) - continue; - - wxString sFile = iter.path().filename().string().c_str(); - if (strstr(sFile.c_str(), name.c_str()) != NULL) { - vecFiles.push_back(sFile); - } - - if (sFile == filename) is_already_exist = true; - } - } - catch (const std::exception&) - { - //wxString sError = error.what(); + //check file suffix + wxString extension = fs::path(filename.wx_str()).extension().c_str(); + if (!extension.Contains(".3mf")) { + msg = _L("Download failed; unknown file format."); + return; } - //update filename - if (is_already_exist && vecFiles.size() >= 1) { - wxString extension = fs::path(filename.wx_str()).extension().c_str(); - wxString name = filename.substr(0, filename.length() - extension.length()); - filename = wxString::Format("%s(%d)%s", name, vecFiles.size() + 1, extension).ToStdString(); + //never replace an existing file + std::string unused_filename; + try { + if (!find_unused_filename(target_path, into_u8(filename), {}, unused_filename)) + unused_filename.clear(); + } catch (const std::exception&) { + unused_filename.clear(); } + if (unused_filename.empty()) { + msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it."); + return; + } + filename = from_u8(unused_filename); msg = _L("Downloading project..."); @@ -15846,10 +16136,6 @@ void Plater::import_model_id(wxString download_info) boost::uuids::uuid uuid = boost::uuids::random_generator()(); std::string unique = to_string(uuid).substr(0, 6); - if (filename.empty()) { - filename = "untitled.3mf"; - } - //target_path /= (boost::format("%1%_%2%.3mf") % filename % unique).str(); target_path /= fs::path(filename.wc_str()); @@ -15898,13 +16184,26 @@ void Plater::import_model_id(wxString download_info) cont = false; } }) - .on_complete([&cont, &download_ok, tmp_path, target_path](std::string body, unsigned /* http_status */) { + .on_complete([&cont, &download_ok, &msg, tmp_path, &target_path](std::string body, unsigned /* http_status */) { fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); file.write(body.c_str(), body.size()); file.close(); - fs::rename(tmp_path, target_path); cont = false; - download_ok = true; + try { + // Another file may have taken the name while downloading. + std::string unused_filename; + if (find_unused_filename(target_path.parent_path(), target_path.filename().string(), {}, unused_filename)) { + target_path = target_path.parent_path() / unused_filename; + fs::rename(tmp_path, target_path); + download_ok = true; + return; + } + } catch (const std::exception &e) { + BOOST_LOG_TRIVIAL(error) << "import_model_id: failed to move the download into place: " << e.what(); + } + boost::system::error_code ec; + fs::remove(tmp_path, ec); + msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it."); }).perform_sync(); // for break while @@ -16422,7 +16721,7 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; - /// --- scale --- + /// -- scale -- // model is created for a 0.4 nozzle, scale z with nozzle size. const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter"); std::vector extruder_types = printer_config->option("extruder_type")->values; @@ -16913,11 +17212,7 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params) set_config_values(print_config, "default_jerk", 0); } - if (!filament_config->option("enable_pressure_advance")->get_at(0)) { - set_config_values(filament_config, "enable_pressure_advance", true); - set_config_values(filament_config, "pressure_advance", 0.0); - set_config_values(filament_config, "adaptive_pressure_advance", false); - } + zero_pressure_advance_where_disabled(filament_config); printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false}); printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{false}); @@ -16979,11 +17274,7 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params) set_config_values(print_config, "default_jerk", 0); } - if (!filament_config->option("enable_pressure_advance")->get_at(0)) { - set_config_values(filament_config, "enable_pressure_advance", true); - set_config_values(filament_config, "pressure_advance", 0.0); - set_config_values(filament_config, "adaptive_pressure_advance", false); - } + zero_pressure_advance_where_disabled(filament_config); printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false}); printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{false}); @@ -17045,11 +17336,7 @@ void Plater::Calib_Cornering(const Calib_Params& params) set_config_values(print_config, "default_jerk", 0); } - if (!filament_config->option("enable_pressure_advance")->get_at(0)) { - set_config_values(filament_config, "enable_pressure_advance", true); - set_config_values(filament_config, "pressure_advance", 0.0); - set_config_values(filament_config, "adaptive_pressure_advance", false); - } + zero_pressure_advance_where_disabled(filament_config); printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false}); printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{true}); @@ -20911,6 +21198,33 @@ GLCanvas3D* Plater::get_assmeble_canvas3D() return nullptr; } +UVEditorCanvas* Plater::get_uv_editor_canvas() +{ + return p->uv_editor_canvas; +} + +void Plater::show_uv_editor(bool show) +{ + if (p->uv_editor_panel == nullptr) + return; + const wxAuiPaneInfo &pane = p->m_aui_mgr.GetPane(p->uv_editor_panel); + if (!pane.IsOk() || pane.IsShown() == show) + return; + + // Deferred, because GLGizmoTextureDisplacement calls this from its ImGui panel - that is, from + // the middle of the 3D canvas's GL frame. Showing an AUI pane re-lays out the window and + // delivers the resulting size/paint events synchronously, and the UV canvas painting itself + // makes its own surface current in the app's *shared* GL context, which mid-frame is the one + // the 3D canvas is drawing into. Doing the layout once the frame is over avoids that entirely. + CallAfter([this, show]() { + wxAuiPaneInfo &deferred_pane = p->m_aui_mgr.GetPane(p->uv_editor_panel); + if (!deferred_pane.IsOk() || deferred_pane.IsShown() == show) + return; + deferred_pane.Show(show); + p->m_aui_mgr.Update(); + }); +} + GLCanvas3D* Plater::get_current_canvas3D(bool exclude_preview) { return p->get_current_canvas3D(exclude_preview); @@ -22650,8 +22964,9 @@ bool Plater::can_copy_to_clipboard() const return true; } -bool Plater::can_undo() const { return IsShown() && p->is_view3D_shown() && p->undo_redo_stack().has_undo_snapshot(); } -bool Plater::can_redo() const { return IsShown() && p->is_view3D_shown() && p->undo_redo_stack().has_redo_snapshot(); } +// The job check keeps the buttons in step with priv::undo()/redo(), which refuse while one runs. +bool Plater::can_undo() const { return IsShown() && p->is_view3D_shown() && p->m_worker.is_idle() && p->undo_redo_stack().has_undo_snapshot(); } +bool Plater::can_redo() const { return IsShown() && p->is_view3D_shown() && p->m_worker.is_idle() && p->undo_redo_stack().has_redo_snapshot(); } bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); } //BBS bool Plater::can_fillcolor() const { return p->can_fillcolor(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 90d0e5e673..ebff1ff90d 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -672,6 +672,13 @@ public: GLCanvas3D* get_assmeble_canvas3D(); wxWindow* get_select_machine_dialog(); + // Docked UV-editor pane used by GLGizmoTextureDisplacement's LSCM projection preview (see + // UVEditorCanvas.hpp). Returns nullptr only before the main window is fully constructed. + class UVEditorCanvas* get_uv_editor_canvas(); + // Shows or hides the UV-editor AUI pane, updating its docked layout accordingly. Safe to call + // repeatedly (e.g. every time the gizmo's active layer/projection method changes). + void show_uv_editor(bool show); + void arrange(); void orient(); void find_new_position(const ModelInstancePtrs &instances); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 055449c35d..d9aedec79b 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1830,7 +1830,10 @@ void PreferencesDialog::create_items() auto item_mix_print_high_low_temperature = create_item_checkbox(_L("Remove mixed temperature restriction"), _L("With this option enabled, you can print materials with a large temperature difference together."), "enable_high_low_temp_mixed_printing"); g_sizer->Add(item_mix_print_high_low_temperature); - + + auto item_remember_print_action = create_item_checkbox(_L("Remember last print action"), _L("If enabled, OrcaSlicer will remember the last selected option in the print button's dropdown (e.g. Print, Export plate sliced file, Export G-code file) and use it as the default on next startup."), "remember_print_action"); + g_sizer->Add(item_remember_print_action); + //// CONTROL > Camera g_sizer->Add(create_item_title(_L("Camera")), 1, wxEXPAND); diff --git a/src/slic3r/GUI/PrintOptionsDialog.cpp b/src/slic3r/GUI/PrintOptionsDialog.cpp index d68bd24ccc..f03bcb1d29 100644 --- a/src/slic3r/GUI/PrintOptionsDialog.cpp +++ b/src/slic3r/GUI/PrintOptionsDialog.cpp @@ -1793,6 +1793,7 @@ wxString PrinterPartsDialog::GetString(NozzleFlowType nozzle_flow_type) const { case Slic3r::S_FLOW: return _L("Standard"); case Slic3r::H_FLOW: return _L("High flow"); case Slic3r::U_FLOW: return _L("TPU High flow"); + case Slic3r::E_FLOW: return _L("E3D High Flow"); default: break; } diff --git a/src/slic3r/GUI/PrivacyUpdateDialog.cpp b/src/slic3r/GUI/PrivacyUpdateDialog.cpp index c417767a42..c396e85bfe 100644 --- a/src/slic3r/GUI/PrivacyUpdateDialog.cpp +++ b/src/slic3r/GUI/PrivacyUpdateDialog.cpp @@ -57,9 +57,7 @@ PrivacyUpdateDialog::PrivacyUpdateDialog(wxWindow* parent, wxWindowID id, const fs::path ph(resources_dir()); ph /= "tooltip/privacyupdate.html"; - m_host_url = ph.string(); - std::replace(m_host_url.begin(), m_host_url.end(), '\\', '/'); - m_host_url = "file:///" + m_host_url; + m_host_url = into_u8(file_url_from_path(ph)); m_vebview_release_note->LoadURL(from_u8(m_host_url)); m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(15)); diff --git a/src/slic3r/GUI/Project.cpp b/src/slic3r/GUI/Project.cpp index 8d87939afc..127400c8b1 100644 --- a/src/slic3r/GUI/Project.cpp +++ b/src/slic3r/GUI/Project.cpp @@ -45,10 +45,10 @@ const std::vector license_list = { ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) : wxPanel(parent, id, pos, size, style) { SetBackgroundColour(*wxWHITE); - m_project_home_url = wxString::Format("file://%s/web/model/index.html", from_u8(resources_dir())); + m_project_home_url = file_url_from_path(boost::filesystem::path(resources_dir()) / "web/model/index.html"); wxString strlang = wxGetApp().current_language_code_safe(); if (strlang != "") - m_project_home_url = wxString::Format("file://%s/web/model/index.html?lang=%s", from_u8(resources_dir()), strlang); + m_project_home_url += "?lang=" + strlang; wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); @@ -293,10 +293,8 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt) if (!accessory_path.empty()) { std::string decode_path = wxGetApp().url_decode(accessory_path.ToStdString()); fs::path path(decode_path); - - if (fs::exists(path)) { - wxLaunchDefaultApplication(path.wstring(), 0); - } + if (!desktop_open_project_attachment(this, path)) + BOOST_LOG_TRIVIAL(warning) << "open_3mf_accessory: not opening " << decode_path; } } else if (strCmd == "request_3mf_info") { diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 6638133ed1..cb49da461a 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -512,7 +512,7 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve out_buf->append(text, size); }, (void*) &html_source, MD_DIALECT_GITHUB | MD_FLAG_STRIKETHROUGH | MD_FLAG_WIKILINKS, 0); html_source.append(""); - m_vebview_release_note->LoadURL("file://" + (boost::filesystem::path (resources_dir()) / "web/guide/0/index.html").string()); + m_vebview_release_note->LoadURL(file_url_from_path(boost::filesystem::path(resources_dir()) / "web/guide/0/index.html")); SetMinSize(GetSize()); SetMaxSize(GetSize()); @@ -1777,7 +1777,7 @@ void InputIpAddressDialog::set_machine_obj(MachineObject* obj) auto str_ip = m_input_ip->GetTextCtrl()->GetValue(); auto str_access_code = m_input_access_code->GetTextCtrl()->GetValue(); // ORCA enabling / disabling buttons with conditions enough to change its style - m_button_ok->Enable(isValidEndpoint(str_ip.ToStdString()) && + m_button_ok->Enable(isIp(str_ip.ToStdString()) && (str_access_code.IsEmpty() || str_access_code.Length() >= 8)); Layout(); @@ -1815,29 +1815,19 @@ void InputIpAddressDialog::update_test_msg(wxString msg,bool connected) Fit(); } -bool InputIpAddressDialog::isValidEndpoint(std::string endpoint) +bool InputIpAddressDialog::isIp(std::string ipstr) { - if (endpoint.empty() || std::any_of(endpoint.begin(), endpoint.end(), [](unsigned char c) { - return std::isspace(c) != 0; - })) - return false; - - const bool has_http_scheme = endpoint.rfind("http://", 0) == 0; - const bool has_https_scheme = endpoint.rfind("https://", 0) == 0; - const auto scheme_pos = endpoint.find("://"); - if (scheme_pos != std::string::npos && !has_http_scheme && !has_https_scheme) - return false; - - std::string port; - const std::string host = Http::get_host_from_url(endpoint, &port); - if (host.empty()) - return false; - - // get_host_from_url returns its input when libcurl cannot parse it. For a - // URL with a scheme, that means a failed parse still needs to be rejected. - if (scheme_pos != std::string::npos && host == endpoint) - return false; - + istringstream ipstream(ipstr); + int num[4]; + char point[3]; + string end; + ipstream >> num[0] >> point[0] >> num[1] >> point[1] >> num[2] >> point[2] >> num[3] >> end; + for (int i = 0; i < 3; ++i) { + if (num[i] < 0 || num[i]>255) return false; + if (point[i] != '.') return false; + } + if (num[3] < 0 || num[3]>255) return false; + if (!end.empty()) return false; return true; } @@ -2140,7 +2130,7 @@ void InputIpAddressDialog::on_text(wxCommandEvent &evt) // ORCA enabling / disabling buttons with conditions enough to change its style bool valid_access_code_length = str_access_code.IsEmpty() || str_access_code.Length() >= 8; - bool enable_btns = isValidEndpoint(str_ip.ToStdString()) && valid_access_code_length && invalid_access_code; + bool enable_btns = isIp(str_ip.ToStdString()) && valid_access_code_length && invalid_access_code; m_button_manual_setup->Enable(enable_btns); m_button_ok->Enable(enable_btns); diff --git a/src/slic3r/GUI/ReleaseNote.hpp b/src/slic3r/GUI/ReleaseNote.hpp index 5d950005df..5d7c0b25c4 100644 --- a/src/slic3r/GUI/ReleaseNote.hpp +++ b/src/slic3r/GUI/ReleaseNote.hpp @@ -348,7 +348,7 @@ public: void update_title(wxString title); void set_machine_obj(MachineObject* obj); void update_test_msg(wxString msg, bool connected); - bool isValidEndpoint(std::string endpoint); + bool isIp(std::string ipstr); void check_ip_address_failed(int result); void on_check_ip_address_failed(wxCommandEvent& evt); void on_ok(wxMouseEvent& evt); diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 30ccde08d4..e17ce782c5 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -78,6 +78,9 @@ std::string get_nozzle_volume_type_cloud_string(NozzleVolumeType nozzle_volume_t else if (nozzle_volume_type == NozzleVolumeType::nvtTPUHighFlow) { return "tpu_high_flow"; } + else if (nozzle_volume_type == NozzleVolumeType::nvtE3DHighFlow) { + return "e3d_high_flow"; + } else if (nozzle_volume_type == NozzleVolumeType::nvtHybrid) { // to be supported return "hybrid_flow"; @@ -2290,9 +2293,7 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector 1) msg_text = wxString::Format(_L("Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment."), params[0], params[1]); @@ -2318,7 +2319,7 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vectorvolumes) { - if (v->is_modifier()) + if (v->is_modifier() || v->is_precise_seam()) // Precise Seam not supported in SLA return false; } } diff --git a/src/slic3r/GUI/SendToPrinter.cpp b/src/slic3r/GUI/SendToPrinter.cpp index 07a88ee884..d582cfdef7 100644 --- a/src/slic3r/GUI/SendToPrinter.cpp +++ b/src/slic3r/GUI/SendToPrinter.cpp @@ -1410,74 +1410,60 @@ void SendToPrinterDialog::show_status(PrintDialogStatus status, std::vectorGetNozzleFlowType() == NozzleFlowType::U_FLOW) { flow_type_of_machine.push_back("TPU High Flow"); + } else if (it->GetNozzleFlowType() == NozzleFlowType::E_FLOW) { + flow_type_of_machine.push_back("E3D High Flow"); } } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index bf348f856f..b6f071fb45 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -506,7 +506,7 @@ void Tab::create_preset_tab() if (dynamic_cast(this) || dynamic_cast(this)) { m_extruder_switch = new MultiSwitchButton(panel); - m_extruder_switch->SetMaxSize({em_unit(this) * 40, -1}); + m_extruder_switch->SetFitToOptions(); m_extruder_switch->Bind(wxCUSTOMEVT_MULTISWITCH_SELECTION, [this](auto &evt) { evt.Skip(); int selection = evt.GetInt(); @@ -539,7 +539,8 @@ void Tab::create_preset_tab() auto right_sizer = new wxBoxSizer(wxHORIZONTAL); m_variant_sizer->AddStretchSpacer(1); - m_variant_sizer->Add(m_extruder_switch, 0, wxALIGN_CENTER, 0); + // Orca: proportion 1 lets a narrow row squeeze the switch, which then scrolls its buttons. + m_variant_sizer->Add(m_extruder_switch, 1, wxALIGN_CENTER, 0); m_variant_sizer->Add(right_sizer, 1, wxALIGN_CENTER); right_sizer->AddStretchSpacer(1); right_sizer->Add(m_extruder_sync_box, 0, wxALIGN_CENTER | wxRIGHT, m_em_unit); @@ -4395,16 +4396,17 @@ void TabFilament::build() optgroup->append_single_option_line("temperature_vitrification", "material_basic_information#softening-temperature"); optgroup->append_single_option_line("idle_temperature", "material_basic_information#idle-temperature"); Line line = { L("Recommended nozzle temperature"), L("Recommended nozzle temperature range of this filament. 0 means not set") }; - line.append_option(optgroup->get_option("nozzle_temperature_range_low")); - line.append_option(optgroup->get_option("nozzle_temperature_range_high")); + line.append_option(optgroup->get_option("nozzle_temperature_range_low", 0)); + line.append_option(optgroup->get_option("nozzle_temperature_range_high", 0)); optgroup->append_line(line); optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { DynamicPrintConfig &filament_config = m_preset_bundle->filaments.get_edited_preset().config; update_dirty(); - if (!m_postpone_update_ui && (opt_key == "nozzle_temperature_range_low" || opt_key == "nozzle_temperature_range_high")) { - m_config_manipulation.check_nozzle_recommended_temperature_range(&filament_config); + const std::string opt_key_without_idx = opt_key.substr(0, opt_key.find('#')); + if (!m_postpone_update_ui && (opt_key_without_idx == "nozzle_temperature_range_low" || opt_key_without_idx == "nozzle_temperature_range_high")) { + m_config_manipulation.check_nozzle_recommended_temperature_range(&filament_config, selected_variant_index()); } on_value_change(opt_key, value); }; @@ -4414,15 +4416,15 @@ void TabFilament::build() optgroup->append_single_option_line("pellet_flow_coefficient", "printer_basic_information_advanced#pellet-modded-printer"); optgroup->append_single_option_line("filament_flow_ratio", "material_flow_ratio_and_pressure_advance#flow-ratio", 0); - optgroup->append_single_option_line("enable_pressure_advance", "material_flow_ratio_and_pressure_advance#pressure-advance"); - optgroup->append_single_option_line("pressure_advance", "material_flow_ratio_and_pressure_advance#pressure-advance"); + optgroup->append_single_option_line("enable_pressure_advance", "material_flow_ratio_and_pressure_advance#pressure-advance", 0); + optgroup->append_single_option_line("pressure_advance", "material_flow_ratio_and_pressure_advance#pressure-advance", 0); // Orca: adaptive pressure advance and calibration model - optgroup->append_single_option_line("adaptive_pressure_advance", "material_flow_ratio_and_pressure_advance#enable-adaptive-pressure-advance-beta"); - optgroup->append_single_option_line("adaptive_pressure_advance_overhangs", "material_flow_ratio_and_pressure_advance#enable-adaptive-pressure-advance-for-overhangs-beta"); - optgroup->append_single_option_line("adaptive_pressure_advance_bridges", "material_flow_ratio_and_pressure_advance#pressure-advance-for-bridges"); + optgroup->append_single_option_line("adaptive_pressure_advance", "material_flow_ratio_and_pressure_advance#enable-adaptive-pressure-advance-beta", 0); + optgroup->append_single_option_line("adaptive_pressure_advance_overhangs", "material_flow_ratio_and_pressure_advance#enable-adaptive-pressure-advance-for-overhangs-beta", 0); + optgroup->append_single_option_line("adaptive_pressure_advance_bridges", "material_flow_ratio_and_pressure_advance#pressure-advance-for-bridges", 0); - Option option = optgroup->get_option("adaptive_pressure_advance_model"); + Option option = optgroup->get_option("adaptive_pressure_advance_model", 0); option.opt.full_width = true; option.opt.is_code = true; option.opt.height = 15; @@ -4431,7 +4433,7 @@ void TabFilament::build() DynamicPrintConfig& filament_config = m_preset_bundle->filaments.get_edited_preset().config; update_dirty(); - if (opt_key == "adaptive_pressure_advance_model") + if (opt_key.substr(0, opt_key.find('#')) == "adaptive_pressure_advance_model") m_config_manipulation.check_adaptive_pressure_advance_model(&filament_config); on_value_change(opt_key, value); @@ -4519,6 +4521,7 @@ void TabFilament::build() DynamicPrintConfig& filament_config = m_preset_bundle->filaments.get_edited_preset().config; update_dirty(); + const std::string opt_key_without_idx = opt_key.substr(0, opt_key.find('#')); /*if (opt_key == "cool_plate_temp" || opt_key == "cool_plate_temp_initial_layer") { m_config_manipulation.check_bed_temperature_difference(BedType::btPC, &filament_config); } @@ -4531,11 +4534,11 @@ void TabFilament::build() else if (opt_key == "textured_plate_temp" || opt_key == "textured_plate_temp_initial_layer") { m_config_manipulation.check_bed_temperature_difference(BedType::btPTE, &filament_config); } - else */if (opt_key == "nozzle_temperature") { - m_config_manipulation.check_nozzle_temperature_range(&filament_config); + else */if (opt_key_without_idx == "nozzle_temperature") { + m_config_manipulation.check_nozzle_temperature_range(&filament_config, selected_variant_index()); } - else if (opt_key == "nozzle_temperature_initial_layer") { - m_config_manipulation.check_nozzle_temperature_initial_layer_range(&filament_config); + else if (opt_key_without_idx == "nozzle_temperature_initial_layer") { + m_config_manipulation.check_nozzle_temperature_initial_layer_range(&filament_config, selected_variant_index()); } on_value_change(opt_key, value); @@ -4570,12 +4573,12 @@ void TabFilament::build() optgroup = page->new_optgroup(L("Part cooling fan"), L"param_cooling_part_fan"); line = { L("Min fan speed threshold"), L("The part cooling fan will run at the minimum fan speed when the estimated layer time is longer than the threshold value. When the layer time is shorter than the threshold, the fan speed will be interpolated between the minimum and maximum fan speed according to layer printing time.") }; line.label_path = "material_cooling#material-part-cooling-fan"; - line.append_option(optgroup->get_option("fan_min_speed")); + line.append_option(optgroup->get_option("fan_min_speed", 0)); line.append_option(optgroup->get_option("fan_cooling_layer_time")); optgroup->append_line(line); line = { L("Max fan speed threshold"), L("The part cooling fan will run at maximum speed when the estimated layer time is shorter than the threshold value.") }; line.label_path = "material_cooling#material-part-cooling-fan"; - line.append_option(optgroup->get_option("fan_max_speed")); + line.append_option(optgroup->get_option("fan_max_speed", 0)); line.append_option(optgroup->get_option("slow_down_layer_time")); optgroup->append_line(line); optgroup->append_single_option_line("reduce_fan_stop_start_freq", "material_cooling#keep-fan-always-on"); @@ -4591,7 +4594,7 @@ void TabFilament::build() optgroup->append_single_option_line("ironing_fan_speed", "material_cooling#ironing-fan-speed"); // ORCA: Add support for ironing fan speed control optgroup = page->new_optgroup(L("Auxiliary part cooling fan"), L"param_cooling_aux_fan"); - optgroup->append_single_option_line("additional_cooling_fan_speed", "material_cooling#auxiliary-part-cooling-fan"); + optgroup->append_single_option_line("additional_cooling_fan_speed", "material_cooling#auxiliary-part-cooling-fan", 0); optgroup = page->new_optgroup(L("Exhaust fan"),L"param_cooling_exhaust"); @@ -4655,7 +4658,7 @@ void TabFilament::build() page = add_options_page(L("Multimaterial"), "custom-gcode_multi_material"); // ORCA: icon only visible on placeholders optgroup = page->new_optgroup(L("Wipe tower parameters"), "param_tower"); - optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower", "material_multimaterial#multimaterial-wipe-tower-parameters"); + optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower", "material_multimaterial#multimaterial-wipe-tower-parameters", 0); optgroup->append_single_option_line("filament_tower_interface_pre_extrusion_dist", "material_multimaterial#multimaterial-wipe-tower-parameters"); optgroup->append_single_option_line("filament_tower_interface_pre_extrusion_length", "material_multimaterial#multimaterial-wipe-tower-parameters"); optgroup->append_single_option_line("filament_tower_ironing_area", "material_multimaterial#multimaterial-wipe-tower-parameters"); @@ -4699,9 +4702,9 @@ void TabFilament::build() }); optgroup = page->new_optgroup(L("Tool change parameters with multi extruder MM printers"), "param_toolchange_multi_extruder"); - optgroup->append_single_option_line("filament_multitool_ramming", "material_multimaterial#tool-change-parameters-with-multi-extruder"); - optgroup->append_single_option_line("filament_multitool_ramming_volume", "material_multimaterial#multi-tool-ramming-volume"); - optgroup->append_single_option_line("filament_multitool_ramming_flow", "material_multimaterial#multi-tool-ramming-flow"); + optgroup->append_single_option_line("filament_multitool_ramming", "material_multimaterial#tool-change-parameters-with-multi-extruder", 0); + optgroup->append_single_option_line("filament_multitool_ramming_volume", "material_multimaterial#multi-tool-ramming-volume", 0); + optgroup->append_single_option_line("filament_multitool_ramming_flow", "material_multimaterial#multi-tool-ramming-flow", 0); page = add_options_page(L("Dependencies"), "advanced"); optgroup = page->new_optgroup(L("Compatible printers"), "param_dependencies_printers"); @@ -4769,8 +4772,14 @@ void TabFilament::update_description_lines() // this->update_volumetric_flow_preset_hints(); } +unsigned int TabFilament::selected_variant_index() const +{ + return m_variant_combo ? std::max(0, m_variant_combo->GetSelection()) : 0; +} + void TabFilament::toggle_options() { + const unsigned int variant_index = selected_variant_index(); if (!m_active_page) return; bool is_BBL_printer = false; @@ -4812,7 +4821,7 @@ void TabFilament::toggle_options() } } - toggle_line("additional_cooling_fan_speed", printer_cfg.opt_bool("auxiliary_fan")); + toggle_line("additional_cooling_fan_speed", printer_cfg.opt_bool("auxiliary_fan"), 256 + variant_index); bool support_air_filtration = printer_cfg.opt_bool("support_air_filtration"); for (auto el : {"activate_air_filtration", "during_print_exhaust_fan_speed", "complete_print_exhaust_fan_speed"}) @@ -4828,8 +4837,8 @@ void TabFilament::toggle_options() } if (m_active_page->title() == L("Filament")) { - bool pa = m_config->opt_bool("enable_pressure_advance", 0); - toggle_option("pressure_advance", pa); + bool pa = m_config->opt_bool("enable_pressure_advance", variant_index); + toggle_option("pressure_advance", pa, 256 + variant_index); //Orca: Enable the plates that should be visible when multi bed support is enabled or a BBL printer is selected; otherwise, enable only the plate visible for the selected bed type. DynamicConfig& proj_cfg = m_preset_bundle->project_config; @@ -4857,12 +4866,12 @@ void TabFilament::toggle_options() // Orca: adaptive pressure advance and calibration model // If PA is not enabled, disable adaptive pressure advance and hide the model section // If adaptive PA is not enabled, hide the adaptive PA model section - toggle_option("adaptive_pressure_advance", pa); - toggle_option("adaptive_pressure_advance_overhangs", pa); - bool has_adaptive_pa = m_config->opt_bool("adaptive_pressure_advance", 0); - toggle_line("adaptive_pressure_advance_overhangs", has_adaptive_pa && pa); - toggle_line("adaptive_pressure_advance_model", has_adaptive_pa && pa); - toggle_line("adaptive_pressure_advance_bridges", has_adaptive_pa && pa); + toggle_option("adaptive_pressure_advance", pa, 0); + toggle_option("adaptive_pressure_advance_overhangs", pa, 0); + bool has_adaptive_pa = m_config->opt_bool("adaptive_pressure_advance", variant_index); + toggle_line("adaptive_pressure_advance_overhangs", has_adaptive_pa && pa, 0); + toggle_line("adaptive_pressure_advance_model", has_adaptive_pa && pa, 0); + toggle_line("adaptive_pressure_advance_bridges", has_adaptive_pa && pa, 0); bool is_pellet_printer = printer_cfg.opt_bool("pellet_modded_printer"); toggle_line("pellet_flow_coefficient", is_pellet_printer); @@ -4870,11 +4879,9 @@ void TabFilament::toggle_options() toggle_line("activate_chamber_temp_control", printer_cfg.opt_bool("support_chamber_temp_control")); - const int selection = m_variant_combo ? m_variant_combo->GetSelection() : 0; - const unsigned int variant_idx = (unsigned int) std::max(selection, 0); - std::string volumetric_speed_cos = m_config->opt_string("volumetric_speed_coefficients", variant_idx); + std::string volumetric_speed_cos = m_config->opt_string("volumetric_speed_coefficients", variant_index); bool enable_fit = volumetric_speed_cos != "0 0 0 0 0 0"; - toggle_option("filament_adaptive_volumetric_speed", enable_fit, 256 + variant_idx); + toggle_option("filament_adaptive_volumetric_speed", enable_fit, 256 + variant_index); } if (m_active_page->title() == L("Setting Overrides")) @@ -4882,20 +4889,19 @@ void TabFilament::toggle_options() if (m_active_page->title() == L("Multimaterial")) { // Orca: hide specific settings for BBL printers - for (auto el : {"filament_minimal_purge_on_wipe_tower", "filament_loading_speed_start", "filament_loading_speed", + toggle_option("filament_minimal_purge_on_wipe_tower", !is_BBL_printer, 256 + variant_index); + for (auto el : {"filament_loading_speed_start", "filament_loading_speed", "filament_unloading_speed_start", "filament_unloading_speed", "filament_toolchange_delay", "filament_cooling_moves", "filament_cooling_initial_speed", "filament_cooling_final_speed"}) toggle_option(el, !is_BBL_printer); - bool multitool_ramming = m_config->opt_bool("filament_multitool_ramming", 0); - toggle_option("filament_multitool_ramming_volume", multitool_ramming); - toggle_option("filament_multitool_ramming_flow", multitool_ramming); + bool multitool_ramming = m_config->opt_bool("filament_multitool_ramming", variant_index); + toggle_option("filament_multitool_ramming_volume", multitool_ramming, 256 + variant_index); + toggle_option("filament_multitool_ramming_flow", multitool_ramming, 256 + variant_index); bool is_BBL_multi_extruder = is_BBL_printer && printer_cfg.option("nozzle_diameter")->size() > 1; - const int selection = m_variant_combo ? m_variant_combo->GetSelection() : 0; - const int extruder_idx = std::max(selection, 0); - toggle_line("long_retractions_when_ec", is_BBL_multi_extruder, 256 + extruder_idx); - toggle_line("retraction_distances_when_ec", is_BBL_multi_extruder && m_config->opt_bool("long_retractions_when_ec", extruder_idx), 256 + extruder_idx); + toggle_line("long_retractions_when_ec", is_BBL_multi_extruder, 256 + variant_index); + toggle_line("retraction_distances_when_ec", is_BBL_multi_extruder && m_config->opt_bool("long_retractions_when_ec", variant_index), 256 + variant_index); } } @@ -5204,7 +5210,6 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("adaptive_bed_mesh_margin", "printer_basic_information_adaptive_bed_mesh#mesh-margin"); optgroup = page->new_optgroup(L("Accessory"), "param_accessory"); - optgroup->append_single_option_line("nozzle_type", "printer_basic_information_accessory#nozzle-type", 0); optgroup->append_single_option_line("nozzle_hrc", "printer_basic_information_accessory#nozzle-hrc"); optgroup->append_single_option_line("auxiliary_fan", "printer_basic_information_accessory#auxiliary-part-cooling-fan"); optgroup->append_single_option_line("fan_direction"); @@ -5719,6 +5724,7 @@ if (is_marlin_flavor) auto optgroup = page->new_optgroup(L("Basic information"), L"param_information", -1, true); optgroup->append_single_option_line("nozzle_diameter", "printer_extruder_basic_information#nozzle-diameter", extruder_idx); + optgroup->append_single_option_line("nozzle_type", "printer_basic_information_accessory#nozzle-type", extruder_idx); //optgroup->append_single_option_line("nozzle_volume_type", "", extruder_idx); optgroup->append_single_option_line("nozzle_volume", "printer_extruder_basic_information#nozzle-volume", extruder_idx); @@ -5730,7 +5736,7 @@ if (is_marlin_flavor) optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value) { bool is_SEMM = m_config->opt_bool("single_extruder_multi_material"); - if (is_SEMM && m_extruders_count > 1 && opt_key.find_first_of("nozzle_diameter") != std::string::npos) + if (is_SEMM && m_extruders_count > 1 && boost::starts_with(opt_key, "nozzle_diameter")) { SuppressBackgroundProcessingUpdate sbpu; const double new_nd = boost::any_cast(value); @@ -8172,7 +8178,7 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) // Orca: a non-Bambu dual-nozzle printer has two extruders but a single variant column, so // the nozzle switch and sync button have nothing to act on. Only enable with real variants. - if (extruder_nums == 2 && m_preset_bundle->support_different_extruders()) { + if (extruder_nums >= 2 && m_preset_bundle->support_different_extruders()) { auto options = generate_extruder_options(); m_extruder_switch->SetOptions(options); @@ -8219,6 +8225,25 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) } } +// The variant switch tags are the narrowest place a volume type is named, so they abbreviate it; +// the flow combo boxes and the Printer tab's parameter labels keep the full names. +static wxString short_nozzle_volume_name(const std::string &volume_name) +{ + // Hybrid has no entry on purpose: it is never a variant string, and the switch lists its two + // sub-nozzle types as separate tags (see generate_extruder_options). + if (volume_name == "Standard") + return "SF"; + if (volume_name == "High Flow") + return "HF"; + if (volume_name == "TPU High Flow") + return "TPU HF"; + if (volume_name == "E3D High Flow") + return "E3D HF"; + if (volume_name == "Extra High Flow") + return "XHF"; + return from_u8(volume_name); +} + std::vector Tab::generate_extruder_options() { std::vector options; @@ -8259,7 +8284,7 @@ std::vector Tab::generate_extruder_options() nozzle = ""; } } - options.push_back(wxString::Format(_L("%s: %s"), _L(drive), _L(nozzle))); + options.push_back(wxString::Format(_L("%s: %s"), _L(drive), short_nozzle_volume_name(nozzle))); } return options; } @@ -8273,18 +8298,22 @@ std::vector Tab::generate_extruder_options() } std::string pt = m_preset_bundle->printers.get_edited_preset().get_printer_type(m_preset_bundle); + // Orca: the main/deputy toolhead names describe a dual-nozzle printer, where extruder 0 is the + // left (deputy) and extruder 1 the right (main) nozzle. From three extruders on the tools are + // interchangeable, so name them by index instead of repeating one side. for (int i = 0; i < extruder_nums; ++i) { - int ext_id = (i == 0) ? DEPUTY_EXTRUDER_ID : MAIN_EXTRUDER_ID; - wxString extruder_name = _L(DevPrinterConfigUtil::get_toolhead_display_name( - pt, ext_id, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase, true)); + wxString extruder_name = extruder_nums > 2 ? wxString::Format("T%d", i + 1) : + _L(DevPrinterConfigUtil::get_toolhead_display_name( + pt, (i == 0) ? DEPUTY_EXTRUDER_ID : MAIN_EXTRUDER_ID, + ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase, true)); NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]); if (volume_type == NozzleVolumeType::nvtHybrid) { - options.push_back(wxString::Format(_L("%s: %s"), extruder_name, _L("Standard"))); - options.push_back(wxString::Format(_L("%s: %s"), extruder_name, _L("High Flow"))); + options.push_back(wxString::Format(_L("%s: %s"), extruder_name, short_nozzle_volume_name(get_nozzle_volume_type_string(NozzleVolumeType::nvtStandard)))); + options.push_back(wxString::Format(_L("%s: %s"), extruder_name, short_nozzle_volume_name(get_nozzle_volume_type_string(NozzleVolumeType::nvtHighFlow)))); } else { - wxString volume_name = get_nozzle_volume_type_name(volume_type); - options.push_back(wxString::Format(_L("%s: %s"), extruder_name, volume_name)); + options.push_back(wxString::Format(_L("%s: %s"), extruder_name, + short_nozzle_volume_name(get_nozzle_volume_type_string(volume_type)))); } } return options; @@ -8315,7 +8344,10 @@ bool Tab::get_extruder_sync_enable_state(int extruder_id) Preset& printer_preset = m_preset_bundle->printers.get_edited_preset(); auto nozzle_volumes = m_preset_bundle->project_config.option("nozzle_volume_type"); auto extruders = printer_preset.config.option("extruder_type"); - if (nozzle_volumes->values.size() < 2 || extruders->values.size() < 2) { + // Orca: every rule below describes the two toolheads of a dual-nozzle printer as left/right. + // A printer with any other extruder count has no single counterpart to copy to, so it gets no + // sync button (a toolchanger would need a target to be chosen). + if (nozzle_volumes->values.size() != 2 || extruders->values.size() != 2) { return false; } @@ -8456,6 +8488,10 @@ void Tab::sync_excluder() ExtruderType(extruders->values[extruder_id]), nozzle_type, variant_keys.second, stride); }; int active_index = get_current_active_extruder(); + // The button copies to the other toolhead, so it is only offered when that other one exists; + // without this the `1 - active_index` below would index an extruder that is not there. + if (!get_extruder_sync_enable_state(active_index)) + return; auto active_nozzle = get_actual_nozzle_volume_type(active_index); int from_index = get_index_for_extruder(active_index, active_nozzle); int dest_index = get_index_for_extruder(1 - active_index, active_nozzle); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index fa8a7ae68b..98428b148e 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -616,6 +616,8 @@ private: void add_filament_overrides_page(); void update_filament_overrides_page(const DynamicPrintConfig* printers_config); void update_volumetric_flow_preset_hints(); + // The variant index the variant switch shows, 0 without one. + unsigned int selected_variant_index() const; std::map m_overrides_options; diff --git a/src/slic3r/GUI/TextureLibrary.cpp b/src/slic3r/GUI/TextureLibrary.cpp new file mode 100644 index 0000000000..7cbd50a240 --- /dev/null +++ b/src/slic3r/GUI/TextureLibrary.cpp @@ -0,0 +1,373 @@ +#include "TextureLibrary.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "libslic3r/PNGReadWrite.hpp" +#include "libslic3r/Utils.hpp" + +#include "libslic3r/AppConfig.hpp" + +#include "slic3r/GUI/GUI.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/I18N.hpp" + +namespace Slic3r::GUI { + +namespace { + +// Extensions the picker will list. The shipped folder only ever contains .png; the rest are here +// so a user who drops a .jpg straight into their own folder still sees it (load_texture_image_data() +// converts anything it can open). +bool is_image_file(const boost::filesystem::path &path) +{ + std::string ext = path.extension().string(); + boost::algorithm::to_lower(ext); + return ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".bmp"; +} + +void scan_dir(const boost::filesystem::path &dir, bool is_user, std::vector &out) +{ + boost::system::error_code ec; + if (!boost::filesystem::is_directory(dir, ec)) + return; + + const size_t first = out.size(); + for (boost::filesystem::directory_iterator it(dir, ec), end; it != end && !ec; it.increment(ec)) { + if (!boost::filesystem::is_regular_file(it->path(), ec) || !is_image_file(it->path())) + continue; + out.push_back({ it->path().stem().string(), it->path().string(), is_user }); + } + std::sort(out.begin() + first, out.end(), + [](const TextureLibraryEntry &a, const TextureLibraryEntry &b) { return a.name < b.name; }); +} + +// True if the image carries any colour at all, i.e. some pixel's channels are not all equal. A +// photo saved as RGB but actually grey should still be stored as a grayscale PNG - it is a third of +// the bytes, and the colour feature keys off has_color(), so storing a grey image as RGB would offer +// the user a "colour" that is a row of identical greys. +bool image_has_color(const wxImage &image) +{ + const unsigned char *rgb = image.GetData(); + if (rgb == nullptr) + return false; + const size_t n = size_t(image.GetWidth()) * size_t(image.GetHeight()); + for (size_t i = 0; i < n; ++i) + if (rgb[i * 3] != rgb[i * 3 + 1] || rgb[i * 3 + 1] != rgb[i * 3 + 2]) + return true; + return false; +} + +// Colour images are stored as-is (as an RGB PNG) so the texture can colour the model as well as +// displace it; decode_height_texture() takes the height from their luminance, with the same +// coefficients ConvertToGreyscale() uses, so the relief is identical either way. wxImage writes the +// PNG here rather than Slic3r::png, which only encodes grayscale. +bool encode_color_png_bytes(const wxImage &image, std::vector &out, std::string &error) +{ + if (image.GetWidth() <= 0 || image.GetHeight() <= 0) { + error = _u8L("The selected image is empty."); + return false; + } + wxMemoryOutputStream stream; + // Alpha would be lost on the way into DecodedHeightTexture anyway, and a partly transparent + // texture reading as black relief is worse than reading as its own colour over the background. + wxImage opaque = image; + if (opaque.HasAlpha()) + opaque.ClearAlpha(); + if (!opaque.SaveFile(stream, wxBITMAP_TYPE_PNG)) { + error = _u8L("Failed to prepare the texture for use."); + return false; + } + const size_t size = size_t(stream.GetLength()); + out.resize(size); + stream.CopyTo(out.data(), size); + if (out.empty()) { + error = _u8L("Failed to prepare the texture for use."); + return false; + } + return true; +} + +// Slic3r::png only writes PNGs to a file, so the encode round-trips through a temp file rather than +// staying in memory. It happens once per import / per texture pick, not per frame, so the I/O is +// not worth avoiding with a second PNG encoder. +bool encode_gray_png_bytes(const wxImage &image, std::vector &out, std::string &error) +{ + const wxImage gray = image.ConvertToGreyscale(); + const int w = gray.GetWidth(); + const int h = gray.GetHeight(); + if (w <= 0 || h <= 0) { + error = _u8L("The selected image is empty."); + return false; + } + + // wxImage always stores 3 bytes per pixel; after ConvertToGreyscale the three are equal. + std::vector pixels(size_t(w) * size_t(h)); + const unsigned char *rgb = gray.GetData(); + for (size_t i = 0; i < pixels.size(); ++i) + pixels[i] = rgb[i * 3]; + + const boost::filesystem::path tmp = boost::filesystem::temp_directory_path() + / boost::filesystem::unique_path("orca_texdisp_%%%%%%%%.png"); + if (!Slic3r::png::write_gray_to_file(tmp.string(), size_t(w), size_t(h), pixels)) { + error = _u8L("Failed to prepare the texture for use."); + return false; + } + + { + std::ifstream ifs(tmp.string(), std::ios::binary); + out.assign(std::istreambuf_iterator(ifs), std::istreambuf_iterator()); + } + boost::system::error_code ec; + boost::filesystem::remove(tmp, ec); + + if (out.empty()) { + error = _u8L("Failed to prepare the texture for use."); + return false; + } + return true; +} + +// Grayscale in, grayscale out; colour in, colour out. +bool encode_png_bytes(const wxImage &image, std::vector &out, std::string &error) +{ + return image_has_color(image) ? encode_color_png_bytes(image, out, error) + : encode_gray_png_bytes(image, out, error); +} + +std::vector read_file_bytes(const std::string &path) +{ + std::ifstream ifs(path, std::ios::binary); + return std::vector(std::istreambuf_iterator(ifs), std::istreambuf_iterator()); +} + +// True if these bytes are a PNG libslic3r can decode, i.e. can be stored on a layer as-is. Mirrors +// exactly what decode_height_texture() accepts: 8-bit grayscale, or 8-bit colour (whose luminance is +// the height and whose RGB is available to colour the model). Anything else is converted on load. +bool is_supported_height_map(const std::vector &bytes) +{ + if (bytes.empty()) + return false; + const png::ReadBuf rbuf{ bytes.data(), bytes.size() }; + if (!png::is_png(rbuf)) + return false; + png::ImageGreyscale gray; + if (png::decode_png(rbuf, gray) && gray.cols > 0 && gray.rows > 0) + return true; + png::ImageColorscale color; + return png::decode_colored_png(rbuf, color) && color.cols > 0 && color.rows > 0 && + color.bytes_per_pixel >= 3 && + color.buf.size() == color.cols * color.rows * size_t(color.bytes_per_pixel); +} + +std::vector g_library; +bool g_library_scanned = false; + +// The user's own textures, most recently used first, kept in the app config. File names are stored rather +// than paths so the order survives a moved data directory; '/' separates them because no platform allows +// it inside a file name. Bounded so a long-lived config does not grow a line without end. +const char *const RECENT_SECTION = "texture_displacement"; +const char *const RECENT_KEY = "recent_textures"; +const size_t RECENT_MAX = 200; + +std::vector recent_texture_names() +{ + std::vector names; + if (wxGetApp().app_config == nullptr) + return names; + const std::string value = wxGetApp().app_config->get(RECENT_SECTION, RECENT_KEY); + for (size_t begin = 0; begin <= value.size();) { + const size_t end = std::min(value.find('/', begin), value.size()); + if (end > begin) + names.push_back(value.substr(begin, end - begin)); + begin = end + 1; + } + return names; +} + +void store_recent_texture_names(std::vector names) +{ + if (wxGetApp().app_config == nullptr) + return; + if (names.size() > RECENT_MAX) + names.resize(RECENT_MAX); + std::string value; + for (const std::string &name : names) + value += (value.empty() ? "" : "/") + name; + wxGetApp().app_config->set(RECENT_SECTION, RECENT_KEY, value); +} + +// Reorders the user's entries (the tail of `library`) by recent use. Stable, so textures never used keep +// the name order scan_dir() gave them, after every used one. +void sort_user_textures(std::vector &library) +{ + const std::vector names = recent_texture_names(); + std::unordered_map rank; + for (size_t i = 0; i < names.size(); ++i) + rank.emplace(names[i], int(i)); + const auto rank_of = [&rank](const TextureLibraryEntry &e) { + const auto it = rank.find(boost::filesystem::path(e.path).filename().string()); + return it == rank.end() ? std::numeric_limits::max() : it->second; + }; + const auto first_user = std::find_if(library.begin(), library.end(), [](const TextureLibraryEntry &e) { return e.is_user; }); + std::stable_sort(first_user, library.end(), + [&rank_of](const TextureLibraryEntry &a, const TextureLibraryEntry &b) { return rank_of(a) < rank_of(b); }); +} + +// True if `path` is a file directly inside user_texture_dir() - the only place textures may be removed +// from, or have their use recorded. +bool in_user_texture_dir(const std::string &path) +{ + const std::string dir = user_texture_dir(); + if (dir.empty()) + return false; + boost::system::error_code ec; + const bool same = boost::filesystem::equivalent(boost::filesystem::path(path).parent_path(), + boost::filesystem::path(dir), ec); + return !ec && same; +} + +} // namespace + +std::string user_texture_dir() +{ + const boost::filesystem::path dir = boost::filesystem::path(Slic3r::data_dir()) / "textures" / "displacement"; + boost::system::error_code ec; + boost::filesystem::create_directories(dir, ec); + if (ec) { + BOOST_LOG_TRIVIAL(error) << "Could not create the user texture directory " << dir.string() << ": " << ec.message(); + return {}; + } + return dir.string(); +} + +const std::vector &texture_library(bool force_rescan) +{ + if (g_library_scanned && !force_rescan) + return g_library; + + g_library.clear(); + scan_dir(boost::filesystem::path(Slic3r::resources_dir()) / "textures" / "displacement", false, g_library); + const std::string user_dir = user_texture_dir(); + if (!user_dir.empty()) + scan_dir(boost::filesystem::path(user_dir), true, g_library); + sort_user_textures(g_library); + + g_library_scanned = true; + return g_library; +} + +void touch_user_texture(const std::string &path) +{ + if (!in_user_texture_dir(path)) + return; + const std::string name = boost::filesystem::path(path).filename().string(); + std::vector names = recent_texture_names(); + names.erase(std::remove(names.begin(), names.end(), name), names.end()); + names.insert(names.begin(), name); + store_recent_texture_names(std::move(names)); + if (g_library_scanned) + sort_user_textures(g_library); +} + +bool remove_user_texture(const std::string &path, std::string &error) +{ + if (!in_user_texture_dir(path)) { + error = _u8L("Only your own imported textures can be removed."); + return false; + } + boost::system::error_code ec; + boost::filesystem::remove(boost::filesystem::path(path), ec); + if (ec) { + BOOST_LOG_TRIVIAL(error) << "Could not delete texture " << path << ": " << ec.message(); + error = _u8L("Could not delete the texture file."); + return false; + } + + const std::string name = boost::filesystem::path(path).filename().string(); + std::vector names = recent_texture_names(); + names.erase(std::remove(names.begin(), names.end(), name), names.end()); + store_recent_texture_names(std::move(names)); + texture_library(true); // drop it from the list + return true; +} + +std::optional import_texture_to_library(const std::string &source_path, std::string &error) +{ + const std::string user_dir = user_texture_dir(); + if (user_dir.empty()) { + error = _u8L("Could not create the folder for imported textures."); + return std::nullopt; + } + + wxImage image; + if (!image.LoadFile(from_u8(source_path)) || !image.IsOk()) { + error = _u8L("Could not load the selected image."); + return std::nullopt; + } + + std::vector bytes; + if (!encode_png_bytes(image, bytes, error)) + return std::nullopt; + + // Never overwrite an existing texture (the user's or, if they picked the same name twice, their + // own earlier import) - uniquify instead. + const std::string stem = boost::filesystem::path(source_path).stem().string(); + boost::filesystem::path dest = boost::filesystem::path(user_dir) / (stem + ".png"); + for (int i = 2; boost::filesystem::exists(dest); ++i) + dest = boost::filesystem::path(user_dir) / (stem + " (" + std::to_string(i) + ").png"); + + { + boost::nowide::ofstream ofs(dest.string(), std::ios::binary); + ofs.write(reinterpret_cast(bytes.data()), std::streamsize(bytes.size())); + if (!ofs.good()) { + error = _u8L("Failed to save the imported texture."); + return std::nullopt; + } + } + + texture_library(true); // pick the new file up + const std::string dest_str = dest.string(); + for (const TextureLibraryEntry &e : g_library) + if (e.path == dest_str) + return e; + + error = _u8L("Failed to save the imported texture."); + return std::nullopt; +} + +std::shared_ptr> load_texture_image_data(const std::string &path, std::string &error) +{ + std::vector bytes = read_file_bytes(path); + if (bytes.empty()) { + error = _u8L("Could not read the texture file."); + return nullptr; + } + if (is_supported_height_map(bytes)) + return std::make_shared>(std::move(bytes)); + + // Not a PNG at all (a jpg somebody copied into the folder by hand, say): convert it the same way + // an import would - keeping its colour if it has any - but leave the file on disk alone. + wxImage image; + if (!image.LoadFile(from_u8(path)) || !image.IsOk()) { + error = _u8L("Could not load the selected image."); + return nullptr; + } + std::vector converted; + if (!encode_png_bytes(image, converted, error)) + return nullptr; + return std::make_shared>(std::move(converted)); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/TextureLibrary.hpp b/src/slic3r/GUI/TextureLibrary.hpp new file mode 100644 index 0000000000..65b35bcea8 --- /dev/null +++ b/src/slic3r/GUI/TextureLibrary.hpp @@ -0,0 +1,62 @@ +#ifndef slic3r_TextureLibrary_hpp_ +#define slic3r_TextureLibrary_hpp_ + +#include +#include +#include +#include + +namespace Slic3r::GUI { + +// One selectable height-map texture in the texture-displacement gizmo's texture picker. +struct TextureLibraryEntry +{ + std::string name; // display name (the file's stem, e.g. "Wood Grain") + std::string path; // absolute path on disk + bool is_user; // imported by the user, as opposed to shipped with OrcaSlicer +}; + +// Every available height-map texture: the ones shipped in resources/textures/displacement first, sorted +// by name, then the user's own from /textures/displacement - most recently used first (see +// touch_user_texture()), then any never used, by name. +// +// The two live in separate directories deliberately: an app update replaces the resources tree +// wholesale, so anything the user imported has to sit somewhere that update can never overwrite or +// delete. `is_user` is what the picker uses to show them under separate headings. +// +// Scanned once and cached. Pass force_rescan after an import, or to pick up a file the user dropped +// into either folder by hand while the app was running. +const std::vector &texture_library(bool force_rescan = false); + +// Moves one of the user's own textures to the front of the recently-used order texture_library() lists +// them in, and stores that order in the app config so it survives a restart. No-op for anything that is +// not in user_texture_dir(). +void touch_user_texture(const std::string &path); + +// Deletes one of the user's own imported textures from user_texture_dir() and forgets it. Anything outside +// that folder is refused, so a shipped texture can never be removed this way. Layers already using the +// texture are unaffected: they hold the image bytes themselves, and a project stores those. Returns false +// with `error` set on failure. +bool remove_user_texture(const std::string &path, std::string &error); + +// /textures/displacement, created if it does not exist yet. Empty string on failure. +std::string user_texture_dir(); + +// Reads any image format wxWidgets can open, converts it to the 8-bit grayscale PNG that +// libslic3r's decode_height_texture() understands, and saves it into user_texture_dir() (uniquified +// if that name is taken). The conversion has to happen here rather than in libslic3r, which has no +// image toolkit and so only ever handles the one already-normalized format. +// +// Returns the newly imported entry, or nullopt with `error` set. `source_path` is only read. +std::optional import_texture_to_library(const std::string &source_path, std::string &error); + +// Encoded bytes of `path`, ready to hand to TextureDisplacementLayer::image_data. Files already in +// the supported 8-bit grayscale PNG form (everything in the two library folders, by construction) +// are passed through verbatim; anything else - e.g. a colour PNG the user copied into the folder +// by hand - is converted on the fly, so a valid image never silently produces a blank layer. +// Returns nullptr with `error` set if the file cannot be read or decoded at all. +std::shared_ptr> load_texture_image_data(const std::string &path, std::string &error); + +} // namespace Slic3r::GUI + +#endif // slic3r_TextureLibrary_hpp_ diff --git a/src/slic3r/GUI/TextureProjectorFrame.cpp b/src/slic3r/GUI/TextureProjectorFrame.cpp new file mode 100644 index 0000000000..cfa29967ad --- /dev/null +++ b/src/slic3r/GUI/TextureProjectorFrame.cpp @@ -0,0 +1,97 @@ +#include "TextureProjectorFrame.hpp" + +#include + +#include +#include + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/I18N.hpp" + +namespace Slic3r { namespace GUI { + +TextureProjectorFrame::TextureProjectorFrame(wxWindow *parent) + : wxFrame(parent, wxID_ANY, _L("Projection frame - drag over the model, then Apply"), wxDefaultPosition, + wxSize(360, 360), + // Caption and resize border so moving and sizing are the native gestures the user + // already knows - "align it by moving the window" only works if the window moves the + // ordinary way. FLOAT_ON_PARENT keeps it above the 3D view without the antisocial + // always-on-top-of-everything behaviour of wxSTAY_ON_TOP. + wxCAPTION | wxRESIZE_BORDER | wxCLOSE_BOX | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT) +{ + SetBackgroundStyle(wxBG_STYLE_PAINT); + Bind(wxEVT_PAINT, &TextureProjectorFrame::on_paint, this); + // A resize changes the gate, so the texture has to be re-stretched under it. + Bind(wxEVT_SIZE, [this](wxSizeEvent &evt) { Refresh(); evt.Skip(); }); + SetTransparent(wxByte(m_alpha)); + + // Hide rather than destroy: the gizmo owns this window's lifetime, and reopening should keep the + // frame exactly where it was left - its position is the placement. + Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt) { + if (evt.CanVeto()) { + evt.Veto(); + Hide(); + } else + evt.Skip(); + }); +} + +void TextureProjectorFrame::set_texture(const std::vector &gray, int width, int height) +{ + if (width <= 0 || height <= 0 || gray.size() < size_t(width) * size_t(height)) { + m_bitmap = wxBitmap(); + Refresh(); + return; + } + + wxImage img(width, height); + unsigned char *dst = img.GetData(); + for (size_t i = 0, n = size_t(width) * size_t(height); i < n; ++i) { + const unsigned char v = gray[i]; + dst[i * 3 + 0] = v; + dst[i * 3 + 1] = v; + dst[i * 3 + 2] = v; + } + m_bitmap = wxBitmap(img); + Refresh(); +} + +void TextureProjectorFrame::set_opacity(int alpha) +{ + m_alpha = std::clamp(alpha, 20, 255); + SetTransparent(wxByte(m_alpha)); + Refresh(); +} + +wxRect TextureProjectorFrame::client_rect_on_screen() const +{ + const wxSize sz = GetClientSize(); + return wxRect(ClientToScreen(wxPoint(0, 0)), sz); +} + +void TextureProjectorFrame::on_paint(wxPaintEvent &) +{ + wxPaintDC dc(this); + const wxSize sz = GetClientSize(); + if (sz.x <= 0 || sz.y <= 0) + return; + + dc.SetBackground(wxBrush(wxColour(20, 20, 20))); + dc.Clear(); + + if (m_bitmap.IsOk()) { + // Stretched to fill the client area rather than kept at its own aspect: the gate maps to the + // uv unit square whatever its shape, so a non-square window genuinely does project a + // stretched texture. Showing it any other way would misrepresent the bake. + wxImage scaled = m_bitmap.ConvertToImage().Scale(sz.x, sz.y, wxIMAGE_QUALITY_NORMAL); + dc.DrawBitmap(wxBitmap(scaled), 0, 0, false); + } + + // The border is the projection's hard edge, so it is drawn explicitly - with the window + // translucent, the native frame alone reads poorly against a busy 3D scene. + dc.SetPen(wxPen(wxColour(0, 200, 180), 2)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRectangle(0, 0, sz.x, sz.y); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/TextureProjectorFrame.hpp b/src/slic3r/GUI/TextureProjectorFrame.hpp new file mode 100644 index 0000000000..784062680d --- /dev/null +++ b/src/slic3r/GUI/TextureProjectorFrame.hpp @@ -0,0 +1,56 @@ +#ifndef slic3r_TextureProjectorFrame_hpp_ +#define slic3r_TextureProjectorFrame_hpp_ + +// The projection-frame overlay for TextureProjectionMethod::ViewProjected. +// +// A semi-transparent, resizable window that the user drags over the 3D view like a slide projector's +// gate: whatever the model shows through this window is what the texture is projected onto, and the +// window's border is the hard edge of the projection. "Apply" then reads the window's client +// rectangle, converts it into the 3D canvas's own pixel space, and builds an exact projective map +// from it (see GLGizmoTextureDisplacement::apply_projection_frame()). +// +// The window itself is deliberately dumb - it owns no placement state and reports nothing +// continuously. Its position and size *are* the placement, and they are read on demand at Apply, +// which is also when the (expensive) visible-facet selection runs. Moving the window is therefore +// free, and nothing recomputes until the user asks for it. +// +// Plain 2D (wxGraphicsContext), not a wxGLCanvas: a second GL canvas would have to share the app's +// one real wxGLContext, the cause of bugs #10 and #14 in TEXTURE_DISPLACEMENT.md. A paint-DC window +// has no such failure mode, and this one only ever draws a bitmap and a border. + +#include + +#include +#include + +namespace Slic3r { namespace GUI { + +class TextureProjectorFrame : public wxFrame +{ +public: + explicit TextureProjectorFrame(wxWindow *parent); + + // The same 8-bit grayscale pixels build_texture_displacement() samples, so what is aligned here + // is what gets baked. Pass width/height <= 0 to clear it. + void set_texture(const std::vector &grayscale_pixels, int width, int height); + + // Whole-window opacity, 0..255. Low enough to see the model through it, high enough to judge + // where the texture lands - the useful range is roughly 60..200. + void set_opacity(int alpha); + int opacity() const { return m_alpha; } + + // The client area (the gate itself, excluding caption and borders) in screen coordinates. This + // is what the projection is built from, so it deliberately excludes the window decorations - + // the user aligns what they see, which is the client area. + wxRect client_rect_on_screen() const; + +private: + wxBitmap m_bitmap; + int m_alpha = 140; + + void on_paint(wxPaintEvent &); +}; + +}} // namespace Slic3r::GUI + +#endif // slic3r_TextureProjectorFrame_hpp_ diff --git a/src/slic3r/GUI/UVEditorCanvas.cpp b/src/slic3r/GUI/UVEditorCanvas.cpp new file mode 100644 index 0000000000..dd0432bc95 --- /dev/null +++ b/src/slic3r/GUI/UVEditorCanvas.cpp @@ -0,0 +1,2150 @@ +#include "UVEditorCanvas.hpp" + +#include +#include +#include +#include + +#include + +#include +#include + +#include "3DScene.hpp" +#include "BitmapCache.hpp" +#include "GLShader.hpp" +#include "GUI_App.hpp" +#include "I18N.hpp" +#include "OpenGLManager.hpp" +#include "Plater.hpp" +#include "wxExtensions.hpp" +#include "Widgets/CheckBox.hpp" +#include "Widgets/SpinInput.hpp" +#include "libslic3r/AppConfig.hpp" +#include "libslic3r/Utils.hpp" + +namespace Slic3r::GUI { + +namespace { +// Roughly Blender's UV/Image editor palette, which is what this pane is measured against. The UV_ +// prefix is not decoration: COLOR_BACKGROUND (and several other COLOR_*) are Win32 system-colour +// macros from WinUser.h, and an unprefixed name here expands to an integer literal mid-declaration. +const ColorRGBA UV_COLOR_BG = { 0.16f, 0.16f, 0.16f, 1.f }; +// The texture outside every island is washed towards the background, so the islands read as the lit areas +// whatever the texture looks like - a white brick texture no longer swallows a light outline. +const ColorRGBA UV_COLOR_OUTSIDE = { 0.16f, 0.16f, 0.16f, 0.72f }; +const ColorRGBA UV_COLOR_GRID = { 1.f, 1.f, 1.f, 0.08f }; +// Every stroke that must stay legible is drawn twice: a wider near-black halo, then the colour on top, so it +// holds up on light and dark texels alike. +const ColorRGBA UV_COLOR_HALO = { 0.06f, 0.06f, 0.07f, 1.f }; +const ColorRGBA UV_COLOR_TILE_OUTLINE = { 0.70f, 0.70f, 0.72f, 1.f }; +const ColorRGBA UV_COLOR_WIRE = { 1.f, 1.f, 1.f, 0.30f }; // interior edges, unselected +const ColorRGBA UV_COLOR_WIRE_SHADOW = { 0.f, 0.f, 0.f, 0.35f }; // 1 px offset under the wire +const ColorRGBA UV_COLOR_BOUNDARY = { 0.93f, 0.93f, 0.94f, 1.f }; +const ColorRGBA UV_COLOR_HOVER = { 0.72f, 0.98f, 0.93f, 1.f }; // what a click would grab +const ColorRGBA UV_COLOR_HOVER_FILL = { 1.f, 1.f, 1.f, 0.12f }; +// No wash on unselected islands: the texture inside them is exactly what gets baked, so it shows unaltered. +const ColorRGBA UV_COLOR_FILL = { 1.f, 1.f, 1.f, 0.f }; +const ColorRGBA UV_COLOR_SEL_FILL = { 0.15f, 0.85f, 0.75f, 0.24f }; +const ColorRGBA UV_COLOR_SEL_WIRE = { 0.55f, 1.f, 0.92f, 0.55f }; +const ColorRGBA UV_COLOR_SEL_BOUNDARY = { 0.16f, 0.90f, 0.78f, 1.f }; // the app teal, brightened to read on texture +const ColorRGBA UV_COLOR_DIAL = { 1.f, 0.85f, 0.2f, 0.9f }; // rotation protractor (#11) + +constexpr float SNAP_PIXELS = 28.f; // how close a boundary vertex has to come before it sticks (#2) + +// wxWidgets reports this canvas' size in *logical* points, while the GL drawable behind it is sized +// in device pixels. On the backends where those differ under HiDPI (the same pair GLCanvas3D guards +// its RetinaHelper with) a viewport built straight from GetSize() covers only the bottom-left +// 1/scale of the drawable, which is exactly where the whole editor ended up drawn, shrunken. +// Mouse coordinates arrive in logical points, so only the viewport needs converting - every other +// GetSize() use here is compared against event coordinates and must stay logical. +wxSize gl_drawable_size(const wxWindow *win, const wxSize &logical_size) +{ +#if defined(__APPLE__) || defined(__WXGTK3__) + const double scale = (win != nullptr) ? win->GetContentScaleFactor() : 1.0; + if (scale > 0.0) + return wxSize(std::max(1, int(std::lround(logical_size.GetWidth() * scale))), + std::max(1, int(std::lround(logical_size.GetHeight() * scale)))); +#else + (void) win; +#endif + return wxSize(std::max(1, logical_size.GetWidth()), std::max(1, logical_size.GetHeight())); +} + +// The pixel format this canvas is created with has to match the one the app's single shared +// wxGLContext was created against (that of View3D's canvas, from OpenGLManager::create_wxglcanvas()), +// so this mirrors that attribute list *including its multisampling*: WGL requires the HDC passed to +// wglMakeCurrent() to have the same pixel format as the one the context was created with, and a +// differing sample count is a differing pixel format. Getting only the non-multisample half of this +// right still leaves SetCurrent() failing, which is silent - the canvas then just shows whatever +// was last in its backbuffer, i.e. nothing. +std::vector gl_attrib_list() +{ + int antialiasing_samples = 4; + if (const AppConfig *app_config = wxGetApp().app_config; app_config != nullptr) { + const std::string value = app_config->get(SETTING_OPENGL_AA_SAMPLES); + if (value == "0" || value == "2" || value == "4" || value == "8" || value == "16") + antialiasing_samples = ::atoi(value.c_str()); + } + // OpenGLManager's own auto-detection has already run by now (View3D is created before this + // canvas), so this only reads its verdict rather than re-detecting. + if (!OpenGLManager::can_multisample()) + antialiasing_samples = 0; + + return { + WX_GL_RGBA, + WX_GL_DOUBLEBUFFER, + WX_GL_MIN_RED, 8, + WX_GL_MIN_GREEN, 8, + WX_GL_MIN_BLUE, 8, + WX_GL_MIN_ALPHA, 8, + WX_GL_DEPTH_SIZE, 24, + WX_GL_STENCIL_SIZE, 8, + WX_GL_SAMPLE_BUFFERS, antialiasing_samples > 0 ? GL_TRUE : GL_FALSE, + WX_GL_SAMPLES, antialiasing_samples, + 0 + }; +} + +// Wide lines are only *required* to be supported in a compatibility profile; a core-profile driver is +// allowed to reject anything but 1.0 with GL_INVALID_VALUE. In practice every desktop driver we care +// about honours it, so ask and swallow the error rather than giving up thickness everywhere. +void set_line_width(float width) +{ + ::glLineWidth(width); + ::glGetError(); +} + +uint64_t undirected_edge_key(int a, int b) +{ + if (a > b) + std::swap(a, b); + return (uint64_t(uint32_t(a)) << 32) | uint32_t(b); +} + +// Signed-area test, so it works whichever way round the triangle is wound. +bool point_in_triangle(const Vec2f &p, const Vec2f &a, const Vec2f &b, const Vec2f &c) +{ + const auto cross = [](const Vec2f &u, const Vec2f &v) { return u.x() * v.y() - u.y() * v.x(); }; + const float d0 = cross(b - a, p - a); + const float d1 = cross(c - b, p - b); + const float d2 = cross(a - c, p - c); + const bool has_neg = (d0 < 0.f) || (d1 < 0.f) || (d2 < 0.f); + const bool has_pos = (d0 > 0.f) || (d1 > 0.f) || (d2 > 0.f); + return !(has_neg && has_pos); +} + +// Shortest signed difference between two angles, so a rotation gesture crossing +/-pi doesn't jump. +float angle_delta(float from, float to) +{ + float d = to - from; + while (d > float(M_PI)) + d -= 2.f * float(M_PI); + while (d < -float(M_PI)) + d += 2.f * float(M_PI); + return d; +} + +// A 2D affine as the 4x4 the "flat" shader's view_model_matrix wants. +Transform3d to_transform3d(const UVEditorCanvas::IslandTransform &m) +{ + Transform3d t = Transform3d::Identity(); + t(0, 0) = m(0, 0); t(0, 1) = m(0, 1); t(0, 3) = m(0, 2); + t(1, 0) = m(1, 0); t(1, 1) = m(1, 1); t(1, 3) = m(1, 2); + return t; +} +} // namespace + +UVEditorCanvas::UVEditorCanvas(wxWindow *parent) + : wxGLCanvas(parent, wxID_ANY, gl_attrib_list().data(), wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS) +{ + // The GL canvas paints its entire surface, so background erasing is unnecessary (and would + // otherwise race with our own rendering) - same setup as OpenGLManager::create_wxglcanvas(). + SetBackgroundStyle(wxBG_STYLE_PAINT); + + // Shares the app's one real GL context (see class comment) rather than creating an + // independent one - this is the same call View3D/Preview/AssembleView make in + // GUI_Preview.cpp, and is what lets this canvas reuse wxGetApp().get_shader(...) and GLModel. + m_context = wxGetApp().init_glcontext(*this); + + Bind(wxEVT_PAINT, &UVEditorCanvas::on_paint, this); + Bind(wxEVT_SIZE, &UVEditorCanvas::on_size, this); + Bind(wxEVT_LEFT_DOWN, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_LEFT_UP, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_RIGHT_DOWN, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_RIGHT_UP, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_MIDDLE_DOWN, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_MIDDLE_UP, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_MOTION, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_MOUSEWHEEL, &UVEditorCanvas::on_mouse, this); + Bind(wxEVT_LEAVE_WINDOW, &UVEditorCanvas::on_leave, this); + Bind(wxEVT_KEY_DOWN, &UVEditorCanvas::on_key, this); + Bind(wxEVT_ERASE_BACKGROUND, &UVEditorCanvas::on_erase_background, this); +} + +// NOTE (applies to set_background_texture() too): these are called from the texture-displacement +// gizmo's ImGui panel, i.e. from *inside* the main 3D canvas's own render pass. They must therefore +// only ever mark state dirty and schedule a repaint - rendering inline from here would make this +// canvas's GL surface current in the middle of the 3D canvas's frame (and did: it was also called +// while this pane was still hidden, where wxGLCanvas::SetCurrent() refuses to switch at all and the +// GL calls that followed simply landed on the 3D canvas instead). +void UVEditorCanvas::set_islands(Islands islands) +{ + // Only frame the view when a patch first appears, not on every stroke that extends one - the + // latter would keep yanking the view out from under a user who has panned or zoomed. + m_needs_fit |= m_islands.indices.empty(); + // Re-uploads that keep the same island/vertex count are just a refresh (e.g. a committed vertex edit + // re-applied), not a re-segmentation, so the selection and the picked sub-element stay valid and are + // worth keeping. A change in either count means the charts were renumbered and both are meaningless. + const bool same_structure = m_islands.island_count == islands.island_count && + m_islands.uvs.size() == islands.uvs.size(); + m_islands = std::move(islands); + if (m_selected_island >= m_islands.island_count) + m_selected_island = -1; + if (!same_structure) { + // A fresh unwrap renumbers charts, so any previous multi-selection is meaningless: drop it, then + // keep the primary (if still valid) as a single-island selection so the highlight is consistent. + m_selection.clear(); + if (m_selected_island >= 0) + m_selection.push_back(m_selected_island); + // Vertex/edge picks index into the old unwrap; drop them too. + m_active_vertex = -1; + m_active_edge = { -1, -1 }; + m_sel_vertices.clear(); + m_sel_edges.clear(); + m_hover_island = m_hover_vertex = -1; + m_hover_edge = { -1, -1 }; + } + + // Boundary vertices and edges, bucketed per island: the vertices for snapping, the edges for the outline. + const size_t n_islands = size_t(std::max(m_islands.island_count, 0)); + m_island_boundary_verts.assign(n_islands, {}); + m_island_boundary_edges.assign(n_islands, {}); + std::vector seen(m_islands.uvs.size(), false); + for (const auto &[a, b] : m_islands.boundary_edges) { + if (a < 0 || b < 0 || size_t(a) >= m_islands.uvs.size() || size_t(b) >= m_islands.uvs.size()) + continue; + const int island = m_islands.vertex_island[size_t(a)]; + if (island < 0 || size_t(island) >= n_islands) + continue; + m_island_boundary_edges[size_t(island)].emplace_back(a, b); + for (const int v : { a, b }) + if (!seen[size_t(v)]) { + seen[size_t(v)] = true; + m_island_boundary_verts[size_t(island)].push_back(v); + } + } + + // Triangles and raw bounds per island, for picking. + m_island_tris.assign(n_islands, {}); + m_island_raw_bounds.assign(n_islands, { Vec2f::Constant(std::numeric_limits::max()), + Vec2f::Constant(std::numeric_limits::lowest()) }); + for (size_t t = 0; t < m_islands.indices.size(); ++t) { + const Vec3i32 &tri = m_islands.indices[t]; + if (tri.minCoeff() < 0 || size_t(tri.maxCoeff()) >= m_islands.uvs.size()) + continue; + const int island = m_islands.vertex_island[size_t(tri[0])]; + if (island < 0 || size_t(island) >= n_islands) + continue; + m_island_tris[size_t(island)].push_back(int(t)); + auto &[lo, hi] = m_island_raw_bounds[size_t(island)]; + for (int k = 0; k < 3; ++k) { + lo = lo.cwiseMin(m_islands.uvs[size_t(tri[k])]); + hi = hi.cwiseMax(m_islands.uvs[size_t(tri[k])]); + } + } + + m_mesh_dirty = true; + m_background_quad_dirty = true; // the backdrop is sized to the unwrap, so it moved too + Refresh(); +} + +void UVEditorCanvas::set_island_transforms(std::vector transforms) +{ + m_transforms = std::move(transforms); + m_background_quad_dirty = true; // content_bounds() depends on where the islands ended up + Refresh(); +} + +void UVEditorCanvas::set_island_fill_colors(std::vector colors) +{ + m_island_fill_colors = std::move(colors); + Refresh(); +} + +void UVEditorCanvas::set_uv_transform(float tiling_scale, float rotation_deg, bool tile_enabled, bool tile_mirrored) +{ + m_tiling_scale = (std::abs(tiling_scale) > 1e-6f) ? tiling_scale : 1.f; + m_rotation_deg = rotation_deg; + m_tile_enabled = tile_enabled; + m_tile_mirrored = tile_mirrored; + m_background_quad_dirty = true; +} + +void UVEditorCanvas::set_background_texture(const std::vector &grayscale_pixels, int width, int height) +{ + if (width <= 0 || height <= 0 || grayscale_pixels.size() != size_t(width) * size_t(height)) { + m_background_width = m_background_height = 0; + m_background_pixels.clear(); + } else { + m_background_width = width; + m_background_height = height; + m_background_pixels.assign(size_t(width) * size_t(height) * 4, 255); + for (size_t i = 0; i < grayscale_pixels.size(); ++i) { + const unsigned char g = grayscale_pixels[i]; + m_background_pixels[i * 4 + 0] = g; + m_background_pixels[i * 4 + 1] = g; + m_background_pixels[i * 4 + 2] = g; + m_background_pixels[i * 4 + 3] = 255; + } + } + m_background_dirty = true; + Refresh(); +} + +void UVEditorCanvas::reset_view() +{ + m_needs_fit = true; + Refresh(); +} + +void UVEditorCanvas::run_command(Command cmd, float value) +{ + switch (cmd) { + case Command::FrameAll: reset_view(); return; + case Command::ToggleSnap: m_snap_enabled = !m_snap_enabled; update_status(); return; + case Command::SetSelectMode: + // Switched here straight away so the strip and the canvas agree at once; the gizmo is still told, + // because it is what keeps the mode when the canvas is next refreshed from the layer. + set_select_mode(static_cast(std::clamp(int(value), 0, 2))); + break; + default: break; + } + // Everything else needs the layer data the canvas doesn't hold; hand it to the gizmo. + if (m_on_command) + m_on_command(cmd, value); +} + +void UVEditorCanvas::set_pane_state(PaneState state) +{ + m_pane_state = std::move(state); + update_status(); + if (m_on_pane_state) + m_on_pane_state(m_pane_state); +} + +void UVEditorCanvas::update_status() +{ + if (!m_on_status) + return; + + wxString msg; + switch (m_gesture) { + case Gesture::MoveIsland: msg = _L("Moving island | release to drop, Esc to cancel"); break; + case Gesture::RotateIsland: + case Gesture::RotateIslandModal: + msg = wxString::Format(_L("Rotating island: %d° | Shift = snap 15°, click to confirm, Esc to cancel"), + int(std::lround(m_rot_display_deg))); + break; + case Gesture::ScaleIslandModal: msg = _L("Scaling island | click to confirm, Esc to cancel"); break; + case Gesture::MoveVertex: msg = _L("Moving vertex | release to drop"); break; + case Gesture::MoveEdge: msg = _L("Moving edge | release to drop"); break; + case Gesture::Pan: msg = _L("Panning"); break; + case Gesture::None: + default: + if (!has_islands()) + msg = m_pane_state.has_layer ? _L("Paint the area on the model, then press Unwrap") : + _L("Pick Unwrap as a texture layer's mapping to edit its UVs here"); + else if (m_select_mode == SelectMode::Vertex) + msg = m_sel_vertices.size() > 1 ? + wxString::Format(_L("%d vertices selected | drag = move together, Shift/Ctrl click = add/remove"), + int(m_sel_vertices.size())) : + _L("Vertex mode: drag a vertex to reshape | Shift/Ctrl click = multi-select, wheel = zoom, Home = frame"); + else if (m_select_mode == SelectMode::Edge) + msg = m_sel_edges.size() > 1 ? + wxString::Format(_L("%d edges selected | drag = move together, Shift/Ctrl click = add/remove"), + int(m_sel_edges.size())) : + _L("Edge mode: drag an island edge to reshape | Shift/Ctrl click = multi-select, wheel = zoom, Home = frame"); + else if (m_selection.size() > 1) + msg = wxString::Format(_L("%d islands selected | drag = move together, Shift/Ctrl click = add/remove, R/S = rotate/scale primary"), + int(m_selection.size())); + else if (m_selected_island >= 0) + msg = wxString::Format(_L("Island %d selected | drag = move, R = rotate, S = scale, Shift/Ctrl click = multi-select, Home = frame"), + m_selected_island + 1); + else + msg = _L("Click an island to select | Shift/Ctrl click = multi-select, wheel = zoom, middle-drag = pan, Home = frame all"); + if (m_snap_enabled) + msg += _L(" | snap ON"); + break; + } + m_on_status(msg); +} + +Vec2f UVEditorCanvas::island_uv(size_t vertex) const +{ + const Vec2f &raw = m_islands.uvs[vertex]; + const int island = m_islands.vertex_island[vertex]; + if (island < 0 || size_t(island) >= m_transforms.size()) + return raw; + const IslandTransform &m = m_transforms[size_t(island)]; + return m.block<2, 2>(0, 0) * raw + m.col(2); +} + +void UVEditorCanvas::content_bounds(Vec2f &min_uv, Vec2f &max_uv) const +{ + // Always include the texture's first tile, so an unwrap that happens to be tiny, or absent, + // still leaves something sensibly framed on screen. + min_uv = Vec2f(0.f, 0.f); + max_uv = Vec2f(1.f, 1.f); + for (size_t i = 0; i < m_islands.uvs.size(); ++i) { + const Vec2f uv = island_uv(i); + min_uv = min_uv.cwiseMin(uv); + max_uv = max_uv.cwiseMax(uv); + } +} + +void UVEditorCanvas::framed_bounds(Vec2f &min_uv, Vec2f &max_uv) const +{ + content_bounds(min_uv, max_uv); + // With tiling on, the backdrop is snapped out to whole tiles, so it is bigger than the raw + // bounds - and by a different amount on each side. Framing the raw bounds therefore left that + // backdrop visibly off-centre: hanging past one edge of the pane with dead space against the + // other. Frame what is drawn instead. (Tiling off draws only the first tile, which the bounds + // already contain, so there is nothing to snap.) + if (m_tile_enabled) { + min_uv = Vec2f(std::floor(min_uv.x()), std::floor(min_uv.y())); + max_uv = Vec2f(std::ceil(max_uv.x()), std::ceil(max_uv.y())); + } +} + +void UVEditorCanvas::fit_view_to_content() +{ + Vec2f min_uv, max_uv; + framed_bounds(min_uv, max_uv); + + const wxSize size = GetSize(); + const float aspect = float(std::max(1, size.GetWidth())) / float(std::max(1, size.GetHeight())); + const Vec2f half = 0.5f * (max_uv - min_uv); + + m_pan = 0.5f * (min_uv + max_uv); + // m_zoom is the half-extent shown across the *shorter* pane edge (see view_half_extents()), so + // each axis' required half-extent has to be converted back into that unit before the larger of + // the two is taken. Sizing off the bigger axis alone, as this did, ignores the pane's shape and + // zooms out further than either axis needs on anything but a square pane. The 1.1 leaves a + // margin so the outermost island edge is not flush against the frame. + m_zoom = std::max(1.1f * std::max(half.x() / std::max(aspect, 1.f), half.y() * std::min(aspect, 1.f)), + 0.05f); + m_needs_fit = false; +} + +void UVEditorCanvas::view_half_extents(float &half_w, float &half_h) const +{ + const wxSize size = GetSize(); + const float w = float(std::max(1, size.GetWidth())); + const float h = float(std::max(1, size.GetHeight())); + + // m_zoom is the half-extent visible across the *shorter* edge; the longer edge shows + // proportionally more. Both axes have to be driven off the same uniform scale, or the content + // comes out squashed on one of the two pane orientations. + const float aspect = w / h; + half_w = m_zoom * std::max(aspect, 1.f); + half_h = m_zoom * std::max(1.f / aspect, 1.f); +} + +Vec2f UVEditorCanvas::screen_to_uv(const wxPoint &px) const +{ + const wxSize size = GetSize(); + const float w = float(std::max(1, size.GetWidth())); + const float h = float(std::max(1, size.GetHeight())); + + float half_w, half_h; + view_half_extents(half_w, half_h); + + // Inverse of the projection in render(): x maps straight through, y is negated there so that v + // runs down the screen - which means screen-down and v-increasing agree, and this is a plain + // scale on both axes. + return Vec2f(m_pan.x() + (2.f * float(px.x) / w - 1.f) * half_w, + m_pan.y() + (2.f * float(px.y) / h - 1.f) * half_h); +} + +int UVEditorCanvas::island_at(const Vec2f &uv) const +{ + int found = -1; + for (int island = 0; island < int(m_island_tris.size()); ++island) { + // The raw bounds through the island's affine: the box of the four transformed corners contains the island. + const auto &[lo, hi] = m_island_raw_bounds[size_t(island)]; + if (lo.x() > hi.x()) + continue; + const IslandTransform m = size_t(island) < m_transforms.size() ? m_transforms[size_t(island)] : + IslandTransform(IslandTransform::Identity()); + Vec2f bmin = Vec2f::Constant(std::numeric_limits::max()), bmax = -bmin; + for (const Vec2f &corner : { lo, hi, Vec2f(lo.x(), hi.y()), Vec2f(hi.x(), lo.y()) }) { + const Vec2f p = m.block<2, 2>(0, 0) * corner + m.col(2); + bmin = bmin.cwiseMin(p); + bmax = bmax.cwiseMax(p); + } + if (uv.x() < bmin.x() || uv.y() < bmin.y() || uv.x() > bmax.x() || uv.y() > bmax.y()) + continue; + + for (const int t : m_island_tris[size_t(island)]) { + const Vec3i32 &tri = m_islands.indices[size_t(t)]; + if (!point_in_triangle(uv, island_uv(size_t(tri[0])), island_uv(size_t(tri[1])), island_uv(size_t(tri[2])))) + continue; + // Islands are allowed to overlap, so a point can be inside several. Keep whichever is already + // selected - otherwise a drag of a partly-covered island would be stolen mid-gesture by the + // one on top of it. + if (is_selected(island)) + return island; + found = island; + break; + } + } + return found; +} + +void UVEditorCanvas::update_hover(const wxPoint &pos) +{ + int island = -1, vertex = -1; + std::pair edge{ -1, -1 }; + if (has_islands()) { + const Vec2f uv = screen_to_uv(pos); + switch (m_select_mode) { + case SelectMode::Island: island = island_at(uv); break; + case SelectMode::Vertex: vertex = vertex_at(uv); break; + case SelectMode::Edge: edge = edge_at(uv); break; + } + } + if (island != m_hover_island || vertex != m_hover_vertex || edge != m_hover_edge) { + m_hover_island = island; + m_hover_vertex = vertex; + m_hover_edge = edge; + Refresh(); + } +} + +void UVEditorCanvas::set_select_mode(SelectMode mode) +{ + if (m_select_mode == mode) + return; + m_select_mode = mode; + m_active_vertex = -1; + m_active_edge = { -1, -1 }; + m_hover_island = m_hover_vertex = -1; + m_hover_edge = { -1, -1 }; + m_sel_vertices.clear(); + m_sel_edges.clear(); + m_gesture = Gesture::None; + update_status(); + Refresh(); +} + +int UVEditorCanvas::vertex_at(const Vec2f &uv) const +{ + // Screen-space threshold, so the pick feels the same at every zoom. + const wxSize size = GetSize(); + const float uv_per_px = 2.f * m_zoom / float(std::max(1, std::min(size.GetWidth(), size.GetHeight()))); + const float threshold = SNAP_PIXELS * uv_per_px; + + int best = -1; + float best_d = threshold * threshold; + for (size_t i = 0; i < m_islands.uvs.size(); ++i) { + const float d = (island_uv(i) - uv).squaredNorm(); + if (d < best_d) { + best_d = d; + best = int(i); + } + } + return best; +} + +std::pair UVEditorCanvas::edge_at(const Vec2f &uv) const +{ + const wxSize size = GetSize(); + const float uv_per_px = 2.f * m_zoom / float(std::max(1, std::min(size.GetWidth(), size.GetHeight()))); + const float threshold = SNAP_PIXELS * uv_per_px; + + // Point-to-segment distance in texture-UV space, against the island outlines (the edges the pane + // exists to show). Interior edges are left alone: the boundary is what a user reshapes. + const auto seg_dist_sq = [](const Vec2f &p, const Vec2f &a, const Vec2f &b) { + const Vec2f ab = b - a; + const float l2 = ab.squaredNorm(); + const float t = (l2 > 1e-12f) ? std::clamp((p - a).dot(ab) / l2, 0.f, 1.f) : 0.f; + return (p - (a + ab * t)).squaredNorm(); + }; + std::pair best{ -1, -1 }; + float best_d = threshold * threshold; + for (const auto &[a, b] : m_islands.boundary_edges) { + if (a < 0 || b < 0 || size_t(a) >= m_islands.uvs.size() || size_t(b) >= m_islands.uvs.size()) + continue; + const float d = seg_dist_sq(uv, island_uv(size_t(a)), island_uv(size_t(b))); + if (d < best_d) { + best_d = d; + best = { a, b }; + } + } + return best; +} + +void UVEditorCanvas::move_vertex_raw(int v, const Vec2f &delta_uv) +{ + if (v < 0 || size_t(v) >= m_islands.uvs.size()) + return; + const int island = m_islands.vertex_island[size_t(v)]; + // The gesture happens in texture-UV space; the stored coordinate is the raw unwrap. Undo the + // island's own linear map (which includes the layer's tiling scale + rotation) to get there. + Eigen::Matrix2f lin = Eigen::Matrix2f::Identity(); + if (island >= 0 && size_t(island) < m_transforms.size()) + lin = m_transforms[size_t(island)].block<2, 2>(0, 0); + const float det = lin.determinant(); + const Vec2f raw_delta = (std::abs(det) > 1e-12f) ? Vec2f(lin.inverse() * delta_uv) : delta_uv; + m_islands.uvs[size_t(v)] += raw_delta; + if (island >= 0 && size_t(island) < m_island_raw_bounds.size()) { // keep the pick box around the moved vertex + auto &[lo, hi] = m_island_raw_bounds[size_t(island)]; + lo = lo.cwiseMin(m_islands.uvs[size_t(v)]); + hi = hi.cwiseMax(m_islands.uvs[size_t(v)]); + } + m_mesh_dirty = true; // the edited raw uv is redrawn from rebuild_island_models() next frame +} + +float UVEditorCanvas::island_rotation_deg(int island) const +{ + // The rotation baked into the island's affine, in the same y-down UV convention the gesture uses. + // First column is scale*(cos, sin); its angle is the island's on-screen orientation. + if (island < 0 || size_t(island) >= m_transforms.size()) + return 0.f; + const IslandTransform &m = m_transforms[size_t(island)]; + return std::atan2(m(1, 0), m(0, 0)) * 180.f / float(M_PI); +} + +Vec2f UVEditorCanvas::island_centroid(int island) const +{ + Vec2f sum = Vec2f::Zero(); + int count = 0; + for (size_t i = 0; i < m_islands.uvs.size(); ++i) + if (m_islands.vertex_island[i] == island) { + sum += island_uv(i); + ++count; + } + return (count > 0) ? Vec2f(sum / float(count)) : Vec2f::Zero(); +} + +Vec2f UVEditorCanvas::uv_delta_to_unwrap(const Vec2f &delta_uv) const +{ + // apply_uv_transform() maps unwrap -> uv as uv = R(unwrap / tiling) + offset, so the inverse of + // a *delta* (the translation drops out) is unwrap = tiling * R^-1(delta_uv). + const float rad = m_rotation_deg * float(M_PI) / 180.f; + const float cs = std::cos(rad), sn = std::sin(rad); + return Vec2f(delta_uv.x() * cs + delta_uv.y() * sn, -delta_uv.x() * sn + delta_uv.y() * cs) * m_tiling_scale; +} + +Vec2f UVEditorCanvas::snap_correction(int island) const +{ + if (!m_snap_enabled || island < 0 || size_t(island) >= m_island_boundary_verts.size()) + return Vec2f::Zero(); + + // A screen-space threshold, so the magnet feels the same at every zoom level. + const wxSize size = GetSize(); + const float uv_per_px = 2.f * m_zoom / float(std::max(1, std::min(size.GetWidth(), size.GetHeight()))); + const float threshold = SNAP_PIXELS * uv_per_px; + + float best_dist_sq = threshold * threshold; + Vec2f best = Vec2f::Zero(); + for (const int mine : m_island_boundary_verts[size_t(island)]) { + const Vec2f a = island_uv(size_t(mine)); + for (size_t other = 0; other < m_island_boundary_verts.size(); ++other) { + if (int(other) == island) + continue; + for (const int theirs : m_island_boundary_verts[other]) { + const Vec2f d = island_uv(size_t(theirs)) - a; + const float dist_sq = d.squaredNorm(); + if (dist_sq < best_dist_sq) { + best_dist_sq = dist_sq; + best = d; + } + } + } + } + return best; +} + +std::vector UVEditorCanvas::selected_edge_endpoints() const +{ + std::vector verts; + for (const auto &[a, b] : m_sel_edges) + for (const int v : { a, b }) + if (v >= 0 && std::find(verts.begin(), verts.end(), v) == verts.end()) + verts.push_back(v); + return verts; +} + +void UVEditorCanvas::end_gesture() +{ + const bool was_editing = m_gesture == Gesture::MoveIsland || m_gesture == Gesture::RotateIsland || + m_gesture == Gesture::RotateIslandModal || m_gesture == Gesture::ScaleIslandModal; + + // Stick to a neighbour at the end of a move, rather than magnetically fighting the cursor + // throughout it - a snap that keeps re-applying mid-drag is very hard to pull *out* of. + if (m_gesture == Gesture::MoveIsland && m_on_island_edit) { + const Vec2f correction = snap_correction(m_selected_island); + if (!correction.isZero()) + m_on_island_edit(m_selected_island, uv_delta_to_unwrap(correction), 0.f, 1.f, false); + } + + if (was_editing && m_on_island_edit) + m_on_island_edit(m_selected_island, Vec2f::Zero(), 0.f, 1.f, /* finished */ true); + + // Commit a vertex/edge edit once, on release: hand the owner the affected unwrapped vertices and + // their new raw-unwrap coordinates so it can store the overrides and re-solve the bake preview. + if ((m_gesture == Gesture::MoveVertex || m_gesture == Gesture::MoveEdge) && m_vertex_edit_moved && + m_on_vertex_edit) { + std::vector> edits; + const auto add = [&](int v) { + if (v >= 0 && size_t(v) < m_islands.uvs.size()) + edits.emplace_back(v, m_islands.uvs[size_t(v)]); + }; + // Commit every element of the multi-selection, not just the primary, so a group drag stores all + // the moved vertices' overrides. Falls back to the primary if the selection is somehow empty. + if (m_gesture == Gesture::MoveVertex) { + if (m_sel_vertices.empty()) + add(m_active_vertex); + else + for (const int v : m_sel_vertices) + add(v); + } else { + const std::vector endpoints = selected_edge_endpoints(); + if (endpoints.empty()) { + add(m_active_edge.first); + add(m_active_edge.second); + } else + for (const int v : endpoints) + add(v); + } + if (!edits.empty()) + m_on_vertex_edit(edits); + } + + m_gesture = Gesture::None; + m_rot_raw_deg = 0.f; + m_rot_applied_deg = 0.f; + m_modal_scale_accum = 1.f; + if (HasCapture()) + ReleaseMouse(); +} + +void UVEditorCanvas::on_key(wxKeyEvent &evt) +{ + const int key = evt.GetKeyCode(); + + // Undo/redo while the pane has focus. Island edits already take a Plater snapshot per gesture (see + // GLGizmoTextureDisplacement::on_island_edited), so this just drives the same global history; the + // gizmo re-pushes the restored island transforms into the canvas on the reload that follows. + if (evt.ControlDown() && (key == 'Z' || key == 'z')) { + if (evt.ShiftDown()) wxGetApp().plater()->redo(); + else wxGetApp().plater()->undo(); + return; + } + if (evt.ControlDown() && (key == 'Y' || key == 'y')) { + wxGetApp().plater()->redo(); + return; + } + + if (m_gesture == Gesture::RotateIslandModal || m_gesture == Gesture::ScaleIslandModal) { + if (key == WXK_ESCAPE) { + // Put the island back exactly where the modal gesture found it, then finish. + if (m_on_island_edit) { + if (m_gesture == Gesture::RotateIslandModal && m_rot_applied_deg != 0.f) + m_on_island_edit(m_selected_island, Vec2f::Zero(), -m_rot_applied_deg, 1.f, false); + if (m_gesture == Gesture::ScaleIslandModal && m_modal_scale_accum != 1.f) + m_on_island_edit(m_selected_island, Vec2f::Zero(), 0.f, 1.f / m_modal_scale_accum, false); + } + end_gesture(); + Refresh(); + return; + } + if (key == WXK_RETURN || key == WXK_NUMPAD_ENTER) { + end_gesture(); + Refresh(); + return; + } + } + + // Frame everything. The unwrap is packed in mm and then divided by the layer's tile size, so it + // can easily sit tens of tiles away from the texture's first one - panning back by hand from + // there is hopeless, and without this there would be no way to reach reset_view() at all. + if (key == WXK_HOME || key == 'F' || key == 'f') { + reset_view(); + return; + } + + // Blender's modal transforms: R / S, then the transform follows the mouse until it is confirmed + // with a click or Enter, or abandoned with Esc. + if (m_selected_island >= 0 && m_select_mode == SelectMode::Island && m_gesture == Gesture::None && + (key == 'R' || key == 'r' || key == 'S' || key == 's')) { + const Vec2f uv = screen_to_uv(ScreenToClient(wxGetMousePosition())); + const Vec2f centre = island_centroid(m_selected_island); + const Vec2f rel = uv - centre; + if (key == 'R' || key == 'r') { + m_gesture = Gesture::RotateIslandModal; + m_rot_raw_deg = 0.f; + m_rot_applied_deg = 0.f; + m_rot_base_deg = island_rotation_deg(m_selected_island); + m_rot_display_deg = m_rot_base_deg; + m_gesture_last_angle = std::atan2(rel.y(), rel.x()); + } else { + m_gesture = Gesture::ScaleIslandModal; + m_modal_scale_accum = 1.f; + m_gesture_last_dist = std::max(rel.norm(), 1e-6f); + } + return; + } + + evt.Skip(); +} + +void UVEditorCanvas::on_mouse(wxMouseEvent &evt) +{ + const wxEventType type = evt.GetEventType(); + const wxPoint pos = evt.GetPosition(); + + // Track the pointer so the +/- add-remove hint can be drawn next to it in Vertex/Edge mode. + m_cursor_px = pos; + m_cursor_inside = true; + if (type == wxEVT_MOTION && m_gesture == Gesture::None) { + update_hover(pos); + if (m_select_mode != SelectMode::Island) + Refresh(); // animate the hint (and its +/- flip) as the pointer/modifiers move + } + + // Key events (R/S/Home) only arrive if this canvas has focus, and clicking it is the natural way + // to ask for it - the pane is not in the tab order. + if (type == wxEVT_LEFT_DOWN || type == wxEVT_RIGHT_DOWN || type == wxEVT_MIDDLE_DOWN) + SetFocus(); + + // A modal R/S is confirmed by any click, exactly as in Blender. + if ((m_gesture == Gesture::RotateIslandModal || m_gesture == Gesture::ScaleIslandModal) && + (type == wxEVT_LEFT_DOWN || type == wxEVT_RIGHT_DOWN)) { + end_gesture(); + Refresh(); + return; + } + + if (type == wxEVT_LEFT_DOWN) { + const Vec2f uv = screen_to_uv(pos); + m_drag_last_px = pos; + m_gesture_last_uv = uv; + if (m_select_mode == SelectMode::Vertex) { + const int hit = vertex_at(uv); + m_active_edge = { -1, -1 }; + m_vertex_edit_moved = false; + // Same Shift-adds / Ctrl-toggles / plain-replaces rules as island selection, so a group of + // vertices can be picked and dragged together. + if (hit >= 0) { + if (evt.ShiftDown()) { + if (!is_vertex_selected(hit)) + m_sel_vertices.push_back(hit); + } else if (evt.ControlDown()) { + if (auto it = std::find(m_sel_vertices.begin(), m_sel_vertices.end(), hit); it != m_sel_vertices.end()) + m_sel_vertices.erase(it); + else + m_sel_vertices.push_back(hit); + } else if (!is_vertex_selected(hit)) { + m_sel_vertices.assign(1, hit); + } + } else if (!evt.ShiftDown() && !evt.ControlDown()) { + m_sel_vertices.clear(); + } + // Primary = the clicked vertex only if it is (still) selected; a Ctrl-deselect just toggles. + m_active_vertex = (hit >= 0 && is_vertex_selected(hit)) ? hit : -1; + m_gesture = (m_active_vertex >= 0) ? Gesture::MoveVertex : Gesture::Pan; + } else if (m_select_mode == SelectMode::Edge) { + const std::pair hit = edge_at(uv); + m_active_vertex = -1; + m_vertex_edit_moved = false; + if (hit.first >= 0) { + if (evt.ShiftDown()) { + if (!is_edge_selected(hit)) + m_sel_edges.push_back(hit); + } else if (evt.ControlDown()) { + if (auto it = std::find(m_sel_edges.begin(), m_sel_edges.end(), hit); it != m_sel_edges.end()) + m_sel_edges.erase(it); + else + m_sel_edges.push_back(hit); + } else if (!is_edge_selected(hit)) { + m_sel_edges.assign(1, hit); + } + } else if (!evt.ShiftDown() && !evt.ControlDown()) { + m_sel_edges.clear(); + } + m_active_edge = (hit.first >= 0 && is_edge_selected(hit)) ? hit : std::pair{ -1, -1 }; + m_gesture = (m_active_edge.first >= 0) ? Gesture::MoveEdge : Gesture::Pan; + } else { + const int hit = island_at(uv); + if (hit >= 0) { + if (evt.ShiftDown()) { + // Shift adds to the selection (and makes the clicked one the new primary). + if (!is_selected(hit)) + m_selection.push_back(hit); + m_selected_island = hit; + } else if (evt.ControlDown()) { + // Ctrl toggles: clicking a selected island removes it (the requested "deselect"), + // clicking an unselected one adds it. + if (auto it = std::find(m_selection.begin(), m_selection.end(), hit); it != m_selection.end()) { + m_selection.erase(it); + m_selected_island = m_selection.empty() ? -1 : m_selection.back(); + } else { + m_selection.push_back(hit); + m_selected_island = hit; + } + } else { + // Plain click: keep the whole selection if the clicked island is already part of it (so + // a drag moves the group), otherwise collapse to just this one. + if (!is_selected(hit)) + m_selection.assign(1, hit); + m_selected_island = hit; + } + } else if (!evt.ShiftDown() && !evt.ControlDown()) { + // Clicking empty space with no modifier clears the selection and pans. + m_selection.clear(); + m_selected_island = -1; + } + m_gesture = (m_selected_island >= 0) ? Gesture::MoveIsland : Gesture::Pan; + } + CaptureMouse(); + Refresh(); + } else if (type == wxEVT_RIGHT_DOWN && m_selected_island >= 0 && m_select_mode == SelectMode::Island) { + const Vec2f rel = screen_to_uv(pos) - island_centroid(m_selected_island); + m_gesture = Gesture::RotateIsland; + m_rot_raw_deg = 0.f; + m_rot_applied_deg = 0.f; + m_rot_base_deg = island_rotation_deg(m_selected_island); + m_rot_display_deg = m_rot_base_deg; + m_gesture_last_angle = std::atan2(rel.y(), rel.x()); + CaptureMouse(); + } else if (type == wxEVT_MIDDLE_DOWN) { + m_gesture = Gesture::Pan; + m_drag_last_px = pos; + CaptureMouse(); + } else if (type == wxEVT_LEFT_UP || type == wxEVT_RIGHT_UP || type == wxEVT_MIDDLE_UP) { + if (m_gesture != Gesture::RotateIslandModal && m_gesture != Gesture::ScaleIslandModal) { + end_gesture(); + Refresh(); + } + } else if (type == wxEVT_MOTION) { + switch (m_gesture) { + case Gesture::Pan: { + const wxSize size = GetSize(); + const float scale = 2.f * m_zoom / float(std::max(1, std::min(size.GetWidth(), size.GetHeight()))); + // Both axes point the same way on screen as in UV space (v runs down), so dragging the + // content along with the cursor is a subtraction on both. + m_pan.x() -= float(pos.x - m_drag_last_px.x) * scale; + m_pan.y() -= float(pos.y - m_drag_last_px.y) * scale; + m_drag_last_px = pos; + Refresh(); + break; + } + case Gesture::MoveIsland: { + const Vec2f uv = screen_to_uv(pos); + if (m_on_island_edit) + m_on_island_edit(m_selected_island, uv_delta_to_unwrap(uv - m_gesture_last_uv), 0.f, 1.f, false); + m_gesture_last_uv = uv; + Refresh(); + break; + } + case Gesture::MoveVertex: { + const Vec2f uv = screen_to_uv(pos); + const Vec2f delta = uv - m_gesture_last_uv; + // Move the whole selection by the same uv-space delta (each vertex converts it through its + // own island transform in move_vertex_raw). Falls back to the primary if none is selected. + if (m_sel_vertices.empty()) + move_vertex_raw(m_active_vertex, delta); + else + for (const int v : m_sel_vertices) + move_vertex_raw(v, delta); + m_gesture_last_uv = uv; + m_vertex_edit_moved = true; + Refresh(); + break; + } + case Gesture::MoveEdge: { + const Vec2f uv = screen_to_uv(pos); + const Vec2f delta = uv - m_gesture_last_uv; + // Move every unique endpoint of every selected edge once. Falls back to the primary edge. + const std::vector endpoints = selected_edge_endpoints(); + if (endpoints.empty()) { + move_vertex_raw(m_active_edge.first, delta); + move_vertex_raw(m_active_edge.second, delta); + } else + for (const int v : endpoints) + move_vertex_raw(v, delta); + m_gesture_last_uv = uv; + m_vertex_edit_moved = true; + Refresh(); + break; + } + case Gesture::RotateIsland: + case Gesture::RotateIslandModal: { + const Vec2f rel = screen_to_uv(pos) - island_centroid(m_selected_island); + const float angle = std::atan2(rel.y(), rel.x()); + // Accumulate the raw mouse rotation incrementally so it survives crossing +/-180 degrees. + m_rot_raw_deg += angle_delta(m_gesture_last_angle, angle) * 180.f / float(M_PI); + m_gesture_last_angle = angle; + + // With Shift, quantise to *global* 15-degree marks (0/15/30...), i.e. snap the island's + // absolute on-screen orientation, not 15 degrees relative to wherever it started (#10) - + // snapping the target rather than each delta is what keeps it from juddering on a step. + constexpr float STEP = 15.f; + const float absolute = m_rot_base_deg + m_rot_raw_deg; + const float target_abs = evt.ShiftDown() ? std::round(absolute / STEP) * STEP : absolute; + const float deg = target_abs - (m_rot_base_deg + m_rot_applied_deg); + if (m_on_island_edit && deg != 0.f) + m_on_island_edit(m_selected_island, Vec2f::Zero(), deg, 1.f, false); + m_rot_applied_deg = target_abs - m_rot_base_deg; + m_rot_display_deg = target_abs; + Refresh(); + break; + } + case Gesture::ScaleIslandModal: { + const Vec2f rel = screen_to_uv(pos) - island_centroid(m_selected_island); + const float dist = std::max(rel.norm(), 1e-6f); + const float factor = dist / m_gesture_last_dist; + if (m_on_island_edit && factor != 1.f) + m_on_island_edit(m_selected_island, Vec2f::Zero(), 0.f, factor, false); + m_modal_scale_accum *= factor; + m_gesture_last_dist = dist; + Refresh(); + break; + } + default: break; + } + } else if (type == wxEVT_MOUSEWHEEL) { + // Zoom about the cursor, not the view centre - otherwise zooming in on something off to the + // side walks it straight out of the frame. + const Vec2f before = screen_to_uv(pos); + const float factor = std::pow(0.9f, float(evt.GetWheelRotation()) / float(evt.GetWheelDelta())); + m_zoom = std::clamp(m_zoom * factor, 0.001f, 5000.f); + const Vec2f after = screen_to_uv(pos); + m_pan += before - after; + if (m_gesture == Gesture::None) + update_hover(pos); + Refresh(); + } +} + +void UVEditorCanvas::rebuild_island_models() +{ + m_mesh_dirty = false; + m_island_wireframe.clear(); + m_island_fill.clear(); + + const int islands = std::max(m_islands.island_count, 0); + if (islands == 0 || m_islands.uvs.empty() || m_islands.indices.empty()) + return; + + m_island_wireframe.resize(size_t(islands)); + m_island_fill.resize(size_t(islands)); + + const int vertex_count = int(m_islands.uvs.size()); + + // Charts have disjoint vertex sets (compute_patch_unwrap() duplicates seam vertices per chart), + // so every vertex belongs to exactly one island and this partition is clean. + std::unordered_map is_boundary; + is_boundary.reserve(m_islands.boundary_edges.size() * 2); + for (const auto &[a, b] : m_islands.boundary_edges) + is_boundary[undirected_edge_key(a, b)] = true; + + // Named, not size_t(islands) inline: the latter is a most-vexing-parse and declares a function + // (a single identifier in the parens reads as a parameter name), which is what every + // "subscript requires array or pointer type" error on these vectors was. + const size_t n_islands = size_t(islands); + + // Global vertex index -> index within its own island's buffers. + std::vector local(m_islands.uvs.size(), -1); + std::vector> island_verts(n_islands); + for (size_t i = 0; i < m_islands.uvs.size(); ++i) { + const int island = m_islands.vertex_island[i]; + if (island < 0 || island >= islands) + continue; + local[i] = int(island_verts[size_t(island)].size()); + island_verts[size_t(island)].push_back(m_islands.uvs[i]); + } + + std::vector wire(n_islands), fill(n_islands); + for (int c = 0; c < islands; ++c) { + wire[size_t(c)].format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + fill[size_t(c)].format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + for (GLModel::Geometry *g : { &wire[size_t(c)], &fill[size_t(c)] }) { + g->reserve_vertices(island_verts[size_t(c)].size()); + for (const Vec2f &uv : island_verts[size_t(c)]) + g->add_vertex(Vec3f(uv.x(), uv.y(), 0.f)); + } + } + + for (const Vec3i32 &tri : m_islands.indices) { + if (tri.minCoeff() < 0 || tri.maxCoeff() >= vertex_count) + continue; + const int island = m_islands.vertex_island[size_t(tri[0])]; + if (island < 0 || island >= islands) + continue; + + fill[size_t(island)].add_triangle(unsigned(local[size_t(tri[0])]), unsigned(local[size_t(tri[1])]), + unsigned(local[size_t(tri[2])])); + // Interior edges only: the island outline is drawn separately, brighter and on top, so drawing + // it here as well would just dim it by blending against itself. + for (int i = 0; i < 3; ++i) { + const int a = tri[i], b = tri[(i + 1) % 3]; + if (!is_boundary.count(undirected_edge_key(a, b))) + wire[size_t(island)].add_line(unsigned(local[size_t(a)]), unsigned(local[size_t(b)])); + } + } + + for (int c = 0; c < islands; ++c) { + if (!wire[size_t(c)].is_empty()) + m_island_wireframe[size_t(c)].init_from(std::move(wire[size_t(c)])); + if (!fill[size_t(c)].is_empty()) + m_island_fill[size_t(c)].init_from(std::move(fill[size_t(c)])); + } +} + +void UVEditorCanvas::rebuild_grid() +{ + // One line per UV unit (i.e. per texture tile), plus a subdivision when zoomed in far enough that + // whole tiles would be too coarse to read. + const float span = 2.f * m_zoom; + float step = 1.f; + while (step > 0.01f && span / step > 40.f) + step *= 2.f; + while (span / step < 4.f) + step *= 0.5f; + + // Cover exactly the currently-visible view rectangle (plus a one-step margin), recomputed on every + // render. The old version only rebuilt when `step` changed, so panning at a fixed zoom left the grid + // frozen at wherever it was last built - which is the "not in whole area / not always rendered while + // moving" the user saw. The grid is only a few dozen lines, so rebuilding it per frame is cheap. + float half_w, half_h; + view_half_extents(half_w, half_h); + const Vec2f lo = m_pan - Vec2f(half_w, half_h) - Vec2f(step, step); + const Vec2f hi = m_pan + Vec2f(half_w, half_h) + Vec2f(step, step); + m_grid_step = step; + + const int first_x = int(std::floor(lo.x() / step)), last_x = int(std::ceil(hi.x() / step)); + const int first_y = int(std::floor(lo.y() / step)), last_y = int(std::ceil(hi.y() / step)); + if (last_x - first_x > 4000 || last_y - first_y > 4000) + return; // degenerate zoom; not worth drawing a grid nobody can see + + GLModel::Geometry grid; + grid.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + unsigned index = 0; + const auto line = [&](const Vec2f &a, const Vec2f &b) { + grid.add_vertex(Vec3f(a.x(), a.y(), 0.f)); + grid.add_vertex(Vec3f(b.x(), b.y(), 0.f)); + grid.add_line(index, index + 1); + index += 2; + }; + for (int i = first_x; i <= last_x; ++i) + line(Vec2f(float(i) * step, lo.y()), Vec2f(float(i) * step, hi.y())); + for (int i = first_y; i <= last_y; ++i) + line(Vec2f(lo.x(), float(i) * step), Vec2f(hi.x(), float(i) * step)); + + m_grid_glmodel.reset(); + if (!grid.is_empty()) + m_grid_glmodel.init_from(std::move(grid)); +} + +void UVEditorCanvas::rebuild_rotation_dial() +{ + m_dial_glmodel.reset(); + const bool rotating = (m_gesture == Gesture::RotateIsland || m_gesture == Gesture::RotateIslandModal); + if (!rotating || m_selected_island < 0) + return; + + const wxSize size = GetSize(); + const float uv_per_px = 2.f * m_zoom / float(std::max(1, std::min(size.GetWidth(), size.GetHeight()))); + const float radius = 90.f * uv_per_px; // ~constant on-screen size regardless of zoom + const Vec2f centre = island_centroid(m_selected_island); + + GLModel::Geometry dial; + dial.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; + unsigned index = 0; + const auto line = [&](const Vec2f &a, const Vec2f &b) { + dial.add_vertex(Vec3f(a.x(), a.y(), 0.f)); + dial.add_vertex(Vec3f(b.x(), b.y(), 0.f)); + dial.add_line(index, index + 1); + index += 2; + }; + const auto on_ring = [&](float deg, float r) { + const float a = deg * float(M_PI) / 180.f; + return centre + r * Vec2f(std::cos(a), std::sin(a)); + }; + + // The ring itself. + constexpr int SEG = 72; + for (int i = 0; i < SEG; ++i) + line(on_ring(float(i) * 360.f / SEG, radius), on_ring(float(i + 1) * 360.f / SEG, radius)); + // A tick every 15 degrees (the snap marks), longer on the cardinals. + for (int d = 0; d < 360; d += 15) { + const bool cardinal = (d % 90) == 0; + line(on_ring(float(d), radius * (cardinal ? 0.80f : 0.90f)), on_ring(float(d), radius * (cardinal ? 1.08f : 1.0f))); + } + // The needle at the island's current absolute angle. + line(centre, on_ring(m_rot_display_deg, radius * 1.12f)); + + if (!dial.is_empty()) + m_dial_glmodel.init_from(std::move(dial)); +} + +void UVEditorCanvas::rebuild_background_quad() +{ + m_background_glmodel.reset(); + m_background_quad_dirty = false; + if (m_background_width <= 0 || m_background_height <= 0) + return; + + Vec2f lo, hi; + if (m_tile_enabled) { + // Whole tiles, so the backdrop's edge lands on a tile boundary instead of slicing a brick in + // half. framed_bounds() applies exactly this, and the view is framed on its result - the two + // must not drift apart or the backdrop stops being centred in the pane. + framed_bounds(lo, hi); + } else { + // Tiling off: the sampler reads 0 outside the first tile and nothing else exists, so the + // backdrop is exactly that one tile (GL_CLAMP_TO_BORDER in render() gives it the same + // black surround, rather than smearing the edge texels outward). + lo = Vec2f(0.f, 0.f); + hi = Vec2f(1.f, 1.f); + } + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2 }; + init_data.reserve_vertices(4); + init_data.reserve_indices(6); + // Texcoord == position: the height sampling maps one whole texture onto each unit square of uv + // (see DecodedHeightTexture::sample()), so uv *is* the texture coordinate. That also puts the + // texture's first pixel row at v = 0, exactly where sample() reads it. + init_data.add_vertex(Vec3f(lo.x(), lo.y(), 0.f), Vec2f(lo.x(), lo.y())); + init_data.add_vertex(Vec3f(hi.x(), lo.y(), 0.f), Vec2f(hi.x(), lo.y())); + init_data.add_vertex(Vec3f(hi.x(), hi.y(), 0.f), Vec2f(hi.x(), hi.y())); + init_data.add_vertex(Vec3f(lo.x(), hi.y(), 0.f), Vec2f(lo.x(), hi.y())); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(0, 2, 3); + m_background_glmodel.init_from(std::move(init_data)); +} + +void UVEditorCanvas::rebuild_background_texture() +{ + m_background_texture.reset(); + m_background_dirty = false; + if (m_background_width > 0 && m_background_height > 0) + m_background_texture.load_from_raw_data(m_background_pixels, (unsigned int) m_background_width, + (unsigned int) m_background_height, false); + // The quad's extent doesn't depend on the pixels, but it does have to exist alongside them. + m_background_quad_dirty = true; +} + +void UVEditorCanvas::on_paint(wxPaintEvent & /*evt*/) +{ + wxPaintDC dc(this); + render(); +} + +void UVEditorCanvas::on_size(wxSizeEvent &evt) +{ + evt.Skip(); + // Refresh() alone only *schedules* a repaint, which Windows can coalesce/delay until a live + // resize drag ends, leaving stale wrong-aspect-ratio content on screen throughout the drag. + // Update() flushes it immediately - still through the normal paint path (unlike calling + // render() directly), which matters because this canvas shares the app's one GL context with + // the 3D view and must not hijack it outside its own paint. + Refresh(); + Update(); +} + +void UVEditorCanvas::on_leave(wxMouseEvent &evt) +{ + evt.Skip(); + if (m_cursor_inside) { + m_cursor_inside = false; + // The +/- hint and the hover highlight were following the cursor; drop them now the pointer is gone. + if (m_gesture == Gesture::None) { + m_hover_island = m_hover_vertex = -1; + m_hover_edge = { -1, -1 }; + } + Refresh(); + } +} + +void UVEditorCanvas::render() +{ + if (m_context == nullptr || !IsShownOnScreen()) + return; + + // wxGLCanvas::SetCurrent() genuinely fails (returns false) on a canvas that isn't shown on + // screen, and can also fail on a pixel-format mismatch with the context - and every GL call + // made afterwards would then run against whichever context *is* current, which here is the main + // 3D canvas mid-frame. Bail instead of corrupting it. + if (!SetCurrent(*m_context)) + return; + + // The context is shared with the 3D view, which leaves its own state behind: GLCanvas3D turns face culling on at + // init and many of its passes turn it back on, and the pane's projection flips Y, so every triangle drawn here + // faces away from it. With culling left on, the texture and the islands simply vanish - which is why they showed + // the first time and were gone, fully or partly, after the 3D view had drawn. A scissor rectangle left on would + // clip the clear and everything else the same way. Set what this pass relies on; put the 3D view's back after. + const GLboolean prev_cull = ::glIsEnabled(GL_CULL_FACE); + const GLboolean prev_scissor = ::glIsEnabled(GL_SCISSOR_TEST); + const GLboolean prev_stencil = ::glIsEnabled(GL_STENCIL_TEST); + glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glDisable(GL_SCISSOR_TEST)); + glsafe(::glDisable(GL_STENCIL_TEST)); + glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); + glsafe(::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)); + + if (m_gl_reset_pending) { + m_gl_reset_pending = false; + m_mesh_dirty = true; + m_background_dirty = true; // re-uploads m_background_pixels, or drops the texture if there are none + m_tile_outline_glmodel.reset(); + m_vertex_marker_glmodel.reset(); + m_dim_quad_glmodel.reset(); + m_stroke_glmodel.reset(); + m_stencil_bits = -1; + } + if (m_mesh_dirty) + rebuild_island_models(); + if (m_background_dirty) + rebuild_background_texture(); + if (m_background_quad_dirty) + rebuild_background_quad(); + if (m_needs_fit) + fit_view_to_content(); + rebuild_grid(); + rebuild_rotation_dial(); + + const wxSize size = GetSize(); // logical points; the on-screen handle sizes below use it + const wxSize viewport = gl_drawable_size(this, size); + glsafe(::glViewport(0, 0, viewport.GetWidth(), viewport.GetHeight())); + // Line widths below are authored in logical points (they are chosen against the same scale the + // hit-test thresholds use), so they take the same logical -> device conversion as the viewport. + const float px_scale = float(viewport.GetWidth()) / float(std::max(1, size.GetWidth())); + const auto line_width = [px_scale](float w) { set_line_width(w * px_scale); }; + glsafe(::glClearColor(UV_COLOR_BG.r(), UV_COLOR_BG.g(), UV_COLOR_BG.b(), 1.f)); + glsafe(::glClearStencil(0)); + glsafe(::glStencilMask(0xFF)); + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + // Orthographic, centered on m_pan. Y is negated so v runs down the screen, which is what puts + // the texture's first pixel row (v = 0, see rebuild_background_quad()) at the top rather than + // upside down. + float half_w, half_h; + view_half_extents(half_w, half_h); + + Transform3d projection_matrix = Transform3d::Identity(); + projection_matrix(0, 0) = 1.0 / std::max(double(half_w), 1e-6); + projection_matrix(1, 1) = -1.0 / std::max(double(half_h), 1e-6); + Transform3d view_matrix = Transform3d::Identity(); + view_matrix.translate(Vec3d(-double(m_pan.x()), -double(m_pan.y()), 0.0)); + + const auto draw_raw = [&](GLModel &model, const ColorRGBA &color, const Transform3d &view_model, const Transform3d &projection) { + if (!model.is_initialized()) + return; + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + shader->start_using(); + shader->set_uniform("view_model_matrix", view_model); + shader->set_uniform("projection_matrix", projection); + model.set_color(color); + model.render(); + shader->stop_using(); + }; + const auto draw = [&](GLModel &model, const ColorRGBA &color, const Transform3d &model_matrix) { + draw_raw(model, color, view_matrix * model_matrix, projection_matrix); + }; + const Transform3d identity = Transform3d::Identity(); + + if (m_background_glmodel.is_initialized()) { + if (GLShaderProgram *shader = wxGetApp().get_shader("flat_texture")) { + shader->start_using(); + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", projection_matrix); + glsafe(::glActiveTexture(GL_TEXTURE0)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_background_texture.get_id())); + // Repeat exactly the way DecodedHeightTexture::sample() does, so the backdrop under an + // island really is the texels that island will sample. With tiling off, sample() returns + // 0 outside the first tile - a black border, not a smeared edge, which is what + // CLAMP_TO_BORDER reproduces (GLTexture's own default of GL_REPEAT would not). + const GLint wrap = m_tile_enabled ? (m_tile_mirrored ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_BORDER; + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap)); + if (!m_tile_enabled) { + constexpr GLfloat border[4] = { 0.f, 0.f, 0.f, 1.f }; + glsafe(::glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border)); + } + m_background_glmodel.render(); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); + shader->stop_using(); + } + } + + const auto island_matrix = [this, &identity](int c) { + return (size_t(c) < m_transforms.size()) ? to_transform3d(m_transforms[size_t(c)]) : identity; + }; + const float uv_per_px = 2.f * m_zoom / float(std::max(1, std::min(size.GetWidth(), size.GetHeight()))); + + // Strokes are built as quads `width_px` wide on screen, rebuilt every paint at the current zoom. Square caps + // cover the joints of an outline; the colours passed here are opaque, so the overlapping caps don't show. + using Segments = std::vector>; + const auto draw_segments = [&](const Segments &segments, float width_px, const ColorRGBA &color) { + if (segments.empty()) + return; + const float half = 0.5f * width_px * uv_per_px; + GLModel::Geometry quads; + quads.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + quads.reserve_vertices(segments.size() * 4); + quads.reserve_indices(segments.size() * 6); + unsigned base = 0; + for (const auto &[a, b] : segments) { + const Vec2f d = b - a; + const float len = d.norm(); + if (len <= 1e-12f) + continue; + const Vec2f t = d * (half / len); + const Vec2f n(-t.y(), t.x()); + for (const Vec2f &p : { Vec2f(a - t + n), Vec2f(a - t - n), Vec2f(b + t - n), Vec2f(b + t + n) }) + quads.add_vertex(Vec3f(p.x(), p.y(), 0.f)); + quads.add_triangle(base, base + 1, base + 2); + quads.add_triangle(base, base + 2, base + 3); + base += 4; + } + m_stroke_glmodel.reset(); + if (quads.is_empty()) + return; + m_stroke_glmodel.init_from(std::move(quads)); + draw(m_stroke_glmodel, color, identity); + }; + const auto draw_stroke = [&](const Segments &segments, float width_px, const ColorRGBA &color, float halo_px) { + draw_segments(segments, width_px + 2.f * halo_px, UV_COLOR_HALO); + draw_segments(segments, width_px, color); + }; + const auto edge_segments = [this](const std::vector> &edges) { + Segments out; + out.reserve(edges.size()); + for (const auto &[a, b] : edges) + if (a >= 0 && b >= 0 && size_t(a) < m_islands.uvs.size() && size_t(b) < m_islands.uvs.size()) + out.emplace_back(island_uv(size_t(a)), island_uv(size_t(b))); + return out; + }; + + // Dim the texture everywhere but inside the islands: the fills go into the stencil only, then one + // full-viewport quad washes the rest towards the background. Skipped without a stencil buffer, where the + // quad would cover the islands too. + if (m_stencil_bits < 0) { + GLint bits = 0; + ::glGetError(); // drop anything pending, so the check below sees only this query + ::glGetIntegerv(GL_STENCIL_BITS, &bits); // compatibility profiles + if (::glGetError() != GL_NO_ERROR) { + bits = 0; + ::glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &bits); + ::glGetError(); + } + m_stencil_bits = std::max(0, int(bits)); + } + if (has_islands() && !m_island_fill.empty() && m_stencil_bits > 0) { + if (!m_dim_quad_glmodel.is_initialized()) { + GLModel::Geometry q; + q.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + q.add_vertex(Vec3f(-1.f, -1.f, 0.f)); + q.add_vertex(Vec3f(1.f, -1.f, 0.f)); + q.add_vertex(Vec3f(1.f, 1.f, 0.f)); + q.add_vertex(Vec3f(-1.f, 1.f, 0.f)); + q.add_triangle(0, 1, 2); + q.add_triangle(0, 2, 3); + m_dim_quad_glmodel.init_from(std::move(q)); + } + glsafe(::glEnable(GL_STENCIL_TEST)); + glsafe(::glStencilFunc(GL_ALWAYS, 1, 0xFF)); + glsafe(::glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)); + glsafe(::glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)); + for (int c = 0; c < int(m_island_fill.size()); ++c) + draw(m_island_fill[size_t(c)], ColorRGBA::WHITE(), island_matrix(c)); + glsafe(::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)); + glsafe(::glStencilFunc(GL_EQUAL, 0, 0xFF)); + glsafe(::glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)); + draw_raw(m_dim_quad_glmodel, UV_COLOR_OUTSIDE, identity, identity); + glsafe(::glDisable(GL_STENCIL_TEST)); + } + + line_width(1.f); + draw(m_grid_glmodel, UV_COLOR_GRID, identity); + + // The texture's first tile. Always drawn, even with nothing painted, so the pane always has a + // fixed landmark: the unwrap is packed in mm and divided by the tile size, so it is routinely + // many tiles away from here, and without this there is no way to tell "the islands are somewhere + // else" apart from "there are no islands". + draw_stroke({ { Vec2f(0.f, 0.f), Vec2f(1.f, 0.f) }, { Vec2f(1.f, 0.f), Vec2f(1.f, 1.f) }, + { Vec2f(1.f, 1.f), Vec2f(0.f, 1.f) }, { Vec2f(0.f, 1.f), Vec2f(0.f, 0.f) } }, + 1.5f, UV_COLOR_TILE_OUTLINE, 1.f); + + // Island fills. Unselected islands get none, so the texture that will be baked shows unaltered; the one a + // click would grab gets a light wash, the selection a teal one. A distortion heatmap (set_island_fill_colors) + // replaces the default for unselected islands and is left alone by the hover wash. + for (int c = 0; c < int(m_island_fill.size()); ++c) { + ColorRGBA fill = size_t(c) < m_island_fill_colors.size() ? m_island_fill_colors[size_t(c)] : UV_COLOR_FILL; + if (is_selected(c)) + fill = UV_COLOR_SEL_FILL; + else if (c == m_hover_island && m_island_fill_colors.empty()) + fill = UV_COLOR_HOVER_FILL; + if (fill.a() > 0.f) + draw(m_island_fill[size_t(c)], fill, island_matrix(c)); + } + + // Interior edges stay GL lines (a patch can have a million of them), each with a dark copy one pixel down + // and right, so the light wire still reads on a light texture. + Transform3d shadow_projection = projection_matrix; + shadow_projection.pretranslate(Vec3d(2.0 / std::max(1, size.GetWidth()), -2.0 / std::max(1, size.GetHeight()), 0.0)); + line_width(1.f); + for (int c = 0; c < int(m_island_wireframe.size()); ++c) { + draw_raw(m_island_wireframe[size_t(c)], UV_COLOR_WIRE_SHADOW, view_matrix * island_matrix(c), shadow_projection); + draw(m_island_wireframe[size_t(c)], is_selected(c) ? UV_COLOR_SEL_WIRE : UV_COLOR_WIRE, island_matrix(c)); + } + + // The island outlines - i.e. exactly the edges the seam angle cut the patch along - because "where does one + // island end and the next begin" is the single thing this pane exists to answer. Plain first, then the hovered + // one, then the selection, so a highlighted outline is never overdrawn by its neighbour's. + { + std::vector> plain, hovered, selected; + for (int c = 0; c < int(m_island_boundary_edges.size()); ++c) { + auto &dst = is_selected(c) ? selected : (c == m_hover_island ? hovered : plain); + dst.insert(dst.end(), m_island_boundary_edges[size_t(c)].begin(), m_island_boundary_edges[size_t(c)].end()); + } + draw_stroke(edge_segments(plain), 1.5f, UV_COLOR_BOUNDARY, 1.25f); + draw_stroke(edge_segments(hovered), 2.5f, UV_COLOR_HOVER, 1.5f); + draw_stroke(edge_segments(selected), 3.f, UV_COLOR_SEL_BOUNDARY, 1.75f); + } + + // The rotation protractor, on top of everything while a rotation gesture is live (#11). + if (m_dial_glmodel.is_initialized()) { + line_width(2.f); + draw(m_dial_glmodel, UV_COLOR_DIAL, identity); + line_width(1.f); + } + + // Vertex/Edge mode: the element under the cursor in the hover colour, and the selection as teal - a selected + // edge drawn over its whole length, a vertex as a square handle, both on a dark halo. + if (!m_vertex_marker_glmodel.is_initialized()) { + GLModel::Geometry q; + q.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; + q.reserve_vertices(4); + q.reserve_indices(6); + q.add_vertex(Vec3f(-0.5f, -0.5f, 0.f)); + q.add_vertex(Vec3f(0.5f, -0.5f, 0.f)); + q.add_vertex(Vec3f(0.5f, 0.5f, 0.f)); + q.add_vertex(Vec3f(-0.5f, 0.5f, 0.f)); + q.add_triangle(0, 1, 2); + q.add_triangle(0, 2, 3); + m_vertex_marker_glmodel.init_from(std::move(q)); + } + const auto draw_marker = [&](int v, float px, const ColorRGBA &color) { + if (v < 0 || size_t(v) >= m_islands.uvs.size()) + return; + const Vec2f p = island_uv(size_t(v)); + Transform3d m = Transform3d::Identity(); + m.translate(Vec3d(double(p.x()), double(p.y()), 0.0)); + m.scale(double(px * uv_per_px)); + draw(m_vertex_marker_glmodel, color, m); + }; + const auto draw_handle = [&](int v, const ColorRGBA &color, float px) { + draw_marker(v, px + 4.f, UV_COLOR_HALO); + draw_marker(v, px, color); + }; + if (m_select_mode == SelectMode::Vertex) { + if (m_hover_vertex >= 0 && !is_vertex_selected(m_hover_vertex)) + draw_handle(m_hover_vertex, UV_COLOR_HOVER, 7.f); + // Every element of the multi-selection, falling back to the primary while the set is still empty. + if (m_sel_vertices.empty()) + draw_handle(m_active_vertex, UV_COLOR_SEL_BOUNDARY, 8.f); + else + for (const int v : m_sel_vertices) + draw_handle(v, UV_COLOR_SEL_BOUNDARY, 8.f); + } else if (m_select_mode == SelectMode::Edge) { + if (m_hover_edge.first >= 0 && !is_edge_selected(m_hover_edge)) + draw_stroke(edge_segments({ m_hover_edge }), 3.f, UV_COLOR_HOVER, 2.f); + std::vector> edges = m_sel_edges; + if (edges.empty() && m_active_edge.first >= 0) + edges.push_back(m_active_edge); + draw_stroke(edge_segments(edges), 4.f, UV_COLOR_SEL_BOUNDARY, 2.f); + for (const auto &[a, b] : edges) { + draw_handle(a, UV_COLOR_SEL_BOUNDARY, 6.f); + draw_handle(b, UV_COLOR_SEL_BOUNDARY, 6.f); + } + } + + // Add/remove hint next to the cursor in Vertex/Edge mode: a green '+' when a click will add to the + // selection (plain or Shift), a red '-' when Ctrl is held and a click will remove one - the UV-side + // twin of the 3D paint cursor's own sign. + if (m_select_mode != SelectMode::Island && m_cursor_inside) { + const Vec2f centre = screen_to_uv(m_cursor_px) + Vec2f(14.f, -14.f) * uv_per_px; // up-right of the pointer + const float r = 6.f * uv_per_px; + const bool removing = wxGetKeyState(WXK_CONTROL); + Segments sign{ { centre - Vec2f(r, 0.f), centre + Vec2f(r, 0.f) } }; // the '-' bar, shared by both signs + if (!removing) + sign.emplace_back(centre - Vec2f(0.f, r), centre + Vec2f(0.f, r)); // the extra stroke that makes it a '+' + draw_stroke(sign, 2.5f, removing ? ColorRGBA(1.f, 0.36f, 0.30f, 1.f) : ColorRGBA(0.40f, 0.92f, 0.50f, 1.f), 1.f); + } + + // The GL context is shared with the 3D view; leave the bits we touched as we found them. + glsafe(::glDisable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); + if (prev_cull) + glsafe(::glEnable(GL_CULL_FACE)); + if (prev_scissor) + glsafe(::glEnable(GL_SCISSOR_TEST)); + if (prev_stencil) + glsafe(::glEnable(GL_STENCIL_TEST)); + + SwapBuffers(); + + // Cheap, and render() runs on every gesture change (each Refresh), so the status line stays + // current without threading update_status() through every mouse/key transition. The panel + // guards against relayout when the text is unchanged. + update_status(); +} + +// ----------------------------------------------- +// UVEditorPanel +// ----------------------------------------------- + +namespace { +enum : int { + ID_UV_FRAME = wxID_HIGHEST + 4200, + ID_UV_SNAP, + ID_UV_AVG_SCALE, + ID_UV_CUT, + ID_UV_JOIN, + ID_UV_UNJOIN, + ID_UV_UNWRAP, + ID_UV_MARK_SEAMS, + ID_UV_SEAM_PATH, + ID_UV_CLEAR_SEAMS, + ID_UV_CLEAR_EDITS, + ID_UV_SELECT_ISLAND, // + SelectMode + ID_UV_SELECT_VERTEX, + ID_UV_SELECT_EDGE, + ID_UV_BG_HEIGHT, // + Background + ID_UV_BG_CHECKER, + ID_UV_BG_DISTORTION, + ID_UV_PICK_TEXTURE, +}; + +// An icon from resources/images, rasterised at the window's real pixel density. On GTK3 create_scaled_bitmap() +// renders at the DIP size and lets GTK upscale that on a HiDPI screen, which is what made these small icons blurry; +// here the SVG is rendered at device pixels instead and tagged with the scale, so it is drawn 1:1. (Windows renders +// at device pixels already, and macOS through BitmapCache's own backing scale.) +wxBitmap pane_icon(wxWindow *win, const std::string &name, int size_dip) +{ +#ifdef __WXGTK3__ + if (const double scale = win->GetContentScaleFactor(); scale > 1.0) { + static BitmapCache cache; + const unsigned px = unsigned(std::lround(size_dip * scale)); + if (wxBitmap *bmp = cache.load_svg(name, 0, px, false, wxGetApp().dark_mode()); bmp != nullptr && bmp->IsOk()) + return wxBitmap(bmp->ConvertToImage(), -1, scale); + } +#endif + return create_scaled_bitmap(name, win, size_dip); +} + +// The size a bitmap takes on screen, in the units a wxDC draws in on this platform. +wxSize drawn_size(const wxBitmap &bmp) +{ +#ifdef __WXGTK3__ + return bmp.GetLogicalSize(); +#else + return ScalableBitmap::GetBmpSize(bmp); +#endif +} + +// `bmp` with its alpha scaled down, for a disabled control. Keeps the bitmap's scale factor, so it stays sharp. +wxBitmap faded(const wxBitmap &bmp, double alpha) +{ + wxImage image = bmp.ConvertToImage(); + if (!image.HasAlpha()) + image.InitAlpha(); + unsigned char *a = image.GetAlpha(); + for (int i = 0, n = image.GetWidth() * image.GetHeight(); i < n; ++i) + a[i] = (unsigned char) std::lround(a[i] * alpha); + return wxBitmap(image, -1, bmp.GetScaleFactor()); +} + +// The pane's colours, matching the texture displacement panel's ImGui style in both themes. +struct PaneColors +{ + wxColour bg, ink, dim, rule, frame, hover; + static PaneColors current() + { + if (wxGetApp().dark_mode()) + return { wxColour(0x2d, 0x2d, 0x31), wxColour(0xef, 0xef, 0xf0), wxColour(0x90, 0x90, 0x96), + wxColour(0x3d, 0x3d, 0x45), wxColour(0x36, 0x36, 0x3c), wxColour(0x49, 0x49, 0x50) }; + return { wxColour(0xff, 0xff, 0xff), wxColour(0x32, 0x3a, 0x3d), wxColour(0x7c, 0x82, 0x82), + wxColour(0xed, 0xed, 0xed), wxColour(0xce, 0xce, 0xce), wxColour(0xee, 0xee, 0xee) }; + } +}; + +wxColour mix(const wxColour &a, const wxColour &b, double t) +{ + const auto ch = [t](unsigned char x, unsigned char y) { return (unsigned char) std::lround(x + (y - x) * t); }; + return wxColour(ch(a.Red(), b.Red()), ch(a.Green(), b.Green()), ch(a.Blue(), b.Blue())); +} +} // namespace + +// An icon button - square, or with a label beside the icon - drawn the way the texture displacement panel draws +// its own: a 1 px frame, a teal frame over a teal tint while a toggle is on, a solid teal fill for the one +// accent action, and an optional amber dot for "needs attention". Drawn by hand rather than with wxButton / +// wxToggleButton so the pane looks the same on every platform and in both themes. +// +// A click emits wxEVT_BUTTON with the button's id; for a toggle the event's int is the new state. The owner +// may overwrite that state again with SetValue() - which is how radio groups and gizmo-owned flags work. +class UVToolButton : public wxWindow +{ +public: + UVToolButton(wxWindow *parent, wxWindowID id, const std::string &icon, const wxString &label, const wxString &tip, + bool toggle, bool accent = false, int size_dip = 26) + : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxFULL_REPAINT_ON_RESIZE) + , m_icon_name(icon), m_icon_dip(size_dip >= 26 ? 16 : 14), m_label(label), m_toggle(toggle), m_accent(accent) + , m_size_dip(size_dip) + { + SetBackgroundStyle(wxBG_STYLE_PAINT); + SetToolTip(tip); + if (accent) { + wxFont font = GetFont(); + font.MakeBold(); + SetFont(font); + } + Bind(wxEVT_PAINT, &UVToolButton::on_paint, this); + Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent &) { m_hover = true; Refresh(); }); + Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &) { m_hover = false; m_pressed = false; Refresh(); }); + Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &) { + if (IsEnabled()) { + m_pressed = true; + Refresh(); + } + }); + Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) { + const bool was_pressed = m_pressed; + m_pressed = false; + Refresh(); + if (!was_pressed || !IsEnabled() || !GetClientRect().Contains(e.GetPosition())) + return; + if (m_toggle) + m_on = !m_on; + wxCommandEvent evt(wxEVT_BUTTON, GetId()); + evt.SetEventObject(this); + evt.SetInt(m_on ? 1 : 0); + ProcessWindowEvent(evt); + }); + SetMinSize(DoGetBestSize()); + } + + void SetValue(bool on) + { + if (on != m_on) { + m_on = on; + Refresh(); + } + } + bool GetValue() const { return m_on; } + // Shows a ready-made bitmap instead of the SVG icon (the layer thumbnail). Its scale factor sets its size. + void SetBitmap(const wxBitmap &bmp) + { + m_bitmap = bmp; + Refresh(); + } + void SetBadge(bool badge) + { + if (badge != m_badge) { + m_badge = badge; + Refresh(); + } + } + bool Enable(bool enable = true) override + { + const bool changed = wxWindow::Enable(enable); + if (changed) + Refresh(); + return changed; + } + +protected: + wxSize DoGetBestSize() const override + { + const int h = FromDIP(m_size_dip); + if (m_label.empty()) + return wxSize(h, h); + const int icon_w = m_icon_name.empty() ? 0 : FromDIP(m_icon_dip) + FromDIP(6); + return wxSize(FromDIP(9) + icon_w + GetTextExtent(m_label).x + FromDIP(10), h); + } + +private: + void on_paint(wxPaintEvent &) + { + wxAutoBufferedPaintDC dc(this); + const PaneColors c = PaneColors::current(); + const wxRect r = GetClientRect(); + const wxColour teal(0x00, 0x96, 0x88); + const bool enabled = IsEnabled(); + + wxColour fill = c.bg, border = c.frame, text = c.ink; + if (m_accent) { + fill = (m_hover && enabled) ? wxColour(0x26, 0xa6, 0x9a) : teal; + border = fill; + text = *wxWHITE; + } else if (m_on) { + fill = mix(c.bg, teal, 0.22); + border = teal; + } else if (m_hover && enabled) { + fill = c.hover; + } + if (m_pressed) + fill = mix(fill, teal, 0.18); + + dc.SetBackground(wxBrush(c.bg)); + dc.Clear(); + dc.SetBrush(wxBrush(fill)); + dc.SetPen(wxPen(border, 1)); + dc.DrawRoundedRectangle(r, FromDIP(2)); + + // Rasterised on first paint rather than in the constructor: the content scale is only reliable once the + // window is on screen, and it changes when the window moves to a screen with a different one. + if (!m_icon_name.empty() && (!m_icon.IsOk() || m_icon_scale != GetContentScaleFactor())) { + m_icon_scale = GetContentScaleFactor(); + m_icon = pane_icon(this, m_icon_name, m_icon_dip); + } + const wxBitmap &bmp = m_bitmap.IsOk() ? m_bitmap : m_icon; + int x = 0; + if (bmp.IsOk()) { + const wxSize bs = drawn_size(bmp); + x = m_label.empty() ? (r.width - bs.x) / 2 : FromDIP(9); + dc.DrawBitmap(enabled ? bmp : faded(bmp, 0.35), x, (r.height - bs.y) / 2, true); + x += bs.x + FromDIP(6); + } else { + x = FromDIP(9); + } + if (!m_label.empty()) { + dc.SetFont(GetFont()); + dc.SetTextForeground(enabled ? text : mix(text, c.bg, 0.55)); + dc.DrawText(m_label, x, (r.height - dc.GetTextExtent(m_label).y) / 2); + } + if (m_badge) { + const int d = FromDIP(9); + dc.SetPen(wxPen(c.bg, FromDIP(2))); + dc.SetBrush(wxBrush(wxColour(0xe0, 0xa4, 0x4a))); + dc.DrawCircle(r.width - d / 2 - 1, d / 2 + 1, d / 2); + } + } + + std::string m_icon_name; + int m_icon_dip = 16; + wxBitmap m_icon; // m_icon_name rasterised for m_icon_scale + double m_icon_scale = 0.; + wxBitmap m_bitmap; + wxString m_label; + bool m_toggle = false; + bool m_accent = false; + int m_size_dip = 26; + bool m_on = false; + bool m_badge = false; + bool m_hover = false; + bool m_pressed = false; +}; + +UVEditorPanel::UVEditorPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) +{ + const PaneColors c = PaneColors::current(); + const int gap = FromDIP(6); + const int pad = FromDIP(8); + SetBackgroundColour(c.bg); + + const auto rule = [&](const wxSize &size) { + auto *w = new wxWindow(this, wxID_ANY, wxDefaultPosition, size); + w->SetBackgroundColour(c.rule); + w->SetMinSize(size); + return w; + }; + const auto text = [&](const wxString &label, const wxColour &colour, long style = 0) { + auto *t = new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, style); + t->SetForegroundColour(colour); + t->SetBackgroundColour(c.bg); + return t; + }; + + // ---- header: the layer being edited, the background under the islands, and Unwrap ---- + auto *header = new wxBoxSizer(wxHORIZONTAL); + m_thumb = new UVToolButton(this, ID_UV_PICK_TEXTURE, std::string(), wxEmptyString, + _L("Change texture - choose another one from the texture library"), false, false, 26); + m_layer_name = text(wxEmptyString, c.ink, wxST_ELLIPSIZE_END); + { + wxFont font = m_layer_name->GetFont(); + font.MakeBold(); + m_layer_name->SetFont(font); + } + // The name opens the library too, like the texture's name in the layer card. + m_layer_name->SetCursor(wxCursor(wxCURSOR_HAND)); + m_layer_name->SetToolTip(m_thumb->GetToolTipText()); + m_layer_name->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &) { + if (m_canvas->pane_state().has_layer) + m_canvas->run_command(UVEditorCanvas::Command::PickTexture); + }); + m_layer_name->SetMinSize(wxSize(FromDIP(30), -1)); + m_tile = text(wxEmptyString, c.dim); + header->Add(m_thumb, 0, wxALIGN_CENTER_VERTICAL); + header->Add(m_layer_name, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, gap); + header->Add(m_tile, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, gap); + + const char *const bg_icons[3] = { "texture_displacement_uv_bg_height", "texture_displacement_checker", + "texture_displacement_distortion" }; + const wxString bg_tips[3] = { _L("Height map - show the layer's texture under the islands"), + _L("Checker - a test grid; squares stay square where the unwrap does not stretch"), + _L("Distortion - colour each island by how much the unwrap stretches it") }; + for (int i = 0; i < 3; ++i) { + m_background[i] = new UVToolButton(this, ID_UV_BG_HEIGHT + i, bg_icons[i], wxEmptyString, bg_tips[i], true, false, 22); + header->Add(m_background[i], 0, wxALIGN_CENTER_VERTICAL | wxLEFT, i == 0 ? gap : FromDIP(3)); + } + header->Add(rule(wxSize(1, FromDIP(18))), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, gap); + m_unwrap = new UVToolButton(this, ID_UV_UNWRAP, "texture_displacement_map_unwrap", _L("Unwrap"), wxEmptyString, false, true, 24); + header->Add(m_unwrap, 0, wxALIGN_CENTER_VERTICAL); + + // ---- settings: what the next Unwrap will do ---- + auto *settings = new wxBoxSizer(wxHORIZONTAL); + auto *seam_label = text(_L("Seam angle"), c.dim); + m_seam_angle = new ::SpinInput(this, wxEmptyString, wxString::FromUTF8("°"), wxDefaultPosition, wxSize(FromDIP(76), FromDIP(24)), 0, + 5, 90, 40); + const wxString seam_tip = _L("Edges sharper than this are cut, and the pieces either side of them are flattened separately. " + "Lower it to cut more: each piece then lies flat with less stretching, at the cost of the " + "texture not running continuously across the cut. Takes effect at the next Unwrap."); + seam_label->SetToolTip(seam_tip); + m_seam_angle->SetToolTip(seam_tip); + m_connect = new ::CheckBox(this); + auto *connect_label = text(_L("Connect islands"), c.ink); + const wxString connect_tip = _L("Lay the unwrap out as a connected net: pieces that share an edge are unfolded next to each " + "other (a cube becomes a joined net rather than six loose squares). They stay separate " + "islands, so you can still move any of them by hand afterwards."); + m_connect->SetToolTip(connect_tip); + connect_label->SetToolTip(connect_tip); + settings->Add(seam_label, 0, wxALIGN_CENTER_VERTICAL); + settings->Add(m_seam_angle, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, gap); + settings->AddStretchSpacer(); + settings->Add(m_connect, 0, wxALIGN_CENTER_VERTICAL); + settings->Add(connect_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(4)); + + // ---- tool strip ---- + auto *strip = new wxBoxSizer(wxVERTICAL); + const auto tool = [&](int id, const char *icon, const wxString &tip, bool toggle) { + auto *b = new UVToolButton(this, id, icon, wxEmptyString, tip, toggle); + strip->Add(b, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(4)); + return b; + }; + // 11 px either side of a group rule (7 below plus the next button's own 4), against 4 px between buttons. + const auto strip_rule = [&]() { + auto *r = rule(wxSize(FromDIP(20), 1)); + strip->Add(r, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(11)); + strip->AddSpacer(FromDIP(7)); + }; + m_select[0] = tool(ID_UV_SELECT_ISLAND, "texture_displacement_uv_select_island", _L("Island - move, rotate and scale whole islands"), true); + m_select[1] = tool(ID_UV_SELECT_VERTEX, "texture_displacement_uv_select_vertex", _L("Vertex - drag vertices to reshape; Shift/Ctrl to multi-select"), true); + m_select[2] = tool(ID_UV_SELECT_EDGE, "texture_displacement_uv_select_edge", _L("Edge - drag edges to reshape; Shift/Ctrl to multi-select"), true); + strip_rule(); + m_mark_seams = tool(ID_UV_MARK_SEAMS, "texture_displacement_uv_seam", + _L("Mark seams - click edges on the model to cut the unwrap along them. The edge under the cursor is " + "highlighted yellow; click to mark it red, click a red edge again to unmark it. Painting is paused " + "while this is on."), + true); + m_seam_path = tool(ID_UV_SEAM_PATH, "texture_displacement_uv_path", + _L("Path - instead of clicking every edge, click a start point and then an end point: the whole " + "shortest path between them is seamed at once. Available while marking seams."), + true); + m_clear_seams = tool(ID_UV_CLEAR_SEAMS, "texture_displacement_cross", _L("Clear seams - remove every seam marked on this layer"), false); + strip_rule(); + m_avg_scale = tool(ID_UV_AVG_SCALE, "texture_displacement_uv_avg_scale", _L("Average scale - give every island the same texel density"), false); + m_cut = tool(ID_UV_CUT, "texture_displacement_uv_cut", _L("Cut - split the selected island across its long axis"), false); + m_join = tool(ID_UV_JOIN, "texture_displacement_uv_join", _L("Join - unfold the selected island onto its nearest neighbour along their shared edge"), false); + m_unjoin = tool(ID_UV_UNJOIN, "texture_displacement_uv_unjoin", _L("Unjoin - send the selected island back to its own packed position"), false); + strip->AddStretchSpacer(); + m_clear_edits = tool(ID_UV_CLEAR_EDITS, "texture_displacement_uv_clear_edits", + _L("Clear UV edits - discard all manual vertex/edge moves and return the unwrap to its automatic shape"), false); + m_snap = tool(ID_UV_SNAP, "texture_displacement_uv_snap", _L("Snap - stick islands together when dragging one against another"), true); + m_frame = tool(ID_UV_FRAME, "texture_displacement_uv_frame", _L("Frame all islands (Home)"), false); + strip->AddSpacer(FromDIP(4)); + + m_canvas = new UVEditorCanvas(this); + auto *body = new wxBoxSizer(wxHORIZONTAL); + body->Add(strip, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(4)); + body->Add(rule(wxSize(1, -1)), 0, wxEXPAND); + body->Add(m_canvas, 1, wxEXPAND); + + // ---- status line: the current gesture on the left, the unwrap summary on the right ---- + m_status = text(wxEmptyString, c.dim, wxST_ELLIPSIZE_END); + m_status->SetMinSize(wxSize(FromDIP(40), -1)); + m_stats = text(wxEmptyString, c.dim); + auto *status = new wxBoxSizer(wxHORIZONTAL); + status->Add(m_status, 1, wxALIGN_CENTER_VERTICAL); + status->Add(m_stats, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, gap); + + auto *sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(header, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, pad); + sizer->Add(settings, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, gap); + sizer->Add(rule(wxSize(-1, 1)), 0, wxEXPAND | wxTOP, gap); + sizer->Add(body, 1, wxEXPAND); + sizer->Add(rule(wxSize(-1, 1)), 0, wxEXPAND); + sizer->Add(status, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, FromDIP(5)); + SetSizer(sizer); + + Bind(wxEVT_BUTTON, &UVEditorPanel::on_tool, this); + // Both settings compare against the last state the gizmo pushed before sending anything: apply_state() + // writes them back, and without the check that write would bounce straight back to the gizmo as an edit. + m_seam_angle->Bind(wxEVT_SPINCTRL, [this](wxCommandEvent &) { + const int value = m_seam_angle->GetValue(); + if (value != int(std::lround(m_canvas->pane_state().seam_angle_deg))) + m_canvas->run_command(UVEditorCanvas::Command::SetSeamAngle, float(value)); + }); + const auto send_connect = [this]() { + if (m_connect->GetValue() != m_canvas->pane_state().connect_islands) + m_canvas->run_command(UVEditorCanvas::Command::SetConnectIslands, m_connect->GetValue() ? 1.f : 0.f); + }; + m_connect->Bind(wxEVT_TOGGLEBUTTON, [send_connect](wxCommandEvent &e) { + send_connect(); + e.Skip(); + }); + connect_label->Bind(wxEVT_LEFT_DOWN, [this, send_connect](wxMouseEvent &) { + if (!m_connect->IsEnabled()) + return; + m_connect->SetValue(!m_connect->GetValue()); + send_connect(); + }); + + m_canvas->set_status_callback([this](const wxString &label) { + if (m_status != nullptr && m_status->GetLabel() != label) { + m_status->SetLabel(label); + m_status->Refresh(); + refresh_selection_tools(); // a selection or mode change is what changes the status line + } + }); + m_canvas->set_pane_state_callback([this](const UVEditorCanvas::PaneState &state) { apply_state(state); }); + apply_state(m_canvas->pane_state()); + + // AUI shows and hides the pane through this panel. Rebuild the canvas's GPU objects when it comes back, so + // the texture and islands never depend on surviving the canvas's native window being hidden. + Bind(wxEVT_SHOW, [this](wxShowEvent &e) { + e.Skip(); + if (e.IsShown()) + m_canvas->invalidate_gl(); + }); +} + +void UVEditorPanel::apply_state(const UVEditorCanvas::PaneState &s) +{ + const wxString name = s.has_layer ? s.layer_name : _L("No layer mapped with Unwrap"); + const wxString tile = s.has_layer ? wxString::Format(_L("%.1f mm tile"), s.tile_mm) : wxString(); + const bool relayout = m_layer_name->GetLabel() != name || m_tile->GetLabel() != tile; + m_layer_name->SetLabel(name); + m_tile->SetLabel(tile); + + if (s.thumbnail_px > 0 && s.thumbnail_rgb.size() == size_t(s.thumbnail_px) * size_t(s.thumbnail_px) * 3) { + // Scaled to device pixels and tagged with the content scale, so HiDPI screens get every pixel of it. + const double scale = GetContentScaleFactor(); + const int px = std::max(1, int(std::lround(FromDIP(20) * scale))); + wxImage image(s.thumbnail_px, s.thumbnail_px, false); + std::copy(s.thumbnail_rgb.begin(), s.thumbnail_rgb.end(), image.GetData()); + m_thumb->SetBitmap(wxBitmap(image.Scale(px, px, wxIMAGE_QUALITY_HIGH), -1, scale)); + } else { + m_thumb->SetBitmap(wxNullBitmap); + } + m_thumb->Enable(s.has_layer); + + for (int i = 0; i < 3; ++i) { + m_background[i]->SetValue(int(s.background) == i); + m_background[i]->Enable(s.has_layer); + } + m_unwrap->Enable(s.has_layer); + m_unwrap->SetBadge(s.unwrap_stale); + m_unwrap->SetToolTip(s.unwrap_stale ? + _L("Out of date - the paint, the seams or the seam angle changed since this unwrap was made. " + "Press to unwrap again.") : + _L("Flatten the painted area into UV islands. It is computed only when you press this, not on " + "every edit - so paint, change the seam angle or mark seams first, then press Unwrap.")); + + if (m_seam_angle->GetValue() != int(std::lround(s.seam_angle_deg))) + m_seam_angle->SetValue(int(std::lround(s.seam_angle_deg))); + m_seam_angle->Enable(s.has_layer); + m_connect->SetValue(s.connect_islands); + m_connect->Enable(s.has_layer); + + m_mark_seams->SetValue(s.mark_seams); + m_mark_seams->Enable(s.has_layer); + m_seam_path->SetValue(s.seam_path); + m_seam_path->Enable(s.has_layer && s.mark_seams); + m_clear_seams->Enable(s.has_layer && s.has_seams); + m_clear_edits->Enable(s.has_layer && s.has_uv_edits); + + m_stats->SetLabel(s.unwrapped ? wxString::Format(_L("%d islands, %s faces"), s.island_count, + wxString(std::to_string(s.face_count))) : + wxString()); + refresh_selection_tools(); + if (relayout) + Layout(); +} + +void UVEditorPanel::refresh_selection_tools() +{ + const bool has_islands = m_canvas->has_islands(); + const int mode = int(m_canvas->select_mode()); + for (int i = 0; i < 3; ++i) { + m_select[i]->SetValue(i == mode); + m_select[i]->Enable(has_islands); + } + const bool island_picked = has_islands && m_canvas->select_mode() == UVEditorCanvas::SelectMode::Island && + m_canvas->selected_island() >= 0; + m_avg_scale->Enable(has_islands); + m_cut->Enable(island_picked); + m_join->Enable(island_picked); + m_unjoin->Enable(island_picked); + m_snap->Enable(has_islands); + m_snap->SetValue(m_canvas->snap_enabled()); + m_frame->Enable(has_islands); +} + +void UVEditorPanel::on_tool(wxCommandEvent &evt) +{ + using Command = UVEditorCanvas::Command; + const int id = evt.GetId(); + const bool on = evt.GetInt() != 0; + switch (id) { + case ID_UV_FRAME: m_canvas->run_command(Command::FrameAll); break; + case ID_UV_SNAP: m_canvas->run_command(Command::ToggleSnap); break; + case ID_UV_AVG_SCALE: m_canvas->run_command(Command::AverageScale); break; + case ID_UV_CUT: m_canvas->run_command(Command::CutSelectedIsland); break; + case ID_UV_JOIN: m_canvas->run_command(Command::JoinSelected); break; + case ID_UV_UNJOIN: m_canvas->run_command(Command::UnjoinSelected); break; + case ID_UV_UNWRAP: m_canvas->run_command(Command::Unwrap); break; + case ID_UV_MARK_SEAMS: m_canvas->run_command(Command::SetMarkSeams, on ? 1.f : 0.f); break; + case ID_UV_SEAM_PATH: m_canvas->run_command(Command::SetSeamPath, on ? 1.f : 0.f); break; + case ID_UV_CLEAR_SEAMS: m_canvas->run_command(Command::ClearSeams); break; + case ID_UV_CLEAR_EDITS: m_canvas->run_command(Command::ClearUVEdits); break; + case ID_UV_PICK_TEXTURE: m_canvas->run_command(Command::PickTexture); break; + case ID_UV_SELECT_ISLAND: + case ID_UV_SELECT_VERTEX: + case ID_UV_SELECT_EDGE: m_canvas->run_command(Command::SetSelectMode, float(id - ID_UV_SELECT_ISLAND)); break; + case ID_UV_BG_HEIGHT: + case ID_UV_BG_CHECKER: + case ID_UV_BG_DISTORTION: + // Shown straight away; the gizmo confirms it with its next state push. + for (int i = 0; i < 3; ++i) + m_background[i]->SetValue(i == id - ID_UV_BG_HEIGHT); + m_canvas->run_command(Command::SetBackground, float(id - ID_UV_BG_HEIGHT)); + break; + default: evt.Skip(); return; + } + refresh_selection_tools(); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/UVEditorCanvas.hpp b/src/slic3r/GUI/UVEditorCanvas.hpp new file mode 100644 index 0000000000..0dd088c4e8 --- /dev/null +++ b/src/slic3r/GUI/UVEditorCanvas.hpp @@ -0,0 +1,441 @@ +#ifndef slic3r_UVEditorCanvas_hpp_ +#define slic3r_UVEditorCanvas_hpp_ + +#include +#include +#include +#include + +// Must come before wx/glcanvas.h in any translation unit that includes this header: glcanvas.h +// pulls in the platform's real GL/gl.h, and glad/gl.h errors out if that happens first (it wants +// to be the one to define the standard include guards GL/gl.h itself defines). +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libslic3r/Point.hpp" +#include "GLModel.hpp" +#include "GLTexture.hpp" + +// Orca's own widgets (slic3r/GUI/Widgets), declared at global scope. +class SpinInput; +class CheckBox; + +namespace Slic3r::GUI { + +// Standalone 2D viewer/editor for a flattened (UV-unwrapped) mesh patch - shows the result of +// GLGizmoTextureDisplacement's LSCM projection method as its own resizable pane (see Plater's +// "uv_editor" AUI pane) rather than folding 2D UV-space rendering into the main 3D viewport. +// +// Islands can be laid out by hand, roughly the way Blender's UV editor works: click one to select +// it, drag to move it, right-drag or press R to rotate it, S to scale it, both about its own centre. +// Islands are free to overlap - nothing re-packs them behind the user's back. The texture underneath +// is always drawn upright and axis-aligned, and it is the islands that move over it, which is what +// makes "rotate this island" a meaningful gesture rather than just spinning the whole texture. +// +// **Geometry is uploaded in the unwrap's own (raw, mm) coordinates, once**, and each island is drawn +// through its own affine matrix passed as a shader uniform. That matters: a patch can easily run to +// a million triangles, and the earlier design - which pre-transformed every UV on the CPU and +// re-uploaded the whole wireframe on every mouse-move event - made a drag cost a couple of hundred +// milliseconds per frame. Moving an island now touches a 2x3 matrix and nothing else. +// +// Uses the app's single shared wxGLContext (via wxGetApp().init_glcontext(), the same call +// View3D/Preview/AssembleView each make in GUI_Preview.cpp) rather than an independent context of +// its own, specifically so it can reuse the app's already-registered "flat"/"flat_texture" +// shaders and GLModel as-is - GLModel::render() looks up its shader via a GUI_App-wide "current +// shader", which only means anything for canvases sharing the app's one real GL context. +class UVEditorCanvas : public wxGLCanvas +{ +public: + explicit UVEditorCanvas(wxWindow *parent); + + // Maps one island's raw unwrap coordinate to a texture UV: the island's own hand placement and + // then the layer's tiling/rotation/offset, composed into a single affine (columns: x basis, + // y basis, translation). + using IslandTransform = Eigen::Matrix; + + // The unwrap to display, in the unwrap's own mm coordinates - *not* texture UVs. Changing this + // is the expensive path (it rebuilds every vertex buffer), so it must only be called when the + // unwrap itself changes, never merely because an island moved. Pass an empty `indices` to show + // nothing. + struct Islands + { + std::vector uvs; + std::vector indices; + std::vector vertex_island; // per uv + std::vector> boundary_edges; // island outlines, indices into uvs + int island_count = 0; + }; + void set_islands(Islands islands); + + // The cheap path: one transform per island. Safe to call on every mouse-move of a drag. + void set_island_transforms(std::vector transforms); + + // One fill colour per island, overriding the default light-green wash - used to paint the UV + // distortion heatmap over the islands when the gizmo's "Distortion" check mode is on (#7/#14). + // Pass empty to go back to the default wash. Cheap: it never touches a vertex buffer. + void set_island_fill_colors(std::vector colors); + + // The layer's own tiling scale and rotation. Needed to map a gesture, which happens in texture-UV + // space, back into the unwrap's mm space - which is where a TextureIsland's offset actually + // lives (see apply_uv_transform()). The tile settings come along because the background has to + // repeat exactly the way the height sampler does, or the pane would stop showing what gets baked. + void set_uv_transform(float tiling_scale, float rotation_deg, bool tile_enabled, bool tile_mirrored); + + // Same 8-bit grayscale pixels build_texture_displacement()'s height sampling uses, shown + // beneath the wireframe (expanded to RGBA on upload) so the unwrap can be checked against the + // texture it will actually sample. Pass width/height <= 0 to clear it. + void set_background_texture(const std::vector &grayscale_pixels, int width, int height); + + // Snap a dragged island's boundary to a neighbouring island's when they come close (#2). Off is + // the honest default for overlap-friendly layouts; the pane toolbar toggles it. + void set_snap_enabled(bool enabled) { m_snap_enabled = enabled; } + bool snap_enabled() const { return m_snap_enabled; } + + // High-level actions the pane's controls trigger. The canvas handles the view-only ones (framing, + // the snap toggle) itself and forwards the rest to whoever owns the island data (the gizmo), via + // the command callback - the canvas has the selection and the view, the gizmo has the layer. + // `value` carries the new setting for the Set* commands (an angle, a flag as 0/1, or an index into + // SelectMode / Background) and is 0 otherwise. + enum class Command { + FrameAll, ToggleSnap, AverageScale, CutSelectedIsland, ProjectFromView, JoinSelected, UnjoinSelected, + Unwrap, SetSeamAngle, SetConnectIslands, SetSelectMode, SetMarkSeams, SetSeamPath, ClearSeams, ClearUVEdits, + SetBackground, PickTexture, PaneClosed + }; + void run_command(Command cmd, float value = 0.f); + using CommandFn = std::function; + void set_command_callback(CommandFn fn) { m_on_command = std::move(fn); } + + // What the canvas shows under the islands; mirrors the gizmo's Normal/Checker/Distortion views. + enum class Background { Height, Checker, Distortion }; + + // Everything the pane's own controls show that the gizmo owns: the active layer and its unwrap settings. + // The gizmo pushes it whenever any of it may have changed, and the pane redraws its header, settings row + // and tool strip from it - so the controls never hold state of their own that could drift from the layer. + struct PaneState + { + bool has_layer = false; // an active layer mapped with Unwrap + wxString layer_name; + float tile_mm = 0.f; + std::vector thumbnail_rgb; // thumbnail_px square, 3 bytes per pixel; empty for none + int thumbnail_px = 0; + float seam_angle_deg = 40.f; + bool connect_islands = true; + bool unwrapped = false; // an unwrap exists for this layer + bool unwrap_stale = false; // paint, seams or the seam angle changed since it was made + bool mark_seams = false; + bool seam_path = false; + bool has_seams = false; + bool has_uv_edits = false; + Background background = Background::Height; + int island_count = 0; + size_t face_count = 0; + }; + void set_pane_state(PaneState state); + const PaneState &pane_state() const { return m_pane_state; } + using PaneStateFn = std::function; + void set_pane_state_callback(PaneStateFn fn) { m_on_pane_state = std::move(fn); } + + // Called whenever the one-line status/hint text changes (current gesture + the shortcuts that + // apply right now), so the pane can show it Blender-style along the bottom. + using StatusFn = std::function; + void set_status_callback(StatusFn fn) { m_on_status = std::move(fn); } + + // Reports an island edit as it happens. The deltas are *incremental* (one mouse event's worth) + // and already converted into the units a TextureIsland stores - unwrap mm, degrees, and a scale + // *factor* to multiply the island's existing scale by. They are incremental on purpose: the owner + // applies them and hands back fresh transforms, and if the gesture tracked geometry rather than + // raw mouse motion that round trip would feed back into itself. `finished` marks the end of a + // gesture, so the owner can rebuild the 3D preview once rather than on every motion event. + using IslandEditFn = + std::function; + void set_island_edit_callback(IslandEditFn fn) { m_on_island_edit = std::move(fn); } + + // What a click grabs: a whole island (move/rotate/scale, groups move together), a single vertex, or + // a single edge (both its endpoints). Vertex/Edge are free-form UV editing - they move the actual + // unwrap coordinates, which the owner then folds into the layer's per-vertex UV overrides so the + // change is baked, not just shown (see set_vertex_edit_callback). + enum class SelectMode { Island, Vertex, Edge }; + void set_select_mode(SelectMode mode); + SelectMode select_mode() const { return m_select_mode; } + + // Reports a committed vertex/edge edit: the list of (unwrapped-vertex index, its new raw-unwrap + // coordinate in mm). Fired once, on mouse release, since it re-solves the displacement preview; the + // pane shows the edit live from its own geometry in the meantime. The owner maps the unwrapped index + // to a mesh vertex (via the unwrap's source_vertex) and stores the override. + using UVVertexEditFn = std::function> &edits)>; + void set_vertex_edit_callback(UVVertexEditFn fn) { m_on_vertex_edit = std::move(fn); } + + // The primary (last-clicked) island, still the pivot for rotate/scale and the target of the + // single-island toolbar commands (Cut/Join/Unjoin). -1 if nothing is selected. + int selected_island() const { return m_selected_island; } + // Whether there is an unwrap on screen at all. + bool has_islands() const { return m_islands.island_count > 0 && !m_islands.indices.empty(); } + // The full multi-selection (Shift adds, Ctrl toggles). Always contains m_selected_island when it is + // >= 0. The gizmo reads this to decide which islands a drag moves together, unioned with each + // selected island's join group. + const std::vector &selected_islands() const { return m_selection; } + void reset_view(); + // Rebuilds every GPU object at the next paint, from the data the canvas keeps on the CPU. Called when the + // pane is shown again, so a hidden-and-reshown canvas never depends on GL objects surviving its native + // window being torn down. + void invalidate_gl() + { + m_gl_reset_pending = true; + Refresh(); + } + +private: + void on_paint(wxPaintEvent &evt); + void on_size(wxSizeEvent &evt); + void on_mouse(wxMouseEvent &evt); + void on_key(wxKeyEvent &evt); + void on_leave(wxMouseEvent &evt); // drops the +/- cursor hint when the pointer leaves the canvas + void on_erase_background(wxEraseEvent &evt) {} // required to avoid flicker on MSW, deliberately a no-op + + void render(); + void rebuild_island_models(); + void rebuild_background_texture(); + void rebuild_background_quad(); + void rebuild_grid(); + // The UV region worth looking at: every island, plus always at least the texture's first tile, so + // there is something sensibly framed even before anything is painted. + void content_bounds(Vec2f &min_uv, Vec2f &max_uv) const; + // What is actually *drawn*, which is content_bounds() snapped out to whole tiles whenever the + // backdrop tiles (see rebuild_background_quad()). Both the framing and the backdrop go through + // this so they cannot disagree. + void framed_bounds(Vec2f &min_uv, Vec2f &max_uv) const; + // Frames framed_bounds(). Bound to Home, and run once each time an unwrap first appears. + void fit_view_to_content(); + + // Half-extents of the visible UV region. Split out because both rendering and every mouse + // gesture need them, and they have to agree exactly or picking lands in the wrong place. + void view_half_extents(float &half_w, float &half_h) const; + Vec2f screen_to_uv(const wxPoint &px) const; + // Raw unwrap coordinate -> texture UV, through the island's own transform. + Vec2f island_uv(size_t vertex) const; + // The island under `uv`, or -1. Prefers the current selection when islands overlap, so that + // dragging one that sits under another doesn't hand the drag to its neighbour halfway through. + int island_at(const Vec2f &uv) const; + // Nearest unwrapped vertex to `uv` within a screen-space threshold, or -1 (Vertex mode picking). + int vertex_at(const Vec2f &uv) const; + // Nearest island-boundary edge to `uv` within a screen-space threshold, as its two unwrapped-vertex + // indices, or {-1,-1} (Edge mode picking). + std::pair edge_at(const Vec2f &uv) const; + // Moves one unwrapped vertex by a texture-UV delta, converting it back into the vertex's own raw + // unwrap space through its island's inverse transform, and marks the mesh dirty so it redraws. + void move_vertex_raw(int unwrapped_vertex, const Vec2f &delta_uv); + Vec2f island_centroid(int island) const; + // Converts a delta in texture-UV space into the unwrap's mm space, undoing the layer's scale and + // rotation - the inverse of what apply_uv_transform() did on the way in. + Vec2f uv_delta_to_unwrap(const Vec2f &delta_uv) const; + // The correction that would bring the selected island's nearest boundary vertex onto a boundary + // vertex of some *other* island, in texture-UV space. Zero if nothing is within reach (#2). + Vec2f snap_correction(int island) const; + void end_gesture(); + // Rebuilds the status line from the current gesture/selection and pushes it to m_on_status. + void update_status(); + // Re-picks what a click at `pos` would grab in the current select mode, and repaints when that changed. + void update_hover(const wxPoint &pos); + + wxGLContext *m_context = nullptr; // owned by OpenGLManager/GUI_App, not by this canvas + + Islands m_islands; + std::vector m_transforms; + // Per-island fill colour override (distortion heatmap); empty means use the default wash (#7). + std::vector m_island_fill_colors; + // Boundary vertices per island, for snapping - a patch's boundary is a tiny fraction of it, and + // rescanning the whole uv array on every snap test would not be. + std::vector> m_island_boundary_verts; + // Per island: its outline edges, its triangles (indices into m_islands.indices) and the bounding box of its + // raw coordinates - so picking tests one island's triangles only when the cursor is inside its box. + std::vector>> m_island_boundary_edges; + std::vector> m_island_tris; + std::vector> m_island_raw_bounds; + + bool m_mesh_dirty = true; + bool m_gl_reset_pending = false; + // One set of models per island, so an island can be drawn through its own transform. Built once + // per unwrap, never on a drag. Outlines are not among them: they are drawn as screen-width quads, + // rebuilt every paint (see render()), because GL wide lines are not reliably wider than 1 px. + std::vector m_island_wireframe; // interior edges + std::vector m_island_fill; // filled; also the stencil mask that keeps islands undimmed + GLModel m_stroke_glmodel; // scratch model for the quads of one stroke pass + GLModel m_dim_quad_glmodel; // full-viewport quad that dims the texture outside the islands + int m_stencil_bits = -1; // of the default framebuffer; -1 = not queried yet + + GLModel m_tile_outline_glmodel; // the texture's first tile, [0,1]^2 - the "you are here" + GLModel m_grid_glmodel; + float m_grid_step = 0.f; // the UV step m_grid_glmodel was built for; 0 = not built + + float m_tiling_scale = 1.f; + float m_rotation_deg = 0.f; + bool m_tile_enabled = true; + bool m_tile_mirrored = false; + bool m_snap_enabled = false; + + std::vector m_background_pixels; // RGBA, expanded from the grayscale input + int m_background_width = 0, m_background_height = 0; + bool m_background_dirty = false; // the pixels need (re)uploading + bool m_background_quad_dirty = true; // only the quad's extent changed + GLTexture m_background_texture; + // Covers content_bounds(), not just [0,1]: the unwrap is packed in mm and then divided by the + // layer's tile size, so it routinely spans many tiles, and a single-unit-square backdrop would + // leave most of the islands sitting over bare background. Texcoord == position, so the GL wrap + // mode repeats it exactly the way DecodedHeightTexture::sample() does. + GLModel m_background_glmodel; + + // 2D pan/zoom. m_pan is the UV-space point at the center of the view, m_zoom half the UV-space + // extent visible across the shorter screen edge. v runs *down* the screen, matching both the + // texture's own row order and every other UV editor's convention. + Vec2f m_pan = Vec2f(0.5f, 0.5f); + float m_zoom = 0.75f; + bool m_needs_fit = true; // fit the view to the next unwrap that arrives + + enum class Gesture + { + None, + Pan, + MoveIsland, + RotateIsland, // right-drag: rotation tracks the mouse, ends when the button is released + RotateIslandModal, // 'R': rotation tracks the mouse until a click confirms or Esc cancels + ScaleIslandModal, // 'S': likewise, distance from the centre drives the scale + MoveVertex, // Vertex mode: drag one unwrapped vertex + MoveEdge, // Edge mode: drag both endpoints of one boundary edge + }; + Gesture m_gesture = Gesture::None; + + SelectMode m_select_mode = SelectMode::Island; + // The sub-element being edited in Vertex/Edge mode (unwrapped-vertex indices), or -1/{-1,-1}. This + // is the *primary* (last-picked) element of the multi-selection below. + int m_active_vertex = -1; + std::pair m_active_edge{ -1, -1 }; + // Multi-selection for Vertex/Edge modes, mirroring the island selection: plain click replaces, Shift + // adds, Ctrl toggles, and a drag moves the whole set together. m_active_vertex/m_active_edge stay the + // primary. Kept as small vectors (tiny, and order doesn't matter here). + std::vector m_sel_vertices; + std::vector> m_sel_edges; + bool is_vertex_selected(int v) const + { + return std::find(m_sel_vertices.begin(), m_sel_vertices.end(), v) != m_sel_vertices.end(); + } + bool is_edge_selected(const std::pair &e) const + { + return std::find(m_sel_edges.begin(), m_sel_edges.end(), e) != m_sel_edges.end(); + } + // Unique unwrapped-vertex endpoints of every selected edge (an endpoint shared by two selected edges + // is returned once, so a drag doesn't move it twice). + std::vector selected_edge_endpoints() const; + // Last known mouse position over the canvas, and whether the pointer is currently inside it. Used to + // draw the +/- add/remove sign next to the cursor in Vertex/Edge mode. + wxPoint m_cursor_px{ 0, 0 }; + bool m_cursor_inside = false; + // Set once a Vertex/Edge drag actually moves, so a bare click (select without drag) doesn't commit a + // no-op edit and take an undo snapshot for nothing. + bool m_vertex_edit_moved = false; + // Lazily-built small filled square, drawn at an edited/hovered vertex as a handle. + GLModel m_vertex_marker_glmodel; + // What a click would grab right now, highlighted so the user sees the target before clicking. + int m_hover_island = -1; + int m_hover_vertex = -1; + std::pair m_hover_edge{ -1, -1 }; + int m_selected_island = -1; + // The full multi-selection; m_selected_island is its primary (last-clicked) member. Kept as a small + // vector rather than a set because it is tiny and iteration order (primary last) is convenient. + std::vector m_selection; + bool is_selected(int island) const + { + return std::find(m_selection.begin(), m_selection.end(), island) != m_selection.end(); + } + wxPoint m_drag_last_px; + Vec2f m_gesture_last_uv = Vec2f::Zero(); + float m_gesture_last_angle = 0.f; + float m_gesture_last_dist = 0.f; + // Rotation is tracked as two running totals over the gesture: the raw mouse rotation, and how much + // has actually been applied. With Shift held the applied total is quantised to 15-degree steps + // (Blender-style angle snapping), so the two diverge - and driving the applied total off the raw + // one, rather than snapping each incremental delta, is what makes the snap stable instead of + // juddering. The raw/applied split also survives crossing +/-180 degrees, which a single wrapped + // angle would not. m_rot_applied doubles as the modal-rotate undo amount for Esc. + float m_rot_raw_deg = 0.f; + float m_rot_applied_deg = 0.f; + // The island's absolute on-screen rotation when the gesture began (decoded from its transform), so + // Shift can snap to *global* 15-degree marks (0/15/30...) rather than 15 degrees relative to + // wherever the island happened to start (#10). Also drives the angle read-out and the dial. + float m_rot_base_deg = 0.f; + float m_rot_display_deg = 0.f; // current absolute angle, for the status line and dial needle + float m_modal_scale_accum = 1.f; // so Esc can undo exactly what the modal scale applied, as a factor + + // A protractor drawn around the island while it rotates: a ring, a tick every 15 degrees, and a + // needle at the current angle, so the rotation is legible (#11). Rebuilt each frame during a + // rotation gesture (cheap: a few hundred short lines) and left empty otherwise. + GLModel m_dial_glmodel; + void rebuild_rotation_dial(); + // The island's current absolute rotation in degrees, decoded from its transform's first column. + float island_rotation_deg(int island) const; + + IslandEditFn m_on_island_edit; + UVVertexEditFn m_on_vertex_edit; + CommandFn m_on_command; + StatusFn m_on_status; + PaneState m_pane_state; + PaneStateFn m_on_pane_state; +}; + +class UVToolButton; // a drawn icon button, defined in UVEditorCanvas.cpp + +// The UV editor pane that goes into Plater's "uv_editor" AUI pane: a header with the active layer, the +// canvas background and Unwrap; a settings row with the unwrap's seam angle and island connection; a +// narrow tool strip down the left (selection mode, seams, island actions, snap and framing); the canvas; +// and a status line naming the current gesture, with the unwrap summary on its right. +// +// It holds no editing state of its own. Every control sends a Command through the canvas to the gizmo, +// and the gizmo pushes PaneState back, from which the controls are redrawn (see apply_state()). The gizmo +// still talks to the inner canvas, reached via canvas(). +class UVEditorPanel : public wxPanel +{ +public: + explicit UVEditorPanel(wxWindow *parent); + UVEditorCanvas *canvas() { return m_canvas; } + +private: + void on_tool(wxCommandEvent &evt); + void apply_state(const UVEditorCanvas::PaneState &state); + // Selection-mode toggles, and the tools that need a selected island, follow the canvas. + void refresh_selection_tools(); + + UVEditorCanvas *m_canvas = nullptr; + + UVToolButton *m_thumb = nullptr; // the layer's texture; a click opens the texture library + wxStaticText *m_layer_name = nullptr; + wxStaticText *m_tile = nullptr; + UVToolButton *m_background[3]{}; + UVToolButton *m_unwrap = nullptr; + + ::SpinInput *m_seam_angle = nullptr; + ::CheckBox *m_connect = nullptr; + + UVToolButton *m_select[3]{}; + UVToolButton *m_mark_seams = nullptr; + UVToolButton *m_seam_path = nullptr; + UVToolButton *m_clear_seams = nullptr; + UVToolButton *m_avg_scale = nullptr; + UVToolButton *m_cut = nullptr; + UVToolButton *m_join = nullptr; + UVToolButton *m_unjoin = nullptr; + UVToolButton *m_clear_edits = nullptr; + UVToolButton *m_snap = nullptr; + UVToolButton *m_frame = nullptr; + + wxStaticText *m_status = nullptr; + wxStaticText *m_stats = nullptr; +}; + +} // namespace Slic3r::GUI + +#endif // slic3r_UVEditorCanvas_hpp_ diff --git a/src/slic3r/GUI/UserManager.cpp b/src/slic3r/GUI/UserManager.cpp index e874c2158d..f181f3e568 100644 --- a/src/slic3r/GUI/UserManager.cpp +++ b/src/slic3r/GUI/UserManager.cpp @@ -31,14 +31,15 @@ int UserManager::parse_json(std::string payload) { bool restored_json = false; json j; - json j_pre = json::parse(payload); - if (j_pre.empty()) { - return -1; - } //bind/unbind try { + json j_pre = json::parse(payload); + if (j_pre.empty()) { + return -1; + } + if (j_pre.contains("bind")) { if (j_pre["bind"].contains("command")) { diff --git a/src/slic3r/GUI/WebDownPluginDlg.cpp b/src/slic3r/GUI/WebDownPluginDlg.cpp index dca17110f9..6358582831 100644 --- a/src/slic3r/GUI/WebDownPluginDlg.cpp +++ b/src/slic3r/GUI/WebDownPluginDlg.cpp @@ -38,9 +38,7 @@ DownPluginFrame::DownPluginFrame(GUI_App *pGUI) : wxDialog((wxWindow *) (pGUI->m // set the frame icon wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); - wxString TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/6/index.html").make_preferred().string()); - - TargetUrl = "file://" + TargetUrl; + wxString TargetUrl = file_url_from_path(boost::filesystem::path(resources_dir()) / "web/guide/6/index.html"); // Create the webview m_browser = WebView::CreateWebView(this, TargetUrl); diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index 9cea8bec28..5370509587 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -218,37 +218,38 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load) m_page = startpage; BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" enter, load=%1%, start_page=%2%")%load%int(startpage); //wxLogMessage("GUIDE: webpage_1 %s", (boost::filesystem::path(resources_dir()) / "web\\guide\\1\\index.html").make_preferred().string().c_str() ); - wxString TargetUrl = from_u8( (boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=1").make_preferred().string() ); + const wxString guide_url = file_url_from_path(boost::filesystem::path(resources_dir()) / "web/guide/0/index.html"); + wxString TargetUrl = guide_url + "?target=1"; //wxLogMessage("GUIDE: webpage_2 %s", TargetUrl.mb_str()); if (startpage == BBL_WELCOME){ SetTitle(_L("Setup Wizard")); - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=1").make_preferred().string()); + TargetUrl = guide_url + "?target=1"; } else if (startpage == BBL_REGION) { SetTitle(_L("Setup Wizard")); - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=11").make_preferred().string()); + TargetUrl = guide_url + "?target=11"; } else if (startpage == BBL_MODELS) { SetTitle(_L("Setup Wizard")); - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=21").make_preferred().string()); + TargetUrl = guide_url + "?target=21"; } else if (startpage == BBL_FILAMENTS) { SetTitle(_L("Setup Wizard")); int nSize = m_ProfileJson["model"].size(); if (nSize>0) - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=22").make_preferred().string()); + TargetUrl = guide_url + "?target=22"; else - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=21").make_preferred().string()); + TargetUrl = guide_url + "?target=21"; } else if (startpage == BBL_FILAMENT_ONLY) { SetTitle(""); - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=23").make_preferred().string()); + TargetUrl = guide_url + "?target=23"; } else if (startpage == BBL_MODELS_ONLY) { SetTitle(""); - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=24").make_preferred().string()); + TargetUrl = guide_url + "?target=24"; } else { SetTitle(_L("Setup Wizard")); - TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/0/index.html?target=21").make_preferred().string()); + TargetUrl = guide_url + "?target=21"; } wxString strlang = wxGetApp().current_language_code_safe(); @@ -256,7 +257,6 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load) if (strlang != "") TargetUrl = wxString::Format("%s&lang=%s", w2s(TargetUrl), strlang); - TargetUrl = "file://" + TargetUrl; if (load) load_url(TargetUrl); @@ -1284,7 +1284,7 @@ bool GuideFrame::BuildProfileJson(const PresetBundle& bundle, bool require_all_r entry["vendor"] = vp.id; entry["nozzle_diameter"] = nozzle_str; entry["materials"] = materials_str; - entry["cover"] = cover_path.string(); + entry["cover"] = into_u8(file_url_from_path(cover_path)); entry["nozzle_selected"] = ""; entry["sub_path"] = ""; m_ProfileJson["model"].push_back(entry); @@ -1405,23 +1405,26 @@ bool GuideFrame::BuildProfileDataFromVendors() // is served from the shipped profiles. Each is stamped by name and // version alone: a profile change requires a version bump, so those two // determine content wherever the vendor's copy sits. - struct VendorSource { std::string name; boost::filesystem::path dir; std::string version; }; - std::vector ordered; - auto add_vendor = [&ordered](const std::string& name, const boost::filesystem::path& dir) { + std::vector ordered; + json stamps = json::array(); + auto add_vendor = [&ordered, &stamps](const std::string& name, const boost::filesystem::path& dir) { // The version a load from `dir` would serve: the profile's where one // exists (a cache is only served while it covers the profile beside // it), the cache's own stamp where the cache is the whole vendor. // A profile without a version (blacklist.json) carries no presets // and is passed over. const boost::filesystem::path profile = dir / (name + ".json"); + std::string version; if (boost::filesystem::exists(profile)) { const Semver v = get_version_from_json(profile.string()); - if (v.valid()) - ordered.push_back({name, dir, v.to_string()}); + if (! v.valid()) + return; + version = v.to_string(); } else { - ordered.push_back({name, dir, - VendorCacheFile::peek_version((dir / (name + ".opc")).string(), name)}); + version = VendorCacheFile::peek_version((dir / (name + ".opc")).string(), name); } + ordered.push_back({name, dir}); + stamps.push_back({name, version}); }; const std::string filament_library(PresetBundle::ORCA_FILAMENT_LIBRARY); if (auto it = vendor_sources.find(filament_library); it != vendor_sources.end()) @@ -1431,9 +1434,6 @@ bool GuideFrame::BuildProfileDataFromVendors() add_vendor(name, dir); if (ordered.empty()) return false; - json stamps = json::array(); - for (const VendorSource& v : ordered) - stamps.push_back({v.name, v.version}); // What this function derives is a pure function of that stamped set, so // the derived JSON is cached whole: a fresh cache makes an open one @@ -1461,26 +1461,18 @@ bool GuideFrame::BuildProfileDataFromVendors() } // Each vendor comes from its preset cache where one covers it, which is - // what makes this worth doing instead of the scan below; loading into a - // bundle per vendor keeps the install order the startup path has. - PresetBundle bundle; - auto load_vendor = [](PresetBundle& into, const std::string& vendor, - const boost::filesystem::path& dir, const PresetBundle* base) { - into.load_vendor_configs_from_json(dir.string(), vendor, PresetBundle::LoadSystem, - ForwardCompatibilitySubstitutionRule::EnableSilent, base); - }; - for (const VendorSource& v : ordered) { - if (*m_cancel_token) - return false; // as in the scan below: a vendor without a cache is parsed, and that takes time - if (v.name == filament_library) { - load_vendor(bundle, v.name, v.dir, nullptr); - } else { - PresetBundle tmp; - load_vendor(tmp, v.name, v.dir, &bundle); - bundle.merge_presets(std::move(tmp)); - } - } - if (bundle.vendors.empty()) + // what makes this worth doing instead of the scan below. + PresetBundle bundle; + std::vector failed; + const std::string errors = bundle.load_vendors(ordered, ForwardCompatibilitySubstitutionRule::EnableSilent, + /*allow_cache=*/true, m_cancel_token.get(), &failed).second; + if (*m_cancel_token || bundle.vendors.empty()) + return false; + if (! errors.empty()) + BOOST_LOG_TRIVIAL(warning) << "GuideFrame: loading the vendors reported: " << errors; + // A vendor that failed to load sends this open to the scan below, which lists + // what it can read of every vendor. + if (! failed.empty()) return false; if (! BuildProfileJson(bundle, /*require_all_resource_vendors=*/false)) return false; @@ -1732,7 +1724,7 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath cover_path = (boost::filesystem::absolute(boost::filesystem::path(resources_dir()) / "/web/image/printer/") / cover_file) .make_preferred(); } - OneModel["cover"] = cover_path.string(); + OneModel["cover"] = into_u8(file_url_from_path(cover_path)); OneModel["nozzle_selected"] = ""; diff --git a/src/slic3r/GUI/WebUserLoginDialog.cpp b/src/slic3r/GUI/WebUserLoginDialog.cpp index 829e7ef106..72860e3bdc 100644 --- a/src/slic3r/GUI/WebUserLoginDialog.cpp +++ b/src/slic3r/GUI/WebUserLoginDialog.cpp @@ -599,7 +599,7 @@ void ZUserLogin::OnScriptResponseMessage(wxCommandEvent &WXUNUSED(evt)) bool ZUserLogin::ShowErrorPage() { - wxString ErrortUrl = from_u8((boost::filesystem::path(resources_dir()) / "web\\login\\error.html").make_preferred().string()); + wxString ErrortUrl = file_url_from_path(boost::filesystem::path(resources_dir()) / "web/login/error.html"); load_url(ErrortUrl); return true; diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index f20d24163c..a98b196eb1 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -36,10 +36,10 @@ namespace GUI { WebViewPanel::WebViewPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) { - wxString url = wxString::Format("file://%s/web/homepage/index.html", from_u8(resources_dir())); + wxString url = file_url_from_path(boost::filesystem::path(resources_dir()) / "web/homepage/index.html"); wxString strlang = wxGetApp().current_language_code_safe(); if (strlang != "") - url = wxString::Format("file://%s/web/homepage/index.html?lang=%s", from_u8(resources_dir()), strlang); + url += "?lang=" + strlang; wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp b/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp index 316389d65c..616b8b8779 100644 --- a/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp +++ b/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp @@ -1,5 +1,6 @@ #include "MultiNozzleSync.hpp" +#include "../GUI.hpp" #include "../GUI_App.hpp" #include "../I18N.hpp" #include "../Plater.hpp" @@ -21,8 +22,6 @@ #include #include -#include -#include #include #include @@ -70,8 +69,8 @@ int getExtruderNozzleCountTotal(PresetBundle *preset_bundle, int extruder_id) // ---- ManualNozzleCountDialog ---------------------------------------------------------------------------------- -ManualNozzleCountDialog::ManualNozzleCountDialog( - wxWindow *parent, NozzleVolumeType volume_type, int standard_count, int highflow_count, int max_nozzle_count, bool force_no_zero) +ManualNozzleCountDialog::ManualNozzleCountDialog(wxWindow *parent, NozzleVolumeType volume_type, int standard_count, int highflow_count, int e3d_count, + int max_nozzle_count, bool force_no_zero, const std::set &supported_types) : DPIDialog(parent, wxID_ANY, _L("Set nozzle count"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) { SetBackgroundColour(*wxWHITE); @@ -93,43 +92,39 @@ ManualNozzleCountDialog::ManualNozzleCountDialog( for (int i = 0; i <= max_nozzle_count; ++i) nozzle_choices.Add(wxString::Format("%d", i)); - // A Hybrid extruder mixes Standard and High Flow nozzles, so it gets both count choices; the concrete - // types get exactly one. - if (volume_type == nvtStandard || volume_type == nvtHybrid) { - wxBoxSizer *standard_sizer = new wxBoxSizer(wxHORIZONTAL); - auto standard_label = new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtStandard)), wxDefaultPosition, wxSize(FromDIP(100), -1)); - standard_label->SetFont(Label::Body_14); - standard_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); - standard_sizer->Add(standard_label, 0, wxALIGN_CENTER_VERTICAL); - m_standard_choice = new ComboBox(content, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(80), -1), 0, nullptr, wxCB_READONLY); - std::vector::iterator iter; - for (iter = nozzle_choices.begin(); iter != nozzle_choices.end(); iter++) - m_standard_choice->Append(*iter); - m_standard_choice->SetSelection(standard_count); - standard_sizer->Add(m_standard_choice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); - choice_sizer->Add(standard_sizer, 0, wxTOP | wxRIGHT, FromDIP(15)); - } - if (volume_type == nvtHighFlow || volume_type == nvtHybrid) { - wxBoxSizer *highflow_sizer = new wxBoxSizer(wxHORIZONTAL); - auto highflow_label = new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtHighFlow)), wxDefaultPosition, wxSize(FromDIP(100), -1)); - highflow_label->SetFont(Label::Body_14); - highflow_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); - highflow_sizer->Add(highflow_label, 0, wxALIGN_CENTER_VERTICAL); - m_highflow_choice = new ComboBox(content, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(80), -1), 0, nullptr, wxCB_READONLY); - std::vector::iterator iter; - for (iter = nozzle_choices.begin(); iter != nozzle_choices.end(); iter++) - m_highflow_choice->Append(*iter); - m_highflow_choice->SetSelection(highflow_count); - highflow_sizer->Add(m_highflow_choice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); - choice_sizer->Add(highflow_sizer, 0, wxTOP | wxRIGHT, FromDIP(15)); - } + // A Hybrid extruder mixes several nozzle volume types, so it gets a count choice for each type the + // extruder actually has; a concrete type gets exactly its own, which it supports by definition. + auto shows = [volume_type, &supported_types](NozzleVolumeType type) { + return volume_type == type || (volume_type == nvtHybrid && (supported_types.empty() || supported_types.count(type) > 0)); + }; + auto add_count_choice = [this, content, choice_sizer, &nozzle_choices](NozzleVolumeType type, int count) { + wxBoxSizer *row_sizer = new wxBoxSizer(wxHORIZONTAL); + auto label = new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(type)), wxDefaultPosition, wxSize(FromDIP(100), -1)); + label->SetFont(Label::Body_14); + label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); + row_sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL); + auto choice = new ComboBox(content, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(80), -1), 0, nullptr, wxCB_READONLY); + for (const wxString &item : nozzle_choices) + choice->Append(item); + choice->SetSelection(count); + row_sizer->Add(choice, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); + choice_sizer->Add(row_sizer, 0, wxTOP | wxRIGHT, FromDIP(15)); + return choice; + }; + if (shows(nvtStandard)) + m_standard_choice = add_count_choice(nvtStandard, standard_count); + if (shows(nvtHighFlow)) + m_highflow_choice = add_count_choice(nvtHighFlow, highflow_count); + if (shows(nvtE3DHighFlow)) + m_e3d_choice = add_count_choice(nvtE3DHighFlow, e3d_count); m_error_label = new wxStaticText(this, wxID_ANY, ""); m_error_label->SetForegroundColour(wxColour("#E14747")); m_error_label->Hide(); - auto update_nozzle_error = [this, force_no_zero, content, max_nozzle_count](int standard_count, int highflow_count) { - const int total_count = standard_count + highflow_count; + auto update_nozzle_error = [this, force_no_zero, content, max_nozzle_count](wxCommandEvent &e) { + // The Hybrid count is the sum over every choice on screen, whatever the extruder's own type. + const int total_count = GetNozzleCount(nvtHybrid); if (0 < total_count && total_count <= max_nozzle_count && m_error_label->IsShown()) { m_error_label->Hide(); m_confirm_btn->Enable(); @@ -145,18 +140,12 @@ ManualNozzleCountDialog::ManualNozzleCountDialog( Layout(); Fit(); } + e.Skip(); }; - if (m_standard_choice) - m_standard_choice->Bind(wxEVT_COMBOBOX, [this, update_nozzle_error](wxCommandEvent &e) { - update_nozzle_error(m_standard_choice->GetSelection(), m_highflow_choice ? m_highflow_choice->GetSelection() : 0); - e.Skip(); - }); - if (m_highflow_choice) - m_highflow_choice->Bind(wxEVT_COMBOBOX, [this, update_nozzle_error](wxCommandEvent &e) { - update_nozzle_error(m_standard_choice ? m_standard_choice->GetSelection() : 0, m_highflow_choice->GetSelection()); - e.Skip(); - }); + for (ComboBox *choice : {m_standard_choice, m_highflow_choice, m_e3d_choice}) + if (choice) + choice->Bind(wxEVT_COMBOBOX, update_nozzle_error); content_sizer->Add(nozzle_icon, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(15)); content_sizer->Add(choice_sizer, 0, wxALIGN_CENTRE_VERTICAL); @@ -181,9 +170,10 @@ int ManualNozzleCountDialog::GetNozzleCount(NozzleVolumeType volume_type) const return m_standard_choice ? m_standard_choice->GetSelection() : 0; if (volume_type == nvtHighFlow) return m_highflow_choice ? m_highflow_choice->GetSelection() : 0; + if (volume_type == nvtE3DHighFlow) + return m_e3d_choice ? m_e3d_choice->GetSelection() : 0; if (volume_type == nvtHybrid) - return (m_standard_choice ? m_standard_choice->GetSelection() : 0) + - (m_highflow_choice ? m_highflow_choice->GetSelection() : 0); + return GetNozzleCount(nvtStandard) + GetNozzleCount(nvtHighFlow) + GetNozzleCount(nvtE3DHighFlow); return 0; } @@ -318,6 +308,7 @@ void manuallySetNozzleCount(int extruder_id) const NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volume_type_opt->values[extruder_id]); const int standard_count = getExtruderNozzleCount(preset_bundle, extruder_id, nvtStandard); const int highflow_count = getExtruderNozzleCount(preset_bundle, extruder_id, nvtHighFlow); + const int e3d_count = getExtruderNozzleCount(preset_bundle, extruder_id, nvtE3DHighFlow); // Require at least one nozzle for a Hybrid extruder (an empty mix is meaningless) and when the other // extruder currently has none. @@ -325,11 +316,19 @@ void manuallySetNozzleCount(int extruder_id) if (nozzle_volume_type_opt->values.size() > 1) force_no_zero |= getExtruderNozzleCountTotal(preset_bundle, 1 - extruder_id) == 0; - ManualNozzleCountDialog dialog(wxGetApp().plater(), volume_type, standard_count, highflow_count, max_nozzle_count->values[extruder_id], force_no_zero); + // The printer profile's variant list is the authority on which volume types an extruder provides. An + // empty set means the profile could not be read, and the dialog then skips filtering instead of hiding + // everything. + const std::set supported_types = + get_extruder_supported_nozzle_volume_types(preset_bundle->printers.get_edited_preset().config, extruder_id); + + ManualNozzleCountDialog dialog(wxGetApp().plater(), volume_type, standard_count, highflow_count, e3d_count, + max_nozzle_count->values[extruder_id], force_no_zero, supported_types); if (dialog.ShowModal() == wxID_OK) { if (volume_type == nvtHybrid) { setExtruderNozzleCount(preset_bundle, extruder_id, nvtStandard, dialog.GetNozzleCount(nvtStandard), true); setExtruderNozzleCount(preset_bundle, extruder_id, nvtHighFlow, dialog.GetNozzleCount(nvtHighFlow), false); + setExtruderNozzleCount(preset_bundle, extruder_id, nvtE3DHighFlow, dialog.GetNozzleCount(nvtE3DHighFlow), false); } else { setExtruderNozzleCount(preset_bundle, extruder_id, volume_type, dialog.GetNozzleCount(volume_type), true); } @@ -641,8 +640,7 @@ NozzleListTable::NozzleListTable(wxWindow* parent) : wxPanel(parent,wxID_ANY,wxD m_web_view->AddScriptMessageHandler("nozzleListTable"); m_web_view->EnableContextMenu(false); fs::path filepath = fs::path(resources_dir()) / "web/flush/NozzleListTable.html"; - wxFileName fn(wxString::FromUTF8(filepath.string())); - wxString url = wxFileSystem::FileNameToURL(fn); + wxString url = file_url_from_path(filepath); m_web_view->LoadURL(url); auto sizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp b/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp index 5a3e9374a7..50bd534c72 100644 --- a/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp +++ b/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -64,7 +65,9 @@ struct NozzleOption class ManualNozzleCountDialog : public DPIDialog { public: - ManualNozzleCountDialog(wxWindow *parent, NozzleVolumeType volume_type, int standard_count, int highflow_count, int max_nozzle_count, bool force_no_zero); + // supported_types lists the volume types the extruder physically provides; an empty set means "unknown", in which case no filtering is applied. + ManualNozzleCountDialog(wxWindow *parent, NozzleVolumeType volume_type, int standard_count, int highflow_count, int e3d_count, int max_nozzle_count, bool force_no_zero, + const std::set &supported_types); ~ManualNozzleCountDialog() override = default; void on_dpi_changed(const wxRect &suggested_rect) override {} int GetNozzleCount(NozzleVolumeType volume_type) const; @@ -72,6 +75,7 @@ public: private: ComboBox *m_standard_choice{nullptr}; ComboBox *m_highflow_choice{nullptr}; + ComboBox *m_e3d_choice{nullptr}; Button *m_confirm_btn{nullptr}; wxStaticText *m_error_label{nullptr}; }; diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp index c391ddd017..f9fa3405d3 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.cpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp @@ -4,6 +4,8 @@ #include "StaticBox.hpp" #include "../wxExtensions.hpp" + +#include #include "../GUI_App.hpp" #include "slic3r/GUI/I18N.hpp" #include "../Utils/MacDarkMode.hpp" @@ -620,19 +622,34 @@ MultiSwitchButton::MultiSwitchButton(wxWindow *parent, wxWindowID id, const wxPo std::make_pair(0x6B6B6B, (int) StateColor::NotChecked), std::make_pair(0xFFFFFE, (int) StateColor::Normal))) , m_button_radius(10.0) - , m_button_padding(10, 6) + , m_button_padding(FromDIP(wxSize(11, 3))) { SetCornerRadius(m_button_radius); SetBorderWidth(0); - sizer = new wxBoxSizer(wxHORIZONTAL); - auto *hsizer = new wxBoxSizer(wxVERTICAL); - hsizer->Add(sizer, 1, wxEXPAND); - SetSizer(hsizer); - SetMinSize(wxSize(-1, 20)); + // Orca: a switch can hold more buttons than the layout has room for (a toolchanger lists one per + // tool), so they live in a scrolled area: the caller caps the switch at its natural width and + // this scrolls horizontally instead of clipping the last buttons. + m_scroll = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxBORDER_NONE); + m_scroll->SetBackgroundColour(GetBackgroundColour()); + // The buttons are a single row, so only the horizontal bar may ever appear: a vertical one would + // eat into the row's height. + m_scroll->ShowScrollbars(wxSHOW_SB_DEFAULT, wxSHOW_SB_NEVER); + m_scroll->EnableScrolling(true, false); + m_scroll->SetScrollRate(FromDIP(10), 0); + sizer = new wxBoxSizer(wxHORIZONTAL); + m_scroll->SetSizer(sizer); + + auto *hsizer = new wxBoxSizer(wxVERTICAL); + hsizer->Add(m_scroll, 1, wxEXPAND); + SetSizer(hsizer); + SetMinSize(wxSize(-1, options_height())); + + Bind(wxEVT_SIZE, &MultiSwitchButton::on_size, this); Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MultiSwitchButton::button_clicked, this); - SetFont(Label::Body_12); + // The tags name a tool and its volume type only, so they stay compact. + SetFont(Label::Body_10); } MultiSwitchButton::~MultiSwitchButton() @@ -640,10 +657,88 @@ MultiSwitchButton::~MultiSwitchButton() DeleteAllOptions(); } +int MultiSwitchButton::options_height() const +{ + // With no button to measure yet, keep the placeholder height the switch starts with. + return btns.empty() ? FromDIP(20) : btns.front()->GetMinSize().y; +} + +void MultiSwitchButton::update_scroll_range() +{ + // The scrollbar range is measured against the virtual size, so it has to follow the buttons + // whenever their labels or count change. + m_scroll->InvalidateBestSize(); + m_scroll->FitInside(); + + // A scrolled window reports its min size plus a scrollbar as its best size, never the width of + // the buttons it holds, so the layout has to be given that width explicitly. It is also the + // widest this switch wants to be: a row with less room squeezes it below this and it scrolls. + const wxSize content = sizer->CalcMin(); + SetMinSize(wxSize(content.x, options_height() + scrollbar_height(content.x))); + SetMaxSize(m_fit_to_options ? wxSize(content.x, -1) : wxDefaultSize); + InvalidateBestSize(); +} + +int MultiSwitchButton::scrollbar_height(int options_width) const +{ + // The bar is drawn inside the switch, so while the buttons need more width than the row gave us + // the switch has to be taller by the bar's height, or the bar sits on top of the buttons. + const int width = GetClientSize().x; + if (width <= 0 || options_width <= width) + return 0; + + const int bar = wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y, this); + return bar > 0 ? bar : 0; +} + +void MultiSwitchButton::on_size(wxSizeEvent &evt) +{ + evt.Skip(); + + // The row resized, so the buttons may now overflow it (or no longer fit in it) and the room the + // bar needs changed with that. Width does not depend on height, so this settles in one pass. + const int height = options_height() + scrollbar_height(sizer->CalcMin().x); + if (GetMinSize().y != height) { + SetMinSize(wxSize(GetMinSize().x, height)); + // The switch sits in a row of this tab, and the tab in a panel that shares its height + // with the page view, so both have to lay out again for the taller row to get its room. + if (wxWindow *tab = GetParent()) { + tab->Layout(); + if (wxWindow *panel = tab->GetParent()) + panel->Layout(); + } + } +} + +void MultiSwitchButton::scroll_option_into_view(Button *btn) +{ + const int width = m_scroll->GetClientSize().x; + const int view_x = m_scroll->GetViewStartPixels().x; + if (width <= 0) // not laid out yet: there is no view to scroll + return; + + const wxRect rect = btn->GetRect(); + const int right = rect.GetRight() + 1; + int target = view_x; + if (rect.x < view_x) + target = rect.x; + else if (right > view_x + width) + target = right - width; + + if (target == view_x) + return; + + // Scroll() counts scroll units; round up so the whole button ends up inside the view rather + // than a few pixels short of it. + int step = 1; + m_scroll->GetScrollPixelsPerUnit(&step, nullptr); + m_scroll->Scroll((target + step - 1) / step, -1); +} + int MultiSwitchButton::AppendOption(const wxString &option, void *clientData) { Button *btn = new Button(); - btn->Create(this, option, "", wxBORDER_NONE); + btn->Create(m_scroll, option, "", wxBORDER_NONE); btn->SetFont(GetFont()); btn->SetBackgroundColor(m_bg_color); btn->SetTextColor(m_text_color); @@ -654,9 +749,6 @@ int MultiSwitchButton::AppendOption(const wxString &option, void *clientData) btns.push_back(btn); sizer->Add(btn, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL); - wxSize text_size = btn->GetTextExtent(option); - btn->SetMinSize(wxSize(text_size.x + m_button_padding.x * 2 + 6, -1)); - return int(btns.size()) - 1; } @@ -666,6 +758,7 @@ void MultiSwitchButton::SetOptions(const std::vector &options) for (const auto &option : options) AppendOption(option); + update_scroll_range(); Layout(); Refresh(); } @@ -700,6 +793,8 @@ void MultiSwitchButton::SetSelection(int index) sel = index; update_button_styles(); send_selection_event(); + // The selected button may be scrolled out of sight, e.g. when the tab restores the active tool. + scroll_option_into_view(btns[sel]); Refresh(); } @@ -718,6 +813,7 @@ void MultiSwitchButton::SetOptionText(unsigned int index, const wxString &text) if (index >= btns.size()) return; btns[index]->SetLabel(text); + update_scroll_range(); } void *MultiSwitchButton::GetOptionData(unsigned int index) const @@ -769,6 +865,7 @@ void MultiSwitchButton::SetButtonPadding(const wxSize &padding) m_button_padding = padding; for (auto *btn : btns) btn->SetPaddingSize(padding); + update_scroll_range(); Layout(); Refresh(); } @@ -777,6 +874,8 @@ void MultiSwitchButton::Rescale() { for (auto *btn : btns) btn->Rescale(); + // Rescaling can change how the labels measure, and the scrollbar range follows the buttons. + update_scroll_range(); } void MultiSwitchButton::button_clicked(wxCommandEvent &event) diff --git a/src/slic3r/GUI/Widgets/SwitchButton.hpp b/src/slic3r/GUI/Widgets/SwitchButton.hpp index 6e271abfaf..decff25919 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.hpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include "Button.hpp" @@ -164,6 +165,10 @@ public: void SetButtonCornerRadius(double radius); void SetButtonPadding(const wxSize &padding); + // Keep the switch exactly as wide as the buttons need instead of letting the layout stretch it. + // A layout with less room than that still squeezes it, and it scrolls its buttons then. + void SetFitToOptions(bool fit = true) { m_fit_to_options = fit; update_scroll_range(); } + void Rescale(); protected: @@ -173,9 +178,20 @@ protected: bool send_selection_event(); private: + // Height of the single button row, measured from the buttons themselves. + int options_height() const; + void update_scroll_range(); + int scrollbar_height(int options_width) const; + void scroll_option_into_view(Button *btn); + void on_size(wxSizeEvent &evt); + std::vector