Compare commits

...
Author SHA1 Message Date
Lam Wei Lun 0ee529e283 Fixes missing Plugins category for installed plugins 2026-09-24 15:25:11 +08:00
Lam Wei Lun 7ae76e44b1 Merge branch 'main' into feat/speed-dial-fixes 2026-09-24 10:42:19 +08:00
Lam Wei Lun 54c32a54b4 Change some search actions and results text. Force repaint for when resizing and show happens 2026-09-24 10:41:55 +08:00
Valerii Bokhan 037b859447 Fix: Correct camera panning for the perspective view (#15212) 2026-09-23 20:38:26 -03:00
Ian BassiandRodrigo Faselli 02746cd0f5 Disable SSAO for grid (#15865)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-23 20:38:04 -03:00
Kris Austin 66b300987b feat: faster startup by lazy-loading main window panels on idle or first use (#15811) 2026-09-23 19:11:10 -03:00
Kris Austin 9bae19fcb3 fix: the 3D scene is drawn in the wrong view for the first half second of startup (#15830) 2026-09-23 18:21:16 -03:00
Lam Wei Lun fcd8131998 WebGuide's Filament Dialog Fix to ensure filaments inheritance chain is checked properly (#15855)
* fix: resolve filament vendor/type across split base presets

WebGuide's filament list dropped presets whose vendor and type came from different ancestors, and looped forever on inherits cycles. Walk the full inherits chain with a path-scoped guard, fill only missing values, and skip presets that still lack vendor or type. Add tests for split-base resolution and validate the real profile tree.

* Merge branch 'main' into feat/filament_dialog_fix

* Fixes unit test

* Merge branch 'main' into feat/filament_dialog_fix

* Merge branch 'main' into feat/filament_dialog_fix

* revert tests/fff_print/test_gcodewriter.cpp changes
2026-09-23 20:23:52 +08:00
a8f1061a02 Add Sovol Zero nozzle profiles and filament profiles (#15756)
* Add Sovol Zero nozzle profiles and filament updates

Preserve inherited tuning with Zero-only overrides so shared
Sovol defaults and other printers remain unchanged. Retain migration
aliases while using canonical names in compatibility references.

Co-authored-by: Codex <noreply@openai.com>

* Fix Sovol Zero bed model reference and ignored settings

Point the Zero model at the shipped bed mesh. Remove unsupported filament
and process keys that the loader silently discards, preserving effective
tuning and the existing preset names and IDs. Bump the Sovol bundle version.

Co-authored-by: Codex <noreply@openai.com>

* Fix Sovol Zero filament identity and vector formatting

Add hardened-steel nozzle variants with disjoint filament compatibility, retain generic product IDs and preserve renamed preset aliases. Convert 43 scalar vector fields to arrays without changing tuning values and bump the Sovol bundle version.

Co-authored-by: Codex <codex@openai.com>

* Keep only shipped names in the Sovol Zero profile renames

The Zero machines, processes, machine model and SPEEDBENCHY filament carried renamed_from entries for names that only ever existed inside this branch (Sovol ZERO ..., " - Brass", " - Hardened Steel"). Drop those, and keep only the redirects that matter to existing users: the historical Sovol Zero material names and the three deleted hardened-steel presets. The Sovol Zero machine model also sheds the setting_id, instantiation and from keys the model loader ignores.

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-09-23 20:05:01 +08:00
SoftFever b46916a8be Revert "Sync Bambu Lab profiles with BambuStudio"
This reverts commit cc883e458d.
2026-09-23 18:19:23 +08:00
SoftFever bf024ed34e Revert "Restore the Bambu Lab bed-model offset so stock BambuStudio meshes line up"
This reverts commit 7758332406.
2026-09-23 18:19:03 +08:00
Sylvain 0211277976 Add Wanhao Duplicator 9 profiles (D9/300, D9/400, D9/500) (#15773) 2026-09-23 17:24:17 +08:00
SoftFever 7758332406 Restore the Bambu Lab bed-model offset so stock BambuStudio meshes line up 2026-09-23 14:58:41 +08:00
SoftFever cc883e458d Sync Bambu Lab profiles with BambuStudio
Polymaker, Overture and eSUN presets move from brand subfolders to
BBL/filament/, matching BambuStudio's layout; their names and ids are
unchanged. Default filament lists keep pointing at presets that exist,
0.2 mm nozzles keep a default PLA, and user presets based on removed or
renamed presets still load. Generic SBS is no longer in the Bambu bundle;
new selections on those printers fall back to OrcaFilamentLibrary's
Generic SBS @System. The profile tool now recognises BambuStudio's new
filament id/name maps and support_recommended_params.json as data files.
2026-09-23 14:58:41 +08:00
145 changed files with 5825 additions and 1094 deletions
+220
View File
@@ -0,0 +1,220 @@
# Deferred Page Construction: High Level Design
## Why it exists
The main window is a notebook of tabs. When the first frame appears, one tab is on
screen and the others are not; some of them are opened later in the session, some
never, and some only exist for certain printers. Building a tab before the first frame
adds its cost to every startup, whether or not the tab is used.
This subsystem builds a tab's panel the first time the tab is shown. It also builds the
remaining tabs while the user is idle after startup, in units of tens of milliseconds,
so a click that lands in the middle of one waits for that unit and no longer. Startup
pays only for what the first frame shows, and the other tabs are usually built before
anyone opens them.
## The parts
`src/slic3r/GUI/Lazy.hpp`, `LazyPage.hpp`, `StagedBuild.hpp` and `IdleScheduler.hpp/.cpp`
(with its wx-free `PrebuildQueue.hpp`) are independent. A holder can hold anything a
factory makes, a page is a holder with a placeholder widget, a staged object can live
outside a holder, and the scheduler knows none of them; it runs tasks, which `MainFrame`
makes from the holders.
### Lazy<T>: the holder
Holds an object that a factory makes on first use, under a name for the log and a place
in the idle queue, both given by the owner. The header has no wx dependency; the busy
cursor for an on-demand build lives in `Lazy.cpp` and is skipped when there is no app,
so the holder is unit-tested.
- `get()` is null until the object is completely built; `built()` says the same.
- `ensure()` builds whatever is left now, under a busy cursor, and returns the object, or
null in the two cases below. A click on an unbuilt tab or a first open of a dialog goes
through this, and it logs the units and time it took.
- `build_step()` runs one unit of construction and returns true while more remain. The
first unit is the factory call, and each later unit is one `StagedBuild` step if the
type has them.
- `when_built(fn)` runs `fn(object)` now if it exists, otherwise once it is built.
- `pending()` says whether the idle prebuild has work here: not built, and the factory
has not returned null. A null factory result is logged and the holder stays unbuilt.
- A unit that pumps the event loop cannot re-enter the holder; a nested `build_step()`
does nothing and a nested `ensure()` returns null.
- After a unit throws, the holder and the scheduler still run the next one.
The holder does not own the object; its wx parent does, as for any window. A type with
one instance in the app derives from `LazyInstance<T>`, which points at that instance's
holder (the holder registers itself, and a recreated `MainFrame`'s holder replaces the
old frame's) and gives the type the static entry points the rest of the app uses,
`T::if_built()`, `T::ensure()` and `T::when_built(fn)`. They return null, or do
nothing, while no holder exists, so a caller needs no `mainframe` check.
`built()` is an atomic flag, since a job worker reads it through the statics
(`MainFrame::get_calibration_curr_tab()`); it is set after the object is complete.
`LazyBase` is the holder's type-free interface (`name()`, `built()`, `pending()`,
`build_step()`, `prebuild_order()`) and is what the scheduler side sees.
### LazyPage<Panel>: the placeholder
A `wxPanel` placed in the parent in place of the real panel, and a `Lazy<Panel>` whose
factory makes the panel inside it (by default `new Panel(parent)`). The notebook needs a
page object for the tab to exist and for `show_device()` to insert and remove tabs by
pointer, and the placeholder is that object. `MainFrame` creates every page once, named
after its `TAB_ID_*`, and keeps it for the frame's life; `show_device()` only moves
pages in and out of the book.
- `Show()` is forwarded to the panel, so a panel's own `Show()` override stays its
activation hook (refresh timers, machine sync) and `SelectPageByName()` works
unchanged. A show builds the panel unless the frame itself is still hidden, because
the book selects its first page as it is inserted; `MainFrame::Show()` shows the
current page again when the frame becomes visible, which builds it.
- `in_book()` says whether the parent notebook currently lists the page, and
`pending()` is that and not built, so a tab `show_device()` has taken out of the book
is not prebuilt.
- A panel built while its page is hidden stays hidden, and a completed panel gets the
dark-mode pass the frame ran before it existed.
The Compare presets dialog is a holder without a page. `MainFrame` keeps a
`Lazy<DiffPresetDialog>` whose factory constructs the dialog and binds its events, the
dialog derives from `LazyInstance`, and its callers use
`DiffPresetDialog::ensure()->show()` and `DiffPresetDialog::if_built()` like a tab's
callers do. Saving a preset refreshes the dialog only while it is shown, since `show()`
reloads the presets.
### StagedBuild: construction in units
A mixin for a panel whose constructor is too big to be one unit. The constructor builds
the skeleton (sizers, and the parts other code may touch) and queues the rest with
`add_build_step()`. `build_step()` runs one step, and `add_build_steps_of(child)`
forwards a child's steps so a nested panel is spread the same way; the parent is built
only once the child is, including steps the child queues later. Steps run in order, on
the main thread. A `Lazy<T>` recognises a staged type at compile time and runs its steps
one per unit.
Nothing may touch what a step builds before the last step has run. In practice:
- nothing paints the panel before it is complete, since a panel built at idle is hidden
with its page and one built on demand finishes inside `ensure()` before the event loop
runs again;
- members created in steps are initialised to null in the header, so a partially built
panel can be destroyed;
- timers and event handlers that use step content check `built()` first
(`MonitorPanel::update_all()`, `CalibrationPanel::update_all()`), and a child's steps
are queued before anything in the constructor can fire such a handler;
- a destructor that disconnects from step content checks `built()` first;
- a constructor or step does not take focus while the panel is off screen
(`IsShownOnScreen()` before `SetFocus()`), since it may run while the user is typing
elsewhere;
- where a step's widgets must keep their place in a sizer that later steps also fill, the
constructor adds an empty slot sizer in that position and the step fills the slot
(`StatusBasePanel`).
### IdleScheduler: when to build
A task is any `LazyBase`: a name for the log, `pending()`, `build_step()` and
`prebuild_order()`. `PrebuildQueue` holds the tasks by order (equal order in the order
added) and runs a slice, the units of the first pending task until it completes, the
budget is spent on the clock it is given, or the interrupt predicate says input arrived.
It has no wx dependency and is unit-tested with a fake clock. A task whose work is gone
is passed over and stays in the queue, so a tab that `show_device()` removes and later
re-inserts is pending again.
`IdleScheduler` drives the queue with the real clock, the app's input timestamp and the
Windows queue check, and logs each unit and slice. Each slice is a timer message: a
period of 250 ms while waiting for the user to go quiet, and a one-shot of zero after a
slice that left work, so the event loop dispatches whatever it has queued (paint,
timers, input) before the next slice runs. Chaining slices with `CallAfter` would not do
this: wx drains pending events fully before the next native message, on every platform.
On GTK the one-shot is 5 ms, because a due GLib timeout runs ahead of the redraw and
idle sources that paint and deliver posted events.
A slice runs only once the user has been idle for the quiet time, and the timer stops
itself once no task is pending. The tick period, quiet time and slice length are
constants in `IdleScheduler.cpp`. A unit cannot be interrupted once started, so the
largest unit bounds click latency on Windows; on the other platforms a click also waits
for the rest of the slice. A unit that pumps the event loop lets the timer fire inside
its own slice, and that tick does nothing.
The tasks are made by their owners. `MainFrame::prebuild_pages_when_idle()` registers
every `LazyPage` the frame created, in or out of the book (`pending()` is false for a
page out of the book), the Compare presets holder, and the Prepare sidebar's settings
page from `ParamsPanel::settings_page_prebuild()`, whose first unit selects the default
tab if none is selected yet and whose later units build one option group each.
`show_device()` only restarts the timer. `MainFrame` owns the scheduler because it owns
everything the tasks build, and clearing the queue with the frame is what keeps a task
from outliving its object.
Idle time comes from `GUI_App::FilterEvent`, which timestamps mouse and keyboard events
(`wxEVT_CATEGORY_USER_INPUT` minus command events, which all claim that category), and
`GUI_App::input_idle_ms()` reports it. On Windows a slice additionally refuses to start
when the message queue holds keyboard, button, touch or pen input. Mouse moves are
excluded because Windows synthesises one whenever a window appears under the cursor,
which every unit does. Other platforms use the timestamp alone.
Once every registered page is built the timer is stopped and the subsystem costs
nothing.
## Rules
**What builds before the first frame.** The Prepare tab's plater, because `post_init()`
needs its GL canvas on screen to initialise OpenGL in every startup state, and the start
page the user configured. Home is built by the first `MainFrame::Show()`, Prepare's
settings page by selecting the tab. `post_init()` passes through the Prepare tab for GL
init under `Freeze()` with `MainFrame::select_prepare_for_gl_init()`, which changes the
selection without the page-changed event, so nothing else is built for that pass.
**Reaching a lazy object.** A caller uses the type's own statics. `T::if_built()` may
return null and is for telling the object something it can live without (a rescale, a
colour change, a status update). `T::ensure()` builds the object and is for navigating
to it or for a caller that is about to show it. A caller that tells the object something
it would not fetch for itself on construction uses `T::when_built()`, which keeps the
message until the object exists. A panel that pulls its state when constructed (the Home
page requests the recent list on load, the Device tab reads the device manager on show)
is reached with `if_built()`; one that cannot pull gets `when_built()`.
**Unit size.** A unit cannot be interrupted, so it should stay within the slice length on
a fast machine. A constructor above that is staged. A single widget above it is the
floor unless the widget itself is split.
**Order.** Cheapest and most likely to be opened first, given where `MainFrame` creates
each holder. The settings page is 0 (the Prepare tab's own content), Home 10, Device 20
(a Bambu user's usual second stop), Calibration 30, Multi-device 40, the web Device
view 50, Project 60 (a second WebView2 instance) and the Compare presets dialog 100;
steps of ten so a new tab takes a value between its neighbours without renumbering
them. `MainFrame::prebuild_pages_when_idle()` registers the tasks once, from
`post_init()`.
**Never prebuilt.** A holder with a negative order, for a tab that few sessions open
and that costs more to build unasked than it saves (the Design tab), and plugin-provided
tabs, which are Python-side and not lazy pages.
## Adopting it
A lazy tab needs:
1. The panel derived from `LazyInstance<Panel>`, since a tab's panel has one instance.
2. A `LazyPage<Panel>*` member in `MainFrame`, created once in `init_tabpanel()` with
its `TAB_ID_*` as the name, its place by the order rule (and a factory if
`new Panel(parent)` is not enough), added to `m_lazy_pages`, and used wherever the
tab is added to or looked up in the notebook.
3. Every use of the panel outside `MainFrame` going through one of the panel's statics,
chosen by the rule above. When converting an existing member, `grep` for it; the
compiler finds the rest.
4. A constructor that copes with the frame already existing and the user being busy
elsewhere, since `wxGetApp().mainframe` is set, the frame may be shown, and the user
may be typing when a lazy panel is built: no `SetFocus()` while off screen, and
whatever the constructor did through a `MainFrame` accessor before (a mode update, a
deferred URL) done in the constructor itself.
To stage a heavy constructor, inherit `StagedBuild`, keep the skeleton in the constructor,
move the rest into `add_build_step()` lambdas in the original order, and follow the
staged-panel rules above. Measure the units. A step that is still one big widget has to
be split inside that widget or accepted as the floor.
Verification is by log. `MainFrame::prebuild_pages_when_idle` lists the queue it
registered, `IdleScheduler::tick` reports each completed task by name at info level and
each slice and unit at debug level, and `Lazy::ensure` reports an object a user built
on demand with the units and time it took. A run from the configured start
page shows every registered page complete, in order, with no unit longer than intended.
A click on a tab mid-prebuild shows the finished panel with an `ensure` line for what was
left, and the slices resume for the remaining tasks once the user is idle again.
+121 -17
View File
@@ -1,7 +1,7 @@
{
"name": "Sovol",
"url": "",
"version": "02.04.00.04",
"version": "02.04.00.07",
"force_update": "0",
"description": "Sovol configurations",
"machine_model_list": [
@@ -167,10 +167,6 @@
"name": "0.20mm Standard @Sovol SV08 MAX 0.4 nozzle",
"sub_path": "process/0.20mm Standard @Sovol SV08 MAX 0.4 nozzle.json"
},
{
"name": "0.20mm Standard @Sovol Zero 0.4 nozzle",
"sub_path": "process/0.20mm Standard @Sovol Zero 0.4 nozzle.json"
},
{
"name": "0.28mm Fast @Sovol SV06 ACE",
"sub_path": "process/0.28mm Fast @Sovol SV06 ACE 0.4 nozzle.json"
@@ -198,6 +194,74 @@
{
"name": "0.40mm Standard @Sovol SV08 MAX 0.8 nozzle",
"sub_path": "process/0.40mm Standard @Sovol SV08 MAX 0.8 nozzle.json"
},
{
"name": "fdm_process_zero",
"sub_path": "process/fdm_process_zero.json"
},
{
"name": "0.06mm Quality @Sovol Zero 0.2 nozzle",
"sub_path": "process/0.06mm Quality @Sovol Zero 0.2 nozzle.json"
},
{
"name": "0.10mm Standard @Sovol Zero 0.2 nozzle",
"sub_path": "process/0.10mm Standard @Sovol Zero 0.2 nozzle.json"
},
{
"name": "0.12mm Quality @Sovol Zero 0.4 nozzle",
"sub_path": "process/0.12mm Quality @Sovol Zero 0.4 nozzle.json"
},
{
"name": "0.14mm Fast @Sovol Zero 0.2 nozzle",
"sub_path": "process/0.14mm Fast @Sovol Zero 0.2 nozzle.json"
},
{
"name": "0.15mm Quality @Sovol Zero 0.6 nozzle",
"sub_path": "process/0.15mm Quality @Sovol Zero 0.6 nozzle.json"
},
{
"name": "0.20mm Quality @Sovol Zero 0.8 nozzle",
"sub_path": "process/0.20mm Quality @Sovol Zero 0.8 nozzle.json"
},
{
"name": "0.20mm Standard @Sovol Zero 0.4 nozzle",
"sub_path": "process/0.20mm Standard @Sovol Zero 0.4 nozzle.json"
},
{
"name": "0.25mm Quality @Sovol Zero 1.0 nozzle",
"sub_path": "process/0.25mm Quality @Sovol Zero 1.0 nozzle.json"
},
{
"name": "0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle",
"sub_path": "process/0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle.json"
},
{
"name": "0.28mm Fast @Sovol Zero 0.4 nozzle",
"sub_path": "process/0.28mm Fast @Sovol Zero 0.4 nozzle.json"
},
{
"name": "0.30mm Standard @Sovol Zero 0.6 nozzle",
"sub_path": "process/0.30mm Standard @Sovol Zero 0.6 nozzle.json"
},
{
"name": "0.40mm Standard @Sovol Zero 0.8 nozzle",
"sub_path": "process/0.40mm Standard @Sovol Zero 0.8 nozzle.json"
},
{
"name": "0.42mm Fast @Sovol Zero 0.6 nozzle",
"sub_path": "process/0.42mm Fast @Sovol Zero 0.6 nozzle.json"
},
{
"name": "0.50mm Standard @Sovol Zero 1.0 nozzle",
"sub_path": "process/0.50mm Standard @Sovol Zero 1.0 nozzle.json"
},
{
"name": "0.56mm Fast @Sovol Zero 0.8 nozzle",
"sub_path": "process/0.56mm Fast @Sovol Zero 0.8 nozzle.json"
},
{
"name": "0.70mm Fast @Sovol Zero 1.0 nozzle",
"sub_path": "process/0.70mm Fast @Sovol Zero 1.0 nozzle.json"
}
],
"filament_list": [
@@ -249,6 +313,10 @@
"name": "Generic PETG @Sovol Zero",
"sub_path": "filament/Generic PETG @Sovol Zero.json"
},
{
"name": "Generic PETG @Sovol Zero Hardened Steel nozzle",
"sub_path": "filament/Generic PETG @Sovol Zero Hardened Steel nozzle.json"
},
{
"name": "Generic PLA @Sovol SV06 ACE",
"sub_path": "filament/Generic PLA @Sovol SV06 ACE.json"
@@ -277,6 +345,14 @@
"name": "Generic PLA @Sovol Zero",
"sub_path": "filament/Generic PLA @Sovol Zero.json"
},
{
"name": "Generic PLA @Sovol Zero Hardened Steel nozzle",
"sub_path": "filament/Generic PLA @Sovol Zero Hardened Steel nozzle.json"
},
{
"name": "Generic PLA SPEEDBENCHY @Sovol Zero",
"sub_path": "filament/Generic PLA SPEEDBENCHY @Sovol Zero.json"
},
{
"name": "Generic PLA Silk @Sovol SV08 MAX",
"sub_path": "filament/Generic PLA Silk @Sovol SV08 MAX.json"
@@ -285,6 +361,10 @@
"name": "Generic PLA Silk @Sovol Zero",
"sub_path": "filament/Generic PLA Silk @Sovol Zero.json"
},
{
"name": "Generic PLA Silk @Sovol Zero Hardened Steel nozzle",
"sub_path": "filament/Generic PLA Silk @Sovol Zero Hardened Steel nozzle.json"
},
{
"name": "Generic TPU @Sovol SV06 ACE",
"sub_path": "filament/Generic TPU @Sovol SV06 ACE.json"
@@ -312,18 +392,6 @@
{
"name": "SUNLU PETG @Sovol SV08 MAX",
"sub_path": "filament/SUNLU PETG @Sovol SV08 MAX.json"
},
{
"name": "Sovol Zero PETG HS Nozzle",
"sub_path": "filament/Sovol Zero PETG HS Nozzle.json"
},
{
"name": "Sovol Zero PLA Basic HS Nozzle",
"sub_path": "filament/Sovol Zero PLA Basic HS Nozzle.json"
},
{
"name": "Sovol Zero PLA Silk HS Nozzle",
"sub_path": "filament/Sovol Zero PLA Silk HS Nozzle.json"
}
],
"machine_list": [
@@ -415,9 +483,45 @@
"name": "Sovol SV08 MAX 0.8 nozzle",
"sub_path": "machine/Sovol SV08 MAX 0.8 nozzle.json"
},
{
"name": "Sovol Zero 0.2 nozzle",
"sub_path": "machine/Sovol Zero 0.2 nozzle.json"
},
{
"name": "Sovol Zero 0.4 nozzle",
"sub_path": "machine/Sovol Zero 0.4 nozzle.json"
},
{
"name": "Sovol Zero 0.6 nozzle",
"sub_path": "machine/Sovol Zero 0.6 nozzle.json"
},
{
"name": "Sovol Zero 0.8 nozzle",
"sub_path": "machine/Sovol Zero 0.8 nozzle.json"
},
{
"name": "Sovol Zero 1.0 nozzle",
"sub_path": "machine/Sovol Zero 1.0 nozzle.json"
},
{
"name": "Sovol Zero 0.2 Hardened Steel nozzle",
"sub_path": "machine/Sovol Zero 0.2 Hardened Steel nozzle.json"
},
{
"name": "Sovol Zero 0.4 Hardened Steel nozzle",
"sub_path": "machine/Sovol Zero 0.4 Hardened Steel nozzle.json"
},
{
"name": "Sovol Zero 0.6 Hardened Steel nozzle",
"sub_path": "machine/Sovol Zero 0.6 Hardened Steel nozzle.json"
},
{
"name": "Sovol Zero 0.8 Hardened Steel nozzle",
"sub_path": "machine/Sovol Zero 0.8 Hardened Steel nozzle.json"
},
{
"name": "Sovol Zero 1.0 Hardened Steel nozzle",
"sub_path": "machine/Sovol Zero 1.0 Hardened Steel nozzle.json"
}
]
}
@@ -1,10 +1,11 @@
{
"type": "filament",
"name": "Generic ABS @Sovol Zero",
"inherits": "Generic ABS @System",
"renamed_from": "Sovol Zero ABS",
"inherits": "fdm_filament_abs",
"from": "system",
"setting_id": "g6sSyyIFYJUzlXsp",
"filament_id": "OFY9muEs",
"instantiation": "true",
"filament_flow_ratio": [
"0.98"
@@ -73,6 +74,39 @@
"0"
],
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.8 nozzle",
"Sovol Zero 1.0 nozzle",
"Sovol Zero 0.2 Hardened Steel nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
],
"cool_plate_temp": [
"80"
],
"eng_plate_temp": [
"80"
],
"textured_plate_temp": [
"80"
],
"cool_plate_temp_initial_layer": [
"80"
],
"eng_plate_temp_initial_layer": [
"80"
],
"textured_plate_temp_initial_layer": [
"80"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_density": [
"1.10"
]
}
@@ -1,11 +1,12 @@
{
"type": "filament",
"filament_id": "OFLakOUI",
"setting_id": "yRKCiPMN6fxibcyg",
"name": "Generic PC @Sovol Zero",
"inherits": "Generic PC @System",
"renamed_from": "Sovol Zero PC",
"from": "system",
"setting_id": "yRKCiPMN6fxibcyg",
"instantiation": "true",
"inherits": "fdm_filament_pc",
"filament_flow_ratio": [
"0.98"
],
@@ -13,7 +14,16 @@
"21"
],
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.8 nozzle",
"Sovol Zero 1.0 nozzle",
"Sovol Zero 0.2 Hardened Steel nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
],
"nozzle_temperature_initial_layer": [
"290"
@@ -51,7 +61,9 @@
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": "0",
"dont_slow_down_outer_wall": [
"0"
],
"overhang_fan_speed": [
"20"
],
@@ -61,8 +73,19 @@
"temperature_vitrification": [
"60"
],
"additional_cooling_fan_speed": "0",
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "50",
"complete_print_exhaust_fan_speed": "50"
"additional_cooling_fan_speed": [
"0"
],
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"50"
],
"complete_print_exhaust_fan_speed": [
"50"
],
"filament_end_gcode": [
"; filament end gcode \n"
]
}
@@ -0,0 +1,116 @@
{
"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",
"filament_flow_ratio": [
"0.98"
],
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.048"
],
"filament_max_volumetric_speed": [
"15"
],
"nozzle_temperature_initial_layer": [
"265"
],
"nozzle_temperature": [
"250"
],
"nozzle_temperature_range_low": [
"230"
],
"nozzle_temperature_range_high": [
"280"
],
"hot_plate_temp": [
"85"
],
"hot_plate_temp_initial_layer": [
"85"
],
"fan_min_speed": [
"10"
],
"fan_max_speed": [
"40"
],
"fan_cooling_layer_time": [
"50"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"10"
],
"slow_down_min_speed": [
"10"
],
"overhang_fan_speed": [
"70"
],
"overhang_fan_threshold": [
"10%"
],
"temperature_vitrification": [
"60"
],
"close_fan_the_first_x_layers": [
"1"
],
"filament_retraction_length": [
"0.5"
],
"filament_z_hop": [
"0.4"
],
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"50"
],
"complete_print_exhaust_fan_speed": [
"50"
],
"compatible_printers": [
"Sovol Zero 0.2 Hardened Steel nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
],
"cool_plate_temp": [
"85"
],
"eng_plate_temp": [
"85"
],
"textured_plate_temp": [
"85"
],
"cool_plate_temp_initial_layer": [
"85"
],
"eng_plate_temp_initial_layer": [
"85"
],
"textured_plate_temp_initial_layer": [
"85"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -1,16 +1,21 @@
{
"type": "filament",
"filament_id": "OFYPdQJh",
"setting_id": "i4OW2eAtXOKdtVNj",
"name": "Generic PETG @Sovol Zero",
"inherits": "Generic PETG @System",
"renamed_from": "Sovol Zero PETG",
"from": "system",
"setting_id": "i4OW2eAtXOKdtVNj",
"instantiation": "true",
"inherits": "fdm_filament_pet",
"filament_flow_ratio": [
"1.0348"
],
"enable_pressure_advance": "1",
"pressure_advance": "0.046",
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.046"
],
"filament_max_volumetric_speed": [
"15"
],
@@ -68,10 +73,44 @@
"filament_z_hop": [
"0.4"
],
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "50",
"complete_print_exhaust_fan_speed": "50",
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"50"
],
"complete_print_exhaust_fan_speed": [
"50"
],
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.8 nozzle",
"Sovol Zero 1.0 nozzle"
],
"cool_plate_temp": [
"85"
],
"eng_plate_temp": [
"85"
],
"textured_plate_temp": [
"85"
],
"cool_plate_temp_initial_layer": [
"85"
],
"eng_plate_temp_initial_layer": [
"85"
],
"textured_plate_temp_initial_layer": [
"85"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -0,0 +1,110 @@
{
"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",
"filament_flow_ratio": [
"1.0348"
],
"filament_max_volumetric_speed": [
"21"
],
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.03"
],
"compatible_printers": [
"Sovol Zero 0.2 Hardened Steel nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature": [
"230"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"250"
],
"hot_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"fan_min_speed": [
"70"
],
"fan_max_speed": [
"100"
],
"fan_cooling_layer_time": [
"80"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"5"
],
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": [
"0"
],
"overhang_fan_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
],
"temperature_vitrification": [
"60"
],
"additional_cooling_fan_speed": [
"75%"
],
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"80%"
],
"complete_print_exhaust_fan_speed": [
"80%"
],
"cool_plate_temp": [
"60"
],
"eng_plate_temp": [
"60"
],
"textured_plate_temp": [
"60"
],
"cool_plate_temp_initial_layer": [
"55"
],
"eng_plate_temp_initial_layer": [
"55"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -1,21 +1,24 @@
{
"type": "filament",
"filament_id": "OFDSrzZ8",
"setting_id": "NNDerIjh7qtuh1I3",
"name": "Generic PLA @Sovol Zero",
"inherits": "Generic PLA @System",
"renamed_from": "Sovol Zero PLA Basic",
"from": "system",
"setting_id": "NNDerIjh7qtuh1I3",
"instantiation": "true",
"inherits": "fdm_filament_pla",
"filament_flow_ratio": [
"0.98"
],
"filament_max_volumetric_speed": [
"21"
"25"
],
"enable_pressure_advance": "1",
"pressure_advance": "0.032",
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.8 nozzle",
"Sovol Zero 1.0 nozzle"
],
"nozzle_temperature_initial_layer": [
"230"
@@ -24,28 +27,28 @@
"210"
],
"nozzle_temperature_range_low": [
"190"
"180"
],
"nozzle_temperature_range_high": [
"250"
"240"
],
"hot_plate_temp": [
"65"
"60"
],
"hot_plate_temp_initial_layer": [
"65"
"60"
],
"fan_min_speed": [
"70"
"100"
],
"fan_max_speed": [
"100"
],
"fan_cooling_layer_time": [
"80"
"60"
],
"full_fan_speed_layer": [
"3"
"2"
],
"slow_down_layer_time": [
"5"
@@ -53,18 +56,43 @@
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": "0",
"overhang_fan_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
"10%"
],
"temperature_vitrification": [
"50"
],
"filament_z_hop": [
"0.4"
],
"filament_retraction_length": [
"0.4"
],
"filament_diameter": [
"1.75"
],
"cool_plate_temp": [
"60"
],
"additional_cooling_fan_speed": "75%",
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "80%",
"complete_print_exhaust_fan_speed": "80%"
"eng_plate_temp": [
"60"
],
"textured_plate_temp": [
"60"
],
"cool_plate_temp_initial_layer": [
"55"
],
"eng_plate_temp_initial_layer": [
"55"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -0,0 +1,118 @@
{
"type": "filament",
"filament_id": "OFIUkWYN",
"setting_id": "MC2InZ7iKDjIGike",
"name": "Generic PLA SPEEDBENCHY @Sovol Zero",
"from": "system",
"instantiation": "true",
"inherits": "fdm_filament_pla",
"filament_flow_ratio": [
"1"
],
"filament_max_volumetric_speed": [
"50"
],
"compatible_printers": [
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature": [
"225"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"250"
],
"hot_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.032"
],
"fan_min_speed": [
"100"
],
"fan_max_speed": [
"100"
],
"fan_cooling_layer_time": [
"30"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"1.7"
],
"slow_down_min_speed": [
"40"
],
"overhang_fan_speed": [
"100"
],
"overhang_fan_threshold": [
"75%"
],
"additional_cooling_fan_speed": [
"100"
],
"filament_z_hop": [
"0"
],
"filament_retraction_length": [
"0.35"
],
"filament_retraction_speed": [
"90"
],
"filament_deretraction_speed": [
"90"
],
"filament_retract_before_wipe": [
"0%"
],
"filament_wipe_distance": [
"2"
],
"filament_retract_when_changing_layer": [
"0"
],
"filament_diameter": [
"1.75"
],
"cool_plate_temp": [
"60"
],
"eng_plate_temp": [
"60"
],
"textured_plate_temp": [
"60"
],
"cool_plate_temp_initial_layer": [
"55"
],
"eng_plate_temp_initial_layer": [
"55"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
],
"temperature_vitrification": [
"100"
]
}
@@ -0,0 +1,110 @@
{
"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",
"filament_flow_ratio": [
"0.98"
],
"filament_max_volumetric_speed": [
"15"
],
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.027"
],
"compatible_printers": [
"Sovol Zero 0.2 Hardened Steel nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature": [
"230"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"250"
],
"hot_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"fan_min_speed": [
"70"
],
"fan_max_speed": [
"100"
],
"fan_cooling_layer_time": [
"80"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"5"
],
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": [
"0"
],
"overhang_fan_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
],
"temperature_vitrification": [
"60"
],
"additional_cooling_fan_speed": [
"75%"
],
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"80%"
],
"complete_print_exhaust_fan_speed": [
"80%"
],
"cool_plate_temp": [
"60"
],
"eng_plate_temp": [
"60"
],
"textured_plate_temp": [
"60"
],
"cool_plate_temp_initial_layer": [
"55"
],
"eng_plate_temp_initial_layer": [
"55"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -1,27 +1,30 @@
{
"type": "filament",
"filament_id": "OFesA6rF",
"setting_id": "Se2yKerHRStYtWf5",
"name": "Generic PLA Silk @Sovol Zero",
"inherits": "Generic PLA Silk @System",
"renamed_from": "Sovol Zero PLA Silk",
"from": "system",
"setting_id": "Se2yKerHRStYtWf5",
"instantiation": "true",
"filament_multitool_ramming_flow": [
"20"
],
"filament_retraction_length": [
"nil"
],
"inherits": "fdm_filament_pla",
"filament_flow_ratio": [
"0.98"
],
"filament_max_volumetric_speed": [
"15"
],
"enable_pressure_advance": "1",
"pressure_advance": "0.029",
"enable_pressure_advance": [
"1"
],
"pressure_advance": [
"0.029"
],
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.8 nozzle",
"Sovol Zero 1.0 nozzle"
],
"nozzle_temperature_initial_layer": [
"245"
@@ -59,7 +62,9 @@
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": "0",
"dont_slow_down_outer_wall": [
"0"
],
"overhang_fan_speed": [
"100"
],
@@ -69,8 +74,43 @@
"temperature_vitrification": [
"60"
],
"additional_cooling_fan_speed": "75%",
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "80%",
"complete_print_exhaust_fan_speed": "80%"
"additional_cooling_fan_speed": [
"75%"
],
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"80%"
],
"complete_print_exhaust_fan_speed": [
"80%"
],
"filament_multitool_ramming_flow": [
"20"
],
"filament_retraction_length": [
"nil"
],
"cool_plate_temp": [
"60"
],
"eng_plate_temp": [
"60"
],
"textured_plate_temp": [
"60"
],
"cool_plate_temp_initial_layer": [
"55"
],
"eng_plate_temp_initial_layer": [
"55"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -1,11 +1,12 @@
{
"type": "filament",
"filament_id": "OFgbpcy9",
"setting_id": "MlY6WQ41FE8zDPSV",
"name": "Generic TPU @Sovol Zero",
"inherits": "Generic TPU @System",
"renamed_from": "Sovol Zero TPU",
"from": "system",
"setting_id": "MlY6WQ41FE8zDPSV",
"instantiation": "true",
"inherits": "fdm_filament_tpu",
"filament_flow_ratio": [
"0.98"
],
@@ -60,11 +61,55 @@
"filament_z_hop": [
"0.4"
],
"additional_cooling_fan_speed": "50",
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "100",
"complete_print_exhaust_fan_speed": "50",
"additional_cooling_fan_speed": [
"50"
],
"activate_air_filtration": [
"1"
],
"during_print_exhaust_fan_speed": [
"100"
],
"complete_print_exhaust_fan_speed": [
"50"
],
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.8 nozzle",
"Sovol Zero 1.0 nozzle",
"Sovol Zero 0.2 Hardened Steel nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
],
"cool_plate_temp": [
"60"
],
"eng_plate_temp": [
"60"
],
"textured_plate_temp": [
"60"
],
"cool_plate_temp_initial_layer": [
"55"
],
"eng_plate_temp_initial_layer": [
"55"
],
"textured_plate_temp_initial_layer": [
"55"
],
"filament_end_gcode": [
"; filament end gcode \n"
],
"filament_retraction_length": [
"nil"
],
"filament_start_gcode": [
"; filament start gcode\n"
]
}
@@ -1,77 +0,0 @@
{
"type": "filament",
"name": "Sovol Zero PETG HS Nozzle",
"inherits": "Generic PETG @System",
"from": "system",
"setting_id": "AfxHmpdOkMDJa2fk",
"filament_id": "OFymnal9",
"instantiation": "true",
"filament_flow_ratio": [
"0.98"
],
"enable_pressure_advance": "1",
"pressure_advance": "0.048",
"filament_max_volumetric_speed": [
"15"
],
"nozzle_temperature_initial_layer": [
"265"
],
"nozzle_temperature": [
"250"
],
"nozzle_temperature_range_low": [
"230"
],
"nozzle_temperature_range_high": [
"280"
],
"hot_plate_temp": [
"85"
],
"hot_plate_temp_initial_layer": [
"85"
],
"fan_min_speed": [
"10"
],
"fan_max_speed": [
"40"
],
"fan_cooling_layer_time": [
"50"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"10"
],
"slow_down_min_speed": [
"10"
],
"overhang_fan_speed": [
"70"
],
"overhang_fan_threshold": [
"10%"
],
"temperature_vitrification": [
"60"
],
"close_fan_the_first_x_layers": [
"1"
],
"filament_retraction_length": [
"0.5"
],
"filament_z_hop": [
"0.4"
],
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "50",
"complete_print_exhaust_fan_speed": "50",
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
]
}
@@ -1,70 +0,0 @@
{
"type": "filament",
"name": "Sovol Zero PLA Basic HS Nozzle",
"inherits": "Generic PLA @System",
"from": "system",
"setting_id": "i9wDnSEIrOBPbOZl",
"filament_id": "OFzB4uOs",
"instantiation": "true",
"filament_flow_ratio": [
"1.0348"
],
"filament_max_volumetric_speed": [
"21"
],
"enable_pressure_advance": "1",
"pressure_advance": "0.03",
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature": [
"230"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"250"
],
"hot_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"fan_min_speed": [
"70"
],
"fan_max_speed": [
"100"
],
"fan_cooling_layer_time": [
"80"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"5"
],
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": "0",
"overhang_fan_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
],
"temperature_vitrification": [
"60"
],
"additional_cooling_fan_speed": "75%",
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "80%",
"complete_print_exhaust_fan_speed": "80%"
}
@@ -1,70 +0,0 @@
{
"type": "filament",
"name": "Sovol Zero PLA Silk HS Nozzle",
"inherits": "Generic PLA @System",
"from": "system",
"setting_id": "XxEJBNFLRltR2Xwn",
"filament_id": "OFAO9A7J",
"instantiation": "true",
"filament_flow_ratio": [
"0.98"
],
"filament_max_volumetric_speed": [
"15"
],
"enable_pressure_advance": "1",
"pressure_advance": "0.027",
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
],
"nozzle_temperature_initial_layer": [
"245"
],
"nozzle_temperature": [
"230"
],
"nozzle_temperature_range_low": [
"190"
],
"nozzle_temperature_range_high": [
"250"
],
"hot_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"fan_min_speed": [
"70"
],
"fan_max_speed": [
"100"
],
"fan_cooling_layer_time": [
"80"
],
"full_fan_speed_layer": [
"3"
],
"slow_down_layer_time": [
"5"
],
"slow_down_min_speed": [
"10"
],
"dont_slow_down_outer_wall": "0",
"overhang_fan_speed": [
"100"
],
"overhang_fan_threshold": [
"50%"
],
"temperature_vitrification": [
"60"
],
"additional_cooling_fan_speed": "75%",
"activate_air_filtration": "1",
"during_print_exhaust_fan_speed": "80%",
"complete_print_exhaust_fan_speed": "80%"
}
@@ -0,0 +1,19 @@
{
"type": "machine",
"name": "Sovol Zero 0.2 Hardened Steel nozzle",
"inherits": "Sovol Zero 0.2 nozzle",
"from": "system",
"setting_id": "OkvEInEyzUUJzw9K",
"instantiation": "true",
"printer_model": "Sovol Zero",
"printer_variant": "0.2HS",
"nozzle_diameter": [
"0.2"
],
"default_filament_profile": [
"Generic PLA @Sovol Zero Hardened Steel nozzle"
],
"nozzle_type": [
"hardened_steel"
]
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
{
"type": "machine",
"name": "Sovol Zero 0.4 Hardened Steel nozzle",
"inherits": "Sovol Zero 0.4 nozzle",
"from": "system",
"setting_id": "RqwHKS8MYRdoeJPi",
"instantiation": "true",
"printer_model": "Sovol Zero",
"printer_variant": "0.4HS",
"nozzle_diameter": [
"0.4"
],
"default_filament_profile": [
"Generic PLA @Sovol Zero Hardened Steel nozzle"
],
"nozzle_type": [
"hardened_steel"
]
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
{
"type": "machine",
"name": "Sovol Zero 0.6 Hardened Steel nozzle",
"inherits": "Sovol Zero 0.6 nozzle",
"from": "system",
"setting_id": "s3N3FJkWrzOylFm8",
"instantiation": "true",
"printer_model": "Sovol Zero",
"printer_variant": "0.6HS",
"nozzle_diameter": [
"0.6"
],
"default_filament_profile": [
"Generic PLA @Sovol Zero Hardened Steel nozzle"
],
"nozzle_type": [
"hardened_steel"
]
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
{
"type": "machine",
"name": "Sovol Zero 0.8 Hardened Steel nozzle",
"inherits": "Sovol Zero 0.8 nozzle",
"from": "system",
"setting_id": "houacf8sQ3bLozqD",
"instantiation": "true",
"printer_model": "Sovol Zero",
"printer_variant": "0.8HS",
"nozzle_diameter": [
"0.8"
],
"default_filament_profile": [
"Generic PLA @Sovol Zero Hardened Steel nozzle"
],
"nozzle_type": [
"hardened_steel"
]
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
{
"type": "machine",
"name": "Sovol Zero 1.0 Hardened Steel nozzle",
"inherits": "Sovol Zero 1.0 nozzle",
"from": "system",
"setting_id": "sqlEiL0in8LSjmmn",
"instantiation": "true",
"printer_model": "Sovol Zero",
"printer_variant": "1.0HS",
"nozzle_diameter": [
"1.0"
],
"default_filament_profile": [
"Generic PLA @Sovol Zero Hardened Steel nozzle"
],
"nozzle_type": [
"hardened_steel"
]
}
File diff suppressed because one or more lines are too long
@@ -2,11 +2,11 @@
"type": "machine_model",
"name": "Sovol Zero",
"model_id": "Sovol-Zero",
"nozzle_diameter": "0.4",
"nozzle_diameter": "0.2;0.4;0.6;0.8;1.0;0.2HS;0.4HS;0.6HS;0.8HS;1.0HS",
"machine_tech": "FFF",
"family": "Sovol",
"bed_model": "sovol_zero_buildplate_model.stl",
"bed_texture": "sovol_zero_buildplate_texture.svg",
"hotend_model": "",
"default_materials": "Generic PLA @Sovol Zero;Sovol Zero PLA Basic HS Nozzle;Generic PLA Silk @Sovol Zero;Sovol Zero PLA Silk HS Nozzle;Generic ABS @Sovol Zero;Generic PETG @Sovol Zero;Sovol Zero PETG HS Nozzle;Generic TPU @Sovol Zero;Generic PC @Sovol Zero"
"default_materials": "Generic PLA @Sovol Zero;Generic PLA SPEEDBENCHY @Sovol Zero;Generic PLA @Sovol Zero Hardened Steel nozzle;Generic PLA Silk @Sovol Zero;Generic PLA Silk @Sovol Zero Hardened Steel nozzle;Generic ABS @Sovol Zero;Generic PETG @Sovol Zero;Generic PETG @Sovol Zero Hardened Steel nozzle;Generic TPU @Sovol Zero;Generic PC @Sovol Zero"
}
@@ -0,0 +1,36 @@
{
"type": "process",
"name": "0.06mm Quality @Sovol Zero 0.2 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "fWP7jaL7sJmmZ6QN",
"instantiation": "true",
"layer_height": "0.06",
"bottom_shell_layers": "8",
"bottom_shell_thickness": "0.8",
"bridge_speed": "30",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.21",
"line_width": "0.21",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.06",
"initial_layer_line_width": "0.3",
"infill_wall_overlap": "18",
"inner_wall_line_width": "0.22",
"wall_loops": "3",
"internal_solid_infill_line_width": "0.21",
"sparse_infill_line_width": "0.21",
"support_top_z_distance": "0.10",
"support_line_width": "0.21",
"tree_support_tip_diameter": "0.21",
"support_speed": "100",
"top_surface_line_width": "0.21",
"top_shell_layers": "8",
"top_shell_thickness": "1",
"compatible_printers": [
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.2 Hardened Steel nozzle"
]
}
@@ -0,0 +1,36 @@
{
"type": "process",
"name": "0.10mm Standard @Sovol Zero 0.2 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "Gql3487jsaTXyuYZ",
"instantiation": "true",
"layer_height": "0.10",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "50",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.22",
"line_width": "0.22",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.12",
"initial_layer_line_width": "0.3",
"infill_wall_overlap": "20",
"inner_wall_line_width": "0.22",
"wall_loops": "2",
"internal_solid_infill_line_width": "0.22",
"sparse_infill_line_width": "0.22",
"support_top_z_distance": "0.20",
"support_line_width": "0.22",
"tree_support_tip_diameter": "0.22",
"support_speed": "100",
"top_surface_line_width": "0.22",
"top_shell_layers": "4",
"top_shell_thickness": "1",
"compatible_printers": [
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.2 Hardened Steel nozzle"
]
}
@@ -0,0 +1,35 @@
{
"type": "process",
"setting_id": "CaEopiv2Wg6pQJjH",
"name": "0.12mm Quality @Sovol Zero 0.4 nozzle",
"from": "system",
"inherits": "fdm_process_zero",
"instantiation": "true",
"layer_height": "0.12",
"bottom_shell_layers": "8",
"bottom_shell_thickness": "0.8",
"bridge_speed": "30",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.42",
"line_width": "0.42",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.12",
"initial_layer_line_width": "0.6",
"sparse_infill_line_width": "0.42",
"infill_wall_overlap": "18",
"inner_wall_line_width": "0.44",
"wall_loops": "3",
"support_top_z_distance": "0.10",
"support_line_width": "0.42",
"tree_support_tip_diameter": "0.42",
"support_speed": "100",
"top_surface_line_width": "0.42",
"internal_solid_infill_line_width": "0.42",
"top_shell_layers": "8",
"compatible_printers": [
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle"
]
}
@@ -0,0 +1,36 @@
{
"type": "process",
"name": "0.14mm Fast @Sovol Zero 0.2 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "I9yoyCcGGTRrDoKu",
"instantiation": "true",
"layer_height": "0.14",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"bridge_speed": "60",
"outer_wall_acceleration": "22000",
"top_surface_acceleration": "22000",
"outer_wall_line_width": "0.24",
"line_width": "0.24",
"sparse_infill_density": "10%",
"inner_wall_acceleration": "28000",
"initial_layer_print_height": "0.14",
"initial_layer_line_width": "0.3",
"infill_wall_overlap": "20",
"inner_wall_line_width": "0.24",
"wall_loops": "2",
"internal_solid_infill_line_width": "0.24",
"sparse_infill_line_width": "0.24",
"support_top_z_distance": "0.30",
"support_line_width": "0.24",
"tree_support_tip_diameter": "0.24",
"support_speed": "120",
"top_surface_line_width": "0.24",
"top_shell_layers": "4",
"top_shell_thickness": "1",
"compatible_printers": [
"Sovol Zero 0.2 nozzle",
"Sovol Zero 0.2 Hardened Steel nozzle"
]
}
@@ -0,0 +1,34 @@
{
"type": "process",
"setting_id": "IfDpa3vM99D4ytny",
"name": "0.15mm Quality @Sovol Zero 0.6 nozzle",
"from": "system",
"inherits": "fdm_process_zero",
"instantiation": "true",
"layer_height": "0.15",
"bottom_shell_layers": "5",
"bottom_shell_thickness": "0.8",
"bridge_speed": "30",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.63",
"line_width": "0.63",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_line_width": "0.9",
"sparse_infill_line_width": "0.63",
"infill_wall_overlap": "18",
"inner_wall_line_width": "0.66",
"wall_loops": "3",
"support_top_z_distance": "0.15",
"support_line_width": "0.63",
"tree_support_tip_diameter": "0.63",
"support_speed": "100",
"top_surface_line_width": "0.63",
"top_shell_layers": "5",
"internal_solid_infill_line_width": "0.63",
"compatible_printers": [
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle"
]
}
@@ -0,0 +1,42 @@
{
"type": "process",
"name": "0.20mm Quality @Sovol Zero 0.8 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "MSxikpQZNYdoBynZ",
"instantiation": "true",
"layer_height": "0.20",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "30",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.84",
"line_width": "0.84",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.36",
"initial_layer_line_width": "1.2",
"sparse_infill_line_width": "0.84",
"infill_wall_overlap": "18",
"inner_wall_line_width": "0.88",
"wall_loops": "3",
"support_top_z_distance": "0.20",
"support_line_width": "0.84",
"tree_support_tip_diameter": "0.84",
"support_speed": "100",
"top_surface_line_width": "0.84",
"top_shell_layers": "4",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "50%",
"internal_solid_infill_speed": "200",
"internal_solid_infill_line_width": "0.84",
"top_surface_speed": "200",
"gap_infill_speed": "200",
"sparse_infill_speed": "500",
"compatible_printers": [
"Sovol Zero 0.8 nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle"
]
}
@@ -1,141 +1,36 @@
{
"type": "process",
"name": "0.20mm Standard @Sovol Zero 0.4 nozzle",
"inherits": "fdm_process_common",
"from": "system",
"setting_id": "ShJTVnJ492No1j2j",
"name": "0.20mm Standard @Sovol Zero 0.4 nozzle",
"from": "system",
"inherits": "fdm_process_zero",
"instantiation": "true",
"reduce_crossing_wall": "1",
"max_travel_detour_distance": "100%",
"layer_height": "0.20",
"bottom_surface_pattern": "monotonic",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"bridge_flow": "1.2",
"internal_bridge_flow": "1.2",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "50",
"internal_bridge_speed": "200",
"brim_type": "auto_brim",
"brim_width": "5",
"brim_object_gap": "0",
"compatible_printers_condition": "",
"print_sequence": "by layer",
"default_acceleration": "40000",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"bridge_no_support": "0",
"draft_shield": "disabled",
"elefant_foot_compensation": "0.1",
"enable_arc_fitting": "0",
"exclude_object": "1",
"outer_wall_line_width": "0.4",
"wall_infill_order": "inner wall/outer wall/infill",
"line_width": "0.4",
"infill_direction": "45",
"sparse_infill_density": "10%",
"sparse_infill_pattern": "grid",
"internal_solid_infill_acceleration": "50%",
"initial_layer_acceleration": "1000",
"initial_solid_infill_acceleration": "3000",
"travel_acceleration": "40000",
"outer_wall_line_width": "0.44",
"line_width": "0.44",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"outer_wall_jerk": "5",
"inner_wall_jerk": "5",
"infill_jerk": "5",
"top_surface_jerk": "5",
"initial_layer_jerk": "5",
"travel_jerk": "5",
"initial_layer_line_width": "0.42",
"initial_layer_print_height": "0.25",
"infill_combination": "0",
"sparse_infill_line_width": "0.45",
"infill_wall_overlap": "15%",
"interface_shells": "0",
"ironing_flow": "15%",
"ironing_spacing": "0.25",
"ironing_speed": "15",
"ironing_type": "no ironing",
"reduce_infill_retraction": "1",
"filename_format": "{printer_model}_{input_filename_base}_{filament_type[0]}_{layer_height}_{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": "20",
"inner_wall_line_width": "0.4",
"initial_layer_print_height": "0.24",
"initial_layer_line_width": "0.6",
"sparse_infill_line_width": "0.44",
"infill_wall_overlap": "20",
"ironing_speed": "100",
"inner_wall_line_width": "0.44",
"wall_loops": "2",
"print_settings_id": "",
"raft_layers": "0",
"seam_position": "aligned",
"skirt_distance": "0.8",
"skirt_height": "1",
"skirt_loops": "1",
"minimum_sparse_infill_area": "15",
"internal_solid_infill_line_width": "0.45",
"spiral_mode": "0",
"standby_temperature_delta": "-5",
"enable_support": "0",
"resolution": "0.012",
"support_type": "tree(auto)",
"support_style": "default",
"support_on_build_plate_only": "0",
"support_top_z_distance": "0.235",
"support_bottom_z_distance": "0.235",
"support_filament": "0",
"support_line_width": "0.45",
"support_interface_loop_pattern": "0",
"support_interface_filament": "0",
"support_interface_top_layers": "5",
"support_interface_bottom_layers": "-1",
"support_interface_spacing": "0.2",
"support_bottom_interface_spacing": "0.2",
"support_interface_speed": "100%",
"support_interface_pattern": "grid",
"support_base_pattern": "rectilinear",
"support_base_pattern_spacing": "3.5",
"support_speed": "100",
"support_threshold_angle": "20",
"support_object_xy_distance": "0.35",
"tree_support_branch_angle": "40",
"tree_support_wall_count": "0",
"detect_thin_wall": "1",
"top_surface_pattern": "monotonic",
"top_surface_line_width": "0.38",
"support_top_z_distance": "0.20",
"support_line_width": "0.44",
"tree_support_tip_diameter": "0.44",
"support_speed": "60",
"top_surface_line_width": "0.44",
"top_shell_layers": "4",
"top_shell_thickness": "1",
"initial_layer_speed": "55",
"initial_layer_infill_speed": "105",
"initial_layer_travel_speed": "60%",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "50%",
"internal_solid_infill_speed": "200",
"top_surface_speed": "200",
"gap_infill_speed": "200",
"sparse_infill_speed": "500",
"accel_to_decel_enable": "1",
"accel_to_decel_factor": "25%",
"travel_speed": "1000",
"enable_prime_tower": "1",
"wipe_tower_no_sparse_layers": "0",
"prime_tower_width": "60",
"xy_hole_compensation": "0",
"xy_contour_compensation": "0",
"bridge_acceleration": "50%",
"seam_gap": "10%",
"precise_outer_wall": "1",
"wall_generator": "classic",
"gcode_label_objects": "1",
"slow_down_layers": "3",
"top_solid_infill_flow_ratio": "0.9",
"only_one_wall_top": "1",
"wall_loop_direction": "clockwise",
"top_bottom_infill_wall_overlap": "25%",
"filter_out_gap_fill": "0",
"detect_narrow_internal_solid_infill": "1",
"thick_bridges": "1",
"bridge_angle": "0",
"internal_solid_infill_line_width": "0.44",
"compatible_printers": [
"Sovol Zero 0.4 nozzle"
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle"
]
}
@@ -0,0 +1,79 @@
{
"type": "process",
"name": "0.25mm Quality @Sovol Zero 1.0 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "JUmnFOoEMJrbWCN9",
"instantiation": "true",
"layer_height": "0.25",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "30",
"internal_bridge_speed": "200",
"default_acceleration": "40000",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "1.05",
"line_width": "1.05",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.45",
"initial_layer_line_width": "1.5",
"infill_combination": "0",
"sparse_infill_line_width": "1.05",
"infill_wall_overlap": "18",
"interface_shells": "0",
"ironing_flow": "15%",
"ironing_spacing": "0.25",
"ironing_speed": "15",
"ironing_type": "no ironing",
"filename_format": "{input_filename_base}_{nozzle_diameter[0]}n_{filament_type[0]}_{layer_height}_{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": "20",
"inner_wall_line_width": "1.1",
"wall_loops": "3",
"print_settings_id": "",
"raft_layers": "0",
"seam_position": "aligned",
"skirt_distance": "0.8",
"skirt_height": "1",
"skirt_loops": "1",
"minimum_sparse_infill_area": "15",
"internal_solid_infill_line_width": "1.05",
"spiral_mode": "0",
"standby_temperature_delta": "-5",
"enable_support": "0",
"resolution": "0.012",
"support_type": "tree(auto)",
"support_style": "snug",
"support_on_build_plate_only": "0",
"support_top_z_distance": "0.25",
"support_bottom_z_distance": "0.235",
"support_filament": "0",
"support_line_width": "1.05",
"tree_support_tip_diameter": "1.05",
"support_interface_loop_pattern": "0",
"support_interface_filament": "0",
"support_interface_top_layers": "5",
"support_interface_bottom_layers": "-1",
"support_interface_spacing": "0.2",
"support_bottom_interface_spacing": "0.2",
"support_interface_speed": "100%",
"support_interface_pattern": "grid",
"support_base_pattern": "rectilinear",
"support_base_pattern_spacing": "3.5",
"support_speed": "100",
"support_threshold_angle": "50",
"support_object_xy_distance": "0.35",
"tree_support_branch_angle": "40",
"top_surface_line_width": "1.05",
"top_shell_layers": "4",
"top_shell_thickness": "1",
"compatible_printers": [
"Sovol Zero 1.0 nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
]
}
@@ -0,0 +1,85 @@
{
"type": "process",
"setting_id": "oFrWcSxmad1b6sD4",
"name": "0.25mm SPEEDBENCHY @Sovol Zero 0.4 nozzle",
"from": "system",
"inherits": "fdm_process_zero",
"instantiation": "true",
"layer_height": "0.25",
"initial_layer_print_height": "0.25",
"line_width": "0.5",
"initial_layer_line_width": "0.5",
"outer_wall_line_width": "0.5",
"inner_wall_line_width": "0.5",
"top_surface_line_width": "0.55",
"internal_solid_infill_line_width": "0.55",
"sparse_infill_line_width": "0.55",
"support_line_width": "0.5",
"tree_support_tip_diameter": "0.5",
"wall_loops": "2",
"top_shell_layers": "3",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"sparse_infill_density": "10%",
"sparse_infill_pattern": "grid",
"bottom_solid_infill_flow_ratio": "1.2",
"top_solid_infill_flow_ratio": "1.4",
"bridge_flow": "1",
"internal_bridge_flow": "1",
"bridge_speed": "250",
"internal_bridge_speed": "250",
"bridge_acceleration": "100%",
"thick_bridges": "0",
"thick_internal_bridges": "0",
"brim_type": "outer_only",
"brim_width": "1",
"brim_object_gap": "0",
"filter_out_gap_fill": "13",
"gap_fill_target": "nowhere",
"min_width_top_surface": "200%",
"minimum_sparse_infill_area": "0",
"infill_direction": "0",
"solid_infill_direction": "0",
"infill_wall_overlap": "15%",
"reduce_crossing_wall": "0",
"skirt_loops": "0",
"only_one_wall_top": "1",
"slow_down_layers": "1",
"wall_direction": "cw",
"initial_layer_speed": "300",
"initial_layer_infill_speed": "300",
"initial_layer_travel_speed": "100%",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "100%",
"internal_solid_infill_speed": "400",
"top_surface_speed": "300",
"gap_infill_speed": "350",
"sparse_infill_speed": "500",
"support_speed": "100",
"travel_speed": "1200",
"default_acceleration": "40000",
"initial_layer_acceleration": "20000",
"outer_wall_acceleration": "40000",
"inner_wall_acceleration": "40000",
"top_surface_acceleration": "20000",
"internal_solid_infill_acceleration": "100%",
"travel_acceleration": "40000",
"accel_to_decel_factor": "50%",
"outer_wall_jerk": "20",
"inner_wall_jerk": "20",
"infill_jerk": "20",
"top_surface_jerk": "20",
"initial_layer_jerk": "20",
"travel_jerk": "20",
"overhang_1_4_speed": "160",
"overhang_2_4_speed": "100",
"overhang_3_4_speed": "60",
"overhang_4_4_speed": "40",
"support_top_z_distance": "0.235",
"support_bottom_z_distance": "0.235",
"compatible_printers": [
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle"
]
}
@@ -0,0 +1,39 @@
{
"type": "process",
"name": "0.28mm Fast @Sovol Zero 0.4 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "1VoML2LGDk4TJgLI",
"instantiation": "true",
"layer_height": "0.28",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"bridge_speed": "60",
"outer_wall_acceleration": "22000",
"top_surface_acceleration": "22000",
"outer_wall_line_width": "0.48",
"line_width": "0.48",
"sparse_infill_density": "10%",
"inner_wall_acceleration": "28000",
"initial_layer_print_height": "0.28",
"initial_layer_line_width": "0.6",
"sparse_infill_line_width": "0.48",
"inner_wall_line_width": "0.48",
"internal_solid_infill_line_width": "0.48",
"support_top_z_distance": "0.30",
"support_line_width": "0.48",
"tree_support_tip_diameter": "0.48",
"support_speed": "120",
"top_surface_line_width": "0.48",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "50%",
"internal_solid_infill_speed": "200",
"top_surface_speed": "200",
"gap_infill_speed": "200",
"sparse_infill_speed": "500",
"compatible_printers": [
"Sovol Zero 0.4 nozzle",
"Sovol Zero 0.4 Hardened Steel nozzle"
]
}
@@ -0,0 +1,35 @@
{
"type": "process",
"setting_id": "lTAs2USEP8D749K7",
"name": "0.30mm Standard @Sovol Zero 0.6 nozzle",
"from": "system",
"inherits": "fdm_process_zero",
"instantiation": "true",
"layer_height": "0.30",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "50",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.66",
"line_width": "0.66",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.36",
"initial_layer_line_width": "0.9",
"sparse_infill_line_width": "0.66",
"infill_wall_overlap": "20",
"inner_wall_line_width": "0.66",
"wall_loops": "2",
"support_top_z_distance": "0.30",
"support_line_width": "0.66",
"tree_support_tip_diameter": "0.66",
"support_speed": "100",
"top_surface_line_width": "0.66",
"top_shell_layers": "4",
"internal_solid_infill_line_width": "0.66",
"compatible_printers": [
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle"
]
}
@@ -0,0 +1,42 @@
{
"type": "process",
"name": "0.40mm Standard @Sovol Zero 0.8 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "8x4CsuqroC9HOdAN",
"instantiation": "true",
"layer_height": "0.40",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "50",
"outer_wall_acceleration": "10000",
"top_surface_acceleration": "5000",
"outer_wall_line_width": "0.88",
"line_width": "0.88",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "12000",
"initial_layer_print_height": "0.48",
"initial_layer_line_width": "1.2",
"sparse_infill_line_width": "0.88",
"infill_wall_overlap": "20",
"inner_wall_line_width": "0.88",
"wall_loops": "2",
"support_top_z_distance": "0.40",
"support_line_width": "0.88",
"tree_support_tip_diameter": "0.88",
"support_speed": "100",
"top_surface_line_width": "0.88",
"top_shell_layers": "4",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "50%",
"internal_solid_infill_speed": "200",
"top_surface_speed": "200",
"gap_infill_speed": "200",
"sparse_infill_speed": "500",
"internal_solid_infill_line_width": "0.88",
"compatible_printers": [
"Sovol Zero 0.8 nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle"
]
}
@@ -0,0 +1,39 @@
{
"type": "process",
"name": "0.42mm Fast @Sovol Zero 0.6 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "illqJAnGiA2pY0hw",
"instantiation": "true",
"layer_height": "0.42",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"bridge_speed": "60",
"outer_wall_acceleration": "22000",
"top_surface_acceleration": "22000",
"outer_wall_line_width": "0.72",
"line_width": "0.72",
"sparse_infill_density": "10%",
"inner_wall_acceleration": "28000",
"initial_layer_print_height": "0.42",
"initial_layer_line_width": "0.9",
"sparse_infill_line_width": "0.72",
"inner_wall_line_width": "0.72",
"internal_solid_infill_line_width": "0.72",
"support_top_z_distance": "0.45",
"support_line_width": "0.72",
"tree_support_tip_diameter": "0.72",
"support_speed": "120",
"top_surface_line_width": "0.72",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "50%",
"internal_solid_infill_speed": "200",
"top_surface_speed": "200",
"gap_infill_speed": "200",
"sparse_infill_speed": "500",
"compatible_printers": [
"Sovol Zero 0.6 nozzle",
"Sovol Zero 0.6 Hardened Steel nozzle"
]
}
@@ -0,0 +1,87 @@
{
"type": "process",
"name": "0.50mm Standard @Sovol Zero 1.0 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "E5K55O4RkMyYCAlt",
"instantiation": "true",
"layer_height": "0.50",
"bottom_shell_layers": "4",
"bottom_shell_thickness": "0.8",
"bridge_speed": "45",
"internal_bridge_speed": "200",
"default_acceleration": "22000",
"outer_wall_acceleration": "16000",
"top_surface_acceleration": "16000",
"outer_wall_line_width": "1.1",
"line_width": "1.1",
"sparse_infill_density": "15%",
"inner_wall_acceleration": "22000",
"initial_layer_print_height": "0.60",
"initial_layer_line_width": "1.5",
"infill_combination": "0",
"sparse_infill_line_width": "1.1",
"infill_wall_overlap": "20",
"interface_shells": "0",
"ironing_flow": "15%",
"ironing_spacing": "0.25",
"ironing_speed": "15",
"ironing_type": "no ironing",
"filename_format": "{input_filename_base}_{nozzle_diameter[0]}n_{filament_type[0]}_{layer_height}_{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": "20",
"inner_wall_line_width": "1.1",
"wall_loops": "2",
"print_settings_id": "",
"raft_layers": "0",
"seam_position": "aligned",
"skirt_distance": "0.8",
"skirt_height": "1",
"skirt_loops": "1",
"minimum_sparse_infill_area": "15",
"internal_solid_infill_line_width": "1.1",
"spiral_mode": "0",
"standby_temperature_delta": "-5",
"enable_support": "0",
"resolution": "0.012",
"support_type": "tree(auto)",
"support_style": "snug",
"support_on_build_plate_only": "0",
"support_top_z_distance": "0.50",
"support_bottom_z_distance": "0.235",
"support_filament": "0",
"support_line_width": "1.1",
"tree_support_tip_diameter": "1.1",
"support_interface_loop_pattern": "0",
"support_interface_filament": "0",
"support_interface_top_layers": "5",
"support_interface_bottom_layers": "-1",
"support_interface_spacing": "0.2",
"support_bottom_interface_spacing": "0.2",
"support_interface_speed": "100%",
"support_interface_pattern": "grid",
"support_base_pattern": "rectilinear",
"support_base_pattern_spacing": "3.5",
"support_speed": "60",
"support_threshold_angle": "50",
"support_object_xy_distance": "0.35",
"tree_support_branch_angle": "40",
"top_surface_line_width": "1.1",
"top_shell_layers": "4",
"top_shell_thickness": "1",
"outer_wall_speed": "30",
"inner_wall_speed": "45",
"small_perimeter_speed": "45",
"internal_solid_infill_speed": "45",
"top_surface_speed": "35",
"gap_infill_speed": "35",
"sparse_infill_speed": "70",
"travel_acceleration": "38000",
"compatible_printers": [
"Sovol Zero 1.0 nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
]
}
@@ -0,0 +1,40 @@
{
"type": "process",
"name": "0.56mm Fast @Sovol Zero 0.8 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "g9PPRM4FLMwjMUfy",
"instantiation": "true",
"layer_height": "0.56",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"bridge_speed": "60",
"default_acceleration": "28000",
"outer_wall_acceleration": "22000",
"top_surface_acceleration": "22000",
"outer_wall_line_width": "0.96",
"line_width": "0.96",
"sparse_infill_density": "10%",
"inner_wall_acceleration": "28000",
"initial_layer_print_height": "0.56",
"initial_layer_line_width": "1.2",
"sparse_infill_line_width": "0.96",
"inner_wall_line_width": "0.96",
"internal_solid_infill_line_width": "0.96",
"support_top_z_distance": "0.60",
"support_line_width": "0.96",
"tree_support_tip_diameter": "0.96",
"top_surface_line_width": "0.96",
"top_shell_layers": "4",
"outer_wall_speed": "35",
"inner_wall_speed": "55",
"small_perimeter_speed": "60",
"internal_solid_infill_speed": "55",
"top_surface_speed": "40",
"gap_infill_speed": "40",
"sparse_infill_speed": "80",
"compatible_printers": [
"Sovol Zero 0.8 nozzle",
"Sovol Zero 0.8 Hardened Steel nozzle"
]
}
@@ -0,0 +1,33 @@
{
"type": "process",
"name": "0.70mm Fast @Sovol Zero 1.0 nozzle",
"inherits": "fdm_process_zero",
"from": "system",
"setting_id": "fW5KJBVndgQE868q",
"instantiation": "true",
"layer_height": "0.70",
"bottom_shell_layers": "3",
"bottom_shell_thickness": "0",
"bridge_speed": "60",
"outer_wall_acceleration": "22000",
"top_surface_acceleration": "22000",
"outer_wall_line_width": "1.2",
"line_width": "1.2",
"sparse_infill_density": "10%",
"inner_wall_acceleration": "28000",
"initial_layer_print_height": "0.70",
"initial_layer_line_width": "1.5",
"sparse_infill_line_width": "1.2",
"inner_wall_line_width": "1.2",
"internal_solid_infill_line_width": "1.2",
"support_top_z_distance": "0.75",
"support_line_width": "1.2",
"tree_support_tip_diameter": "1.2",
"support_speed": "120",
"top_surface_line_width": "1.2",
"top_shell_layers": "3",
"compatible_printers": [
"Sovol Zero 1.0 nozzle",
"Sovol Zero 1.0 Hardened Steel nozzle"
]
}
@@ -0,0 +1,73 @@
{
"type": "process",
"name": "fdm_process_zero",
"inherits": "fdm_process_common",
"from": "system",
"instantiation": "false",
"reduce_crossing_wall": "1",
"max_travel_detour_distance": "10",
"bottom_surface_pattern": "monotonic",
"bridge_flow": "1.2",
"internal_bridge_flow": "1.2",
"brim_type": "auto_brim",
"brim_width": "5",
"brim_object_gap": "0",
"print_sequence": "by layer",
"bridge_no_support": "0",
"draft_shield": "disabled",
"elefant_foot_compensation": "0.1",
"enable_arc_fitting": "0",
"exclude_object": "1",
"wall_infill_order": "inner wall/outer wall/infill",
"infill_direction": "45",
"sparse_infill_pattern": "grid",
"internal_solid_infill_acceleration": "50%",
"initial_layer_acceleration": "1000",
"travel_acceleration": "40000",
"outer_wall_jerk": "5",
"inner_wall_jerk": "5",
"infill_jerk": "5",
"top_surface_jerk": "5",
"initial_layer_jerk": "5",
"travel_jerk": "5",
"tree_support_wall_count": "0",
"reduce_infill_retraction": "1",
"detect_thin_wall": "1",
"top_surface_pattern": "monotonic",
"initial_layer_speed": "55",
"initial_layer_infill_speed": "105",
"initial_layer_travel_speed": "60%",
"outer_wall_speed": "350",
"inner_wall_speed": "400",
"small_perimeter_speed": "50%",
"internal_solid_infill_speed": "200",
"top_surface_speed": "200",
"gap_infill_speed": "200",
"sparse_infill_speed": "500",
"accel_to_decel_enable": "1",
"accel_to_decel_factor": "25%",
"travel_speed": "1000",
"enable_prime_tower": "0",
"wipe_tower_no_sparse_layers": "0",
"prime_tower_width": "60",
"xy_hole_compensation": "0",
"xy_contour_compensation": "0",
"bridge_acceleration": "50%",
"seam_gap": "10%",
"precise_outer_wall": "1",
"wall_generator": "classic",
"gcode_label_objects": "1",
"slow_down_layers": "3",
"top_solid_infill_flow_ratio": "0.9",
"only_one_wall_top": "1",
"top_bottom_infill_wall_overlap": "25%",
"filter_out_gap_fill": "0",
"detect_narrow_internal_solid_infill": "1",
"thick_bridges": "1",
"bridge_angle": "0",
"initial_layer_line_width": "150%",
"default_acceleration": "40000",
"compatible_printers": [],
"internal_bridge_speed": "150",
"filename_format": "{input_filename_base}_{nozzle_diameter[0]}n_{filament_type[0]}_{layer_height}_{print_time}.gcode"
}
+137 -1
View File
@@ -1,12 +1,60 @@
{
"name": "Wanhao",
"version": "02.04.00.02",
"version": "02.04.00.03",
"force_update": "0",
"description": "Wanhao configurations",
"machine_model_list": [
{
"name": "Wanhao D12-300",
"sub_path": "machine/Wanhao D12-300.json"
},
{
"name": "Wanhao D9-300 MK1",
"sub_path": "machine/Wanhao D9-300 MK1.json"
},
{
"name": "Wanhao D9-300 MK1 BLTouch kit",
"sub_path": "machine/Wanhao D9-300 MK1 BLTouch kit.json"
},
{
"name": "Wanhao D9-300 MK2",
"sub_path": "machine/Wanhao D9-300 MK2.json"
},
{
"name": "Wanhao D9-300 MK3",
"sub_path": "machine/Wanhao D9-300 MK3.json"
},
{
"name": "Wanhao D9-400 MK1",
"sub_path": "machine/Wanhao D9-400 MK1.json"
},
{
"name": "Wanhao D9-400 MK1 BLTouch kit",
"sub_path": "machine/Wanhao D9-400 MK1 BLTouch kit.json"
},
{
"name": "Wanhao D9-400 MK2",
"sub_path": "machine/Wanhao D9-400 MK2.json"
},
{
"name": "Wanhao D9-400 MK3",
"sub_path": "machine/Wanhao D9-400 MK3.json"
},
{
"name": "Wanhao D9-500 MK1",
"sub_path": "machine/Wanhao D9-500 MK1.json"
},
{
"name": "Wanhao D9-500 MK1 BLTouch kit",
"sub_path": "machine/Wanhao D9-500 MK1 BLTouch kit.json"
},
{
"name": "Wanhao D9-500 MK2",
"sub_path": "machine/Wanhao D9-500 MK2.json"
},
{
"name": "Wanhao D9-500 MK3",
"sub_path": "machine/Wanhao D9-500 MK3.json"
}
],
"process_list": [
@@ -33,6 +81,38 @@
{
"name": "0.24mm Draft @Wanhao D12-300",
"sub_path": "process/0.24mm Draft @Wanhao D12-300.json"
},
{
"name": "fdm_process_wanhao_d9_common",
"sub_path": "process/fdm_process_wanhao_d9_common.json"
},
{
"name": "0.12mm Fine @Wanhao D9",
"sub_path": "process/0.12mm Fine @Wanhao D9.json"
},
{
"name": "0.20mm Standard @Wanhao D9",
"sub_path": "process/0.20mm Standard @Wanhao D9.json"
},
{
"name": "0.28mm Draft @Wanhao D9",
"sub_path": "process/0.28mm Draft @Wanhao D9.json"
},
{
"name": "fdm_process_wanhao_d9_mk1_common",
"sub_path": "process/fdm_process_wanhao_d9_mk1_common.json"
},
{
"name": "0.12mm Fine @Wanhao D9 MK1",
"sub_path": "process/0.12mm Fine @Wanhao D9 MK1.json"
},
{
"name": "0.20mm Standard @Wanhao D9 MK1",
"sub_path": "process/0.20mm Standard @Wanhao D9 MK1.json"
},
{
"name": "0.28mm Draft @Wanhao D9 MK1",
"sub_path": "process/0.28mm Draft @Wanhao D9 MK1.json"
}
],
"filament_list": [],
@@ -48,6 +128,62 @@
{
"name": "Wanhao D12-300 0.4 nozzle",
"sub_path": "machine/Wanhao D12-300 0.4 nozzle.json"
},
{
"name": "fdm_wanhao_d9_common",
"sub_path": "machine/fdm_wanhao_d9_common.json"
},
{
"name": "Wanhao D9-300 MK1 BLTouch kit 0.4 nozzle",
"sub_path": "machine/Wanhao D9-300 MK1 BLTouch kit 0.4 nozzle.json"
},
{
"name": "Wanhao D9-300 MK2 0.4 nozzle",
"sub_path": "machine/Wanhao D9-300 MK2 0.4 nozzle.json"
},
{
"name": "Wanhao D9-300 MK3 0.4 nozzle",
"sub_path": "machine/Wanhao D9-300 MK3 0.4 nozzle.json"
},
{
"name": "Wanhao D9-400 MK1 BLTouch kit 0.4 nozzle",
"sub_path": "machine/Wanhao D9-400 MK1 BLTouch kit 0.4 nozzle.json"
},
{
"name": "Wanhao D9-400 MK2 0.4 nozzle",
"sub_path": "machine/Wanhao D9-400 MK2 0.4 nozzle.json"
},
{
"name": "Wanhao D9-400 MK3 0.4 nozzle",
"sub_path": "machine/Wanhao D9-400 MK3 0.4 nozzle.json"
},
{
"name": "Wanhao D9-500 MK1 BLTouch kit 0.4 nozzle",
"sub_path": "machine/Wanhao D9-500 MK1 BLTouch kit 0.4 nozzle.json"
},
{
"name": "Wanhao D9-500 MK2 0.4 nozzle",
"sub_path": "machine/Wanhao D9-500 MK2 0.4 nozzle.json"
},
{
"name": "Wanhao D9-500 MK3 0.4 nozzle",
"sub_path": "machine/Wanhao D9-500 MK3 0.4 nozzle.json"
},
{
"name": "fdm_wanhao_d9_mk1_common",
"sub_path": "machine/fdm_wanhao_d9_mk1_common.json"
},
{
"name": "Wanhao D9-300 MK1 0.4 nozzle",
"sub_path": "machine/Wanhao D9-300 MK1 0.4 nozzle.json"
},
{
"name": "Wanhao D9-400 MK1 0.4 nozzle",
"sub_path": "machine/Wanhao D9-400 MK1 0.4 nozzle.json"
},
{
"name": "Wanhao D9-500 MK1 0.4 nozzle",
"sub_path": "machine/Wanhao D9-500 MK1 0.4 nozzle.json"
}
]
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-300 MK1 0.4 nozzle",
"inherits": "fdm_wanhao_d9_mk1_common",
"from": "system",
"setting_id": "MXNRpMDaVXj2xUx0",
"instantiation": "true",
"printer_model": "Wanhao D9-300 MK1",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"300x0",
"300x300",
"0x300"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9 MK1"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-300 MK1 BLTouch kit 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "rq6cPs92KgrUyZrn",
"instantiation": "true",
"printer_model": "Wanhao D9-300 MK1 BLTouch kit",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"300x0",
"300x300",
"0x300"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-300 MK1 BLTouch kit",
"model_id": "Wanhao-D9-300-MK1u2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-300 MK1",
"model_id": "Wanhao-D9-300-MK1",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-300 MK2 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "w3Cin9es1Jfx0dmR",
"instantiation": "true",
"printer_model": "Wanhao D9-300 MK2",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"300x0",
"300x300",
"0x300"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-300 MK2",
"model_id": "Wanhao-D9-300-MK2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-300 MK3 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "acFQWZqlt4QSgBPv",
"instantiation": "true",
"printer_model": "Wanhao D9-300 MK3",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"300x0",
"300x300",
"0x300"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-300 MK3",
"model_id": "Wanhao-D9-300-MK3",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-400 MK1 0.4 nozzle",
"inherits": "fdm_wanhao_d9_mk1_common",
"from": "system",
"setting_id": "DGSNE3AbmlBBG5PY",
"instantiation": "true",
"printer_model": "Wanhao D9-400 MK1",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"400x0",
"400x400",
"0x400"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9 MK1"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-400 MK1 BLTouch kit 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "WcKY7v24ewtzPfnU",
"instantiation": "true",
"printer_model": "Wanhao D9-400 MK1 BLTouch kit",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"400x0",
"400x400",
"0x400"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-400 MK1 BLTouch kit",
"model_id": "Wanhao-D9-400-MK1u2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-400 MK1",
"model_id": "Wanhao-D9-400-MK1",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-400 MK2 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "jn1FEJFeN7S2gEbD",
"instantiation": "true",
"printer_model": "Wanhao D9-400 MK2",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"400x0",
"400x400",
"0x400"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-400 MK2",
"model_id": "Wanhao-D9-400-MK2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-400 MK3 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "2kFyH1E3tqMWtDmG",
"instantiation": "true",
"printer_model": "Wanhao D9-400 MK3",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"400x0",
"400x400",
"0x400"
],
"printable_height": "400",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-400 MK3",
"model_id": "Wanhao-D9-400-MK3",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-500 MK1 0.4 nozzle",
"inherits": "fdm_wanhao_d9_mk1_common",
"from": "system",
"setting_id": "nj0TfnDKHb4wFX1R",
"instantiation": "true",
"printer_model": "Wanhao D9-500 MK1",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"500x0",
"500x500",
"0x500"
],
"printable_height": "500",
"default_print_profile": "0.20mm Standard @Wanhao D9 MK1"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-500 MK1 BLTouch kit 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "Hmrnlh6pJzdO2dIJ",
"instantiation": "true",
"printer_model": "Wanhao D9-500 MK1 BLTouch kit",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"500x0",
"500x500",
"0x500"
],
"printable_height": "500",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-500 MK1 BLTouch kit",
"model_id": "Wanhao-D9-500-MK1u2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-500 MK1",
"model_id": "Wanhao-D9-500-MK1",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-500 MK2 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "g2GSmhWJLFDwqzFI",
"instantiation": "true",
"printer_model": "Wanhao D9-500 MK2",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"500x0",
"500x500",
"0x500"
],
"printable_height": "500",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-500 MK2",
"model_id": "Wanhao-D9-500-MK2",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,20 @@
{
"type": "machine",
"name": "Wanhao D9-500 MK3 0.4 nozzle",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"setting_id": "F7l90Rgr8Ni0sQva",
"instantiation": "true",
"printer_model": "Wanhao D9-500 MK3",
"nozzle_diameter": [
"0.4"
],
"printable_area": [
"0x0",
"500x0",
"500x500",
"0x500"
],
"printable_height": "500",
"default_print_profile": "0.20mm Standard @Wanhao D9"
}
@@ -0,0 +1,9 @@
{
"type": "machine_model",
"name": "Wanhao D9-500 MK3",
"model_id": "Wanhao-D9-500-MK3",
"nozzle_diameter": "0.4",
"machine_tech": "FFF",
"family": "Wanhao",
"default_materials": "Generic PLA @System;Generic PETG @System;Generic ABS @System"
}
@@ -0,0 +1,108 @@
{
"type": "machine",
"name": "fdm_wanhao_d9_common",
"inherits": "fdm_wanhao_common",
"from": "system",
"instantiation": "false",
"gcode_flavor": "marlin2",
"use_relative_e_distances": "1",
"emit_machine_limits_to_gcode": "0",
"nozzle_diameter": [
"0.4"
],
"printer_variant": "0.4",
"max_layer_height": [
"0.32"
],
"min_layer_height": [
"0.08"
],
"machine_max_speed_x": [
"300",
"300"
],
"machine_max_speed_y": [
"300",
"300"
],
"machine_max_speed_z": [
"5",
"5"
],
"machine_max_speed_e": [
"25",
"25"
],
"machine_max_acceleration_x": [
"3000",
"3000"
],
"machine_max_acceleration_y": [
"3000",
"3000"
],
"machine_max_acceleration_z": [
"100",
"100"
],
"machine_max_acceleration_e": [
"3000",
"3000"
],
"machine_max_acceleration_extruding": [
"1000",
"1000"
],
"machine_max_acceleration_travel": [
"1000",
"1000"
],
"machine_max_acceleration_retracting": [
"800",
"800"
],
"machine_max_jerk_x": [
"10",
"10"
],
"machine_max_jerk_y": [
"10",
"10"
],
"machine_max_jerk_z": [
"0.4",
"0.4"
],
"machine_max_jerk_e": [
"1",
"1"
],
"retraction_length": [
"2.0"
],
"retraction_speed": [
"25"
],
"deretraction_speed": [
"25"
],
"retraction_minimum_travel": [
"1"
],
"z_hop": [
"0"
],
"wipe": [
"0"
],
"retract_when_changing_layer": [
"1"
],
"machine_start_gcode": "; Wanhao Duplicator 9 start G-code, for the Marlin 2.1 firmwares at github.com/Le-Syl21/WANHAO-Duplicator-9\nG21 ; millimetres\nG90 ; absolute coordinates\nM83 ; relative extrusion\nM140 S[bed_temperature_initial_layer_single] ; heat the bed\nM104 S150 ; warm the nozzle without letting it ooze\nG91 ; a print stopped by hand can leave the nozzle down on the bed\nG1 Z10 F300 ; so raise it before homing: a BLTouch needs 10 mm to deploy\nG90\nM280 P0 S160 ; BLTouch: clear an alarm and stow the pin\nG28 ; home all axes (this turns bed levelling off)\nM420 S1 ; turn the bed mesh saved from the screen back on\nG1 Z10 F300\nM104 S[nozzle_temperature_initial_layer] ; start the nozzle now, the bed is still heating\nM190 S[bed_temperature_initial_layer_single] ; wait for the bed\nM109 S[nozzle_temperature_initial_layer] ; and confirm the nozzle\nG92 E0\nG1 X15 Y20 Z0.3 F3000 ; start of the priming line\nG1 Y140 E9.0 F1200 ; draw a line of filament\nG1 X15.5 F3000\nG1 Y20 E9.0 F1200 ; and back, next to it\nG92 E0\nG1 X22 F6000 ; wipe sideways to snap the string\nG1 Z2 F300 ; lift, so the line does not stick to the nozzle",
"machine_end_gcode": "; Wanhao Duplicator 9 end G-code\nM104 S0 ; nozzle heater off\nM140 S0 ; bed heater off\nM107 ; fan off\nG91 ; relative moves\nG1 E-2 F1500 ; release the pressure in the nozzle\nG1 Z10 F300 ; lift the nozzle\nG90 ; absolute moves\nG1 X5 Y{print_bed_max[1] - 10} F3000 ; bring the bed to the front\nM84 X Y E ; motors off, Z keeps its position",
"layer_change_gcode": "G92 E0",
"machine_pause_gcode": "M600",
"default_filament_profile": [
"Generic PLA @System"
]
}
@@ -0,0 +1,28 @@
{
"type": "machine",
"name": "fdm_wanhao_d9_mk1_common",
"inherits": "fdm_wanhao_d9_common",
"from": "system",
"instantiation": "false",
"machine_start_gcode": "; Wanhao Duplicator 9 start G-code, for the Marlin 2.1 firmwares at github.com/Le-Syl21/WANHAO-Duplicator-9\nG21 ; millimetres\nG90 ; absolute coordinates\nM83 ; relative extrusion\nM140 S[bed_temperature_initial_layer_single] ; heat the bed\nM104 S150 ; warm the nozzle without letting it ooze\nG91 ; a print stopped by hand can leave the nozzle down on the bed\nG1 Z10 F300 ; clear the bed before homing\nG90\nG28 ; home all axes (this turns bed levelling off)\nM420 S1 ; turn the bed mesh saved from the screen back on\nG1 Z10 F300\nM104 S[nozzle_temperature_initial_layer] ; start the nozzle now, the bed is still heating\nM190 S[bed_temperature_initial_layer_single] ; wait for the bed\nM109 S[nozzle_temperature_initial_layer] ; and confirm the nozzle\nG92 E0\nG1 X15 Y20 Z0.3 F3000 ; start of the priming line\nG1 Y140 E9.0 F1200 ; draw a line of filament\nG1 X15.5 F3000\nG1 Y20 E9.0 F1200 ; and back, next to it\nG92 E0\nG1 X22 F6000 ; wipe sideways to snap the string\nG1 Z2 F300 ; lift, so the line does not stick to the nozzle",
"machine_max_acceleration_x": [
"500",
"500"
],
"machine_max_acceleration_y": [
"500",
"500"
],
"machine_max_acceleration_e": [
"500",
"500"
],
"machine_max_acceleration_extruding": [
"500",
"500"
],
"machine_max_acceleration_travel": [
"500",
"500"
]
}
@@ -0,0 +1,17 @@
{
"type": "process",
"name": "0.12mm Fine @Wanhao D9 MK1",
"inherits": "fdm_process_wanhao_d9_mk1_common",
"from": "system",
"setting_id": "EClNN5UDWbLACTuz",
"instantiation": "true",
"layer_height": "0.12",
"initial_layer_print_height": "0.14",
"top_shell_layers": "4",
"bottom_shell_layers": "4",
"compatible_printers": [
"Wanhao D9-300 MK1 0.4 nozzle",
"Wanhao D9-400 MK1 0.4 nozzle",
"Wanhao D9-500 MK1 0.4 nozzle"
]
}
@@ -0,0 +1,23 @@
{
"type": "process",
"name": "0.12mm Fine @Wanhao D9",
"inherits": "fdm_process_wanhao_d9_common",
"from": "system",
"setting_id": "0hvsKsPO55TlduZR",
"instantiation": "true",
"layer_height": "0.12",
"initial_layer_print_height": "0.14",
"top_shell_layers": "4",
"bottom_shell_layers": "4",
"compatible_printers": [
"Wanhao D9-300 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-400 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-500 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-300 MK2 0.4 nozzle",
"Wanhao D9-400 MK2 0.4 nozzle",
"Wanhao D9-500 MK2 0.4 nozzle",
"Wanhao D9-300 MK3 0.4 nozzle",
"Wanhao D9-400 MK3 0.4 nozzle",
"Wanhao D9-500 MK3 0.4 nozzle"
]
}
@@ -0,0 +1,17 @@
{
"type": "process",
"name": "0.20mm Standard @Wanhao D9 MK1",
"inherits": "fdm_process_wanhao_d9_mk1_common",
"from": "system",
"setting_id": "CXNOj3tPeTUXx81B",
"instantiation": "true",
"layer_height": "0.20",
"initial_layer_print_height": "0.24",
"top_shell_layers": "3",
"bottom_shell_layers": "3",
"compatible_printers": [
"Wanhao D9-300 MK1 0.4 nozzle",
"Wanhao D9-400 MK1 0.4 nozzle",
"Wanhao D9-500 MK1 0.4 nozzle"
]
}
@@ -0,0 +1,23 @@
{
"type": "process",
"name": "0.20mm Standard @Wanhao D9",
"inherits": "fdm_process_wanhao_d9_common",
"from": "system",
"setting_id": "UVXxknNxJswqaURQ",
"instantiation": "true",
"layer_height": "0.20",
"initial_layer_print_height": "0.24",
"top_shell_layers": "3",
"bottom_shell_layers": "3",
"compatible_printers": [
"Wanhao D9-300 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-400 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-500 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-300 MK2 0.4 nozzle",
"Wanhao D9-400 MK2 0.4 nozzle",
"Wanhao D9-500 MK2 0.4 nozzle",
"Wanhao D9-300 MK3 0.4 nozzle",
"Wanhao D9-400 MK3 0.4 nozzle",
"Wanhao D9-500 MK3 0.4 nozzle"
]
}
@@ -0,0 +1,17 @@
{
"type": "process",
"name": "0.28mm Draft @Wanhao D9 MK1",
"inherits": "fdm_process_wanhao_d9_mk1_common",
"from": "system",
"setting_id": "omfIWwVnQVVxPrtb",
"instantiation": "true",
"layer_height": "0.28",
"initial_layer_print_height": "0.34",
"top_shell_layers": "3",
"bottom_shell_layers": "3",
"compatible_printers": [
"Wanhao D9-300 MK1 0.4 nozzle",
"Wanhao D9-400 MK1 0.4 nozzle",
"Wanhao D9-500 MK1 0.4 nozzle"
]
}
@@ -0,0 +1,23 @@
{
"type": "process",
"name": "0.28mm Draft @Wanhao D9",
"inherits": "fdm_process_wanhao_d9_common",
"from": "system",
"setting_id": "FEJqq1ylXWqaBPR6",
"instantiation": "true",
"layer_height": "0.28",
"initial_layer_print_height": "0.34",
"top_shell_layers": "3",
"bottom_shell_layers": "3",
"compatible_printers": [
"Wanhao D9-300 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-400 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-500 MK1 BLTouch kit 0.4 nozzle",
"Wanhao D9-300 MK2 0.4 nozzle",
"Wanhao D9-400 MK2 0.4 nozzle",
"Wanhao D9-500 MK2 0.4 nozzle",
"Wanhao D9-300 MK3 0.4 nozzle",
"Wanhao D9-400 MK3 0.4 nozzle",
"Wanhao D9-500 MK3 0.4 nozzle"
]
}
@@ -0,0 +1,38 @@
{
"type": "process",
"name": "fdm_process_wanhao_d9_common",
"inherits": "fdm_process_wanhao_common",
"from": "system",
"instantiation": "false",
"line_width": "0.4",
"initial_layer_line_width": "0.6",
"wall_loops": "2",
"infill_wall_overlap": "15%",
"sparse_infill_density": "15%",
"sparse_infill_pattern": "gyroid",
"outer_wall_speed": "25",
"inner_wall_speed": "40",
"sparse_infill_speed": "50",
"internal_solid_infill_speed": "50",
"top_surface_speed": "40",
"gap_infill_speed": "40",
"bridge_speed": "50",
"support_speed": "35",
"initial_layer_speed": "25",
"initial_layer_infill_speed": "25",
"travel_speed": "100",
"default_acceleration": "1000",
"outer_wall_acceleration": "1000",
"inner_wall_acceleration": "1000",
"top_surface_acceleration": "1000",
"sparse_infill_acceleration": "1000",
"initial_layer_acceleration": "1000",
"bridge_acceleration": "1000",
"travel_acceleration": "1000",
"default_jerk": "0",
"skirt_loops": "2",
"skirt_distance": "4",
"brim_type": "no_brim",
"enable_support": "0",
"enable_arc_fitting": "0"
}
@@ -0,0 +1,15 @@
{
"type": "process",
"name": "fdm_process_wanhao_d9_mk1_common",
"inherits": "fdm_process_wanhao_d9_common",
"from": "system",
"instantiation": "false",
"default_acceleration": "500",
"outer_wall_acceleration": "500",
"inner_wall_acceleration": "500",
"top_surface_acceleration": "500",
"sparse_infill_acceleration": "500",
"initial_layer_acceleration": "500",
"bridge_acceleration": "500",
"travel_acceleration": "500"
}
+57 -23
View File
@@ -30,7 +30,7 @@ var USER_MODE = "simple";
var MODE_RANK = { simple: 0, advanced: 1, expert: 2, develop: 3 };
// Search ranking weights: every contiguous match must outrank every fuzzy one regardless of field,
// and title must outrank group, which outranks source.
// and title must outrank group/category, which outranks source.
var SCORE_CONTIGUOUS = 100000;
var SCORE_TITLE = 2000;
var SCORE_GROUP = 1000;
@@ -118,6 +118,18 @@ function sourceNorm(a) {
a._sn = NormText(a.source || "", false);
return a._sn;
}
function pluginCategoryNorm(a) {
if (a._pcn === undefined)
a._pcn = a.kind === "plugin" ? NormText(T("sd_plugins", "Plugins"), false) : "";
return a._pcn;
}
// Plugin type is searchable metadata, so typing "plugin" can find runnable plugin actions even
// when neither their capability nor plugin name contains that word. Keep both category forms.
function pluginTypeNorm(a) {
if (a._pn === undefined)
a._pn = a.kind === "plugin" ? NormText("plugin plugins", false) : "";
return a._pn;
}
// Search-only alias for the descriptive name when the title differs (e.g. "Reverse on even" vs
// "Overhang reversal"). Never rendered, so no highlight ranges.
function fullNorm(a) {
@@ -152,7 +164,7 @@ function fieldMatchScore(norm, needle, wwRe) {
// Split a query into normalized (folded+lowercased) whitespace-separated tokens. Empty for a blank
// query. These drive the multi-token path: every token must match some field, but different tokens
// may match different fields (the title, the group, or the source breadcrumb).
// may match different fields (the title, group, source breadcrumb, or plugin kind).
function queryTokens(query) {
var norm = NormText(String(query || "").trim(), false);
return norm ? norm.split(/\s+/).filter(Boolean) : [];
@@ -170,14 +182,19 @@ function tokenMatch(a, token, wwRe) {
var g = fieldMatchScore(groupNorm(a), token, wwRe);
var s = fieldMatchScore(sourceNorm(a), token, wwRe);
var f = fieldMatchScore(fullNorm(a), token, wwRe);
if (!t && !g && !s && !f) return null;
var p = fieldMatchScore(pluginCategoryNorm(a), token, wwRe);
var typeMatch = fieldMatchScore(pluginTypeNorm(a), token, wwRe);
if (!t && !g && !s && !f && !p && !typeMatch) return null;
var score = Math.max(
t ? (t.contiguous ? SCORE_CONTIGUOUS : 0) + SCORE_TITLE + t.score : -Infinity,
g ? (g.contiguous ? SCORE_CONTIGUOUS : 0) + SCORE_GROUP + g.score : -Infinity,
s ? (s.contiguous ? SCORE_CONTIGUOUS : 0) + s.score : -Infinity,
f ? (f.contiguous ? SCORE_CONTIGUOUS : 0) + f.score : -Infinity
f ? (f.contiguous ? SCORE_CONTIGUOUS : 0) + f.score : -Infinity,
p ? (p.contiguous ? SCORE_CONTIGUOUS : 0) + SCORE_GROUP + p.score : -Infinity,
typeMatch ? (typeMatch.contiguous ? SCORE_CONTIGUOUS : 0) + SCORE_GROUP + typeMatch.score : -Infinity
);
return { score: score, title: t ? t.ranges : null, group: g ? g.ranges : null, source: s ? s.ranges : null };
return { score: score, title: t ? t.ranges : null, group: g ? g.ranges : null, source: s ? s.ranges : null,
plugin: p ? p.ranges : null };
}
// Merge per-field token ranges into sorted, coalesced ranges for highlighting. Overlapping or adjacent
@@ -201,8 +218,8 @@ function mergeRanges(ranges) {
}
// Combine per-field scores into one value, or null when nothing matched.
// Ranking: contiguous > fuzzy, then title > group > source/full alias, then start/gaps.
function scoreFields(t, g, s, f) {
// Ranking: contiguous > fuzzy, then title > group/category > source/full alias, then start/gaps.
function scoreFields(t, g, s, f, p, typeMatch) {
var best = null;
function consider(m, weight) {
if (!m) return;
@@ -213,6 +230,8 @@ function scoreFields(t, g, s, f) {
consider(g, SCORE_GROUP);
consider(s, 0);
consider(f, 0);
consider(p, SCORE_GROUP);
consider(typeMatch, SCORE_GROUP);
return best;
}
@@ -226,7 +245,8 @@ function scoreFields(t, g, s, f) {
// - tokens: every whitespace-separated word must match SOME field, but different words may match
// different fields. This is what lets "speed acceleration inner" find "Inner wall" whose path is
// "Process : Speed : Acceleration" (title + source breadcrumb together).
// full_label is searchable too but never highlighted, since it is not rendered.
// full_label and canonical plugin kind are searchable aliases. The visible category is also searchable
// so its own match can be highlighted in plugin rows.
// A phrase match always outranks a distributed token match.
function searchActions(actions, query) {
var q = (query || "").trim();
@@ -251,26 +271,31 @@ function searchActions(actions, query) {
var g = fieldMatchScore(groupNorm(a), searchNeedle, wwRe);
var s = fieldMatchScore(sourceNorm(a), searchNeedle, wwRe);
var f = fieldMatchScore(fullNorm(a), searchNeedle, wwRe);
var phrase = scoreFields(t, g, s, f);
var p = fieldMatchScore(pluginCategoryNorm(a), searchNeedle, wwRe);
var typeMatch = fieldMatchScore(pluginTypeNorm(a), searchNeedle, wwRe);
var phrase = scoreFields(t, g, s, f, p, typeMatch);
var score, ranges;
if (phrase !== null) {
score = phrase + SCORE_PHRASE;
ranges = { title: t ? t.ranges : null, group: g ? g.ranges : null, source: s ? s.ranges : null };
ranges = { title: t ? t.ranges : null, group: g ? g.ranges : null, source: s ? s.ranges : null,
plugin: p ? p.ranges : null };
} else {
// Require every token; a token that matches nothing drops the action immediately. Ranges
// from all matching tokens are merged per field so each matched word highlights.
var sum = 0, titleR = null, groupR = null, sourceR = null, all = true;
for (var k = 0; k < searchTokens.length; k++) {
var m = tokenMatch(a, searchTokens[k], searchTokenRes[k]);
var sum = 0, titleR = null, groupR = null, sourceR = null, pluginR = null, all = true;
for (var tokenIndex = 0; tokenIndex < searchTokens.length; tokenIndex++) {
var m = tokenMatch(a, searchTokens[tokenIndex], searchTokenRes[tokenIndex]);
if (!m) { all = false; break; }
sum += m.score;
if (m.title) (titleR || (titleR = [])).push(m.title);
if (m.group) (groupR || (groupR = [])).push(m.group);
if (m.source) (sourceR || (sourceR = [])).push(m.source);
if (m.plugin) (pluginR || (pluginR = [])).push(m.plugin);
}
if (!all) continue;
score = sum;
ranges = { title: mergeRanges(titleR), group: mergeRanges(groupR), source: mergeRanges(sourceR) };
ranges = { title: mergeRanges(titleR), group: mergeRanges(groupR), source: mergeRanges(sourceR),
plugin: mergeRanges(pluginR) };
}
// Ranges are per-field against the ACTUAL text drawn: title for the row-name, and group (or
// source when group is empty) for the eyebrow - so highlight offsets stay aligned to the label.
@@ -278,6 +303,7 @@ function searchActions(actions, query) {
title: ranges.title,
group: ranges.group,
source: ranges.source,
plugin: ranges.plugin,
useEyebrowGroup: !!(a.group)
};
scored.push({ a: a, s: score });
@@ -390,7 +416,7 @@ function favDigitFromEvent(e) {
function resultCountText(total, shown, query) {
return (query || "").trim() ?
T("sd_result_count", "Showing %s of %s actions", shown, total) :
T("sd_result_count", "Showing %s actions", shown) :
T("sd_result_count_all", "%s actions", total);
}
@@ -461,6 +487,12 @@ function actionCategory(a) {
return cat || T("sd_other", "Other");
}
function actionEyebrow(a, typedQuery, isRecent) {
if (a && a.kind === "plugin" && (String(typedQuery || "").trim() || isRecent))
return T("sd_plugins", "Plugins");
return (a && (a.group || a.source)) || "";
}
// Stable-bucket actions by category, then order the groups alphabetically. Within a group the incoming
// (frecency) order is kept. Pure so the node-vm test can exercise grouping.
function groupActions(list) {
@@ -711,7 +743,7 @@ window.HandleStudio = function (payload) {
builtKey = "";
if (qEl) {
qEl.value = "";
qEl.placeholder = T("sd_search_n", "Search %s actions", ACTIONS.length);
qEl.placeholder = T("sd_search", "Search actions");
syncClearButton();
}
render({ resize: true, resetScroll: true });
@@ -931,12 +963,14 @@ function beginRow(item, i, mono, ariaLabel) {
function renderActionRow(a, i) {
var on = FAVS.indexOf(a.id) !== -1;
var shell = beginRow(a, i, false, actionLabel(a, ACTIONS));
var mi = matchIndex[a.id];
// The eyebrow shows group when present, else source. Highlight with the ranges of whichever of the
// two the eyebrow actually renders (so a "Recent Projects"/"Object" header match lights up like a
// setting path does - the offsets are computed against the same string we are marking).
var eyebrow = a.group || a.source;
var eyebrowMatch = mi ? (mi.useEyebrowGroup ? mi.group : mi.source) : null;
var typedQuery = String(query || "").trim();
var isRecent = !typedQuery && i < RECENTS.length && RECENTS[i].id === a.id;
var mi = typedQuery ? matchIndex[a.id] : null;
// Plugin search/recent rows show their category; other rows show their group or source breadcrumb.
// Use match ranges from the visible field so category and breadcrumb highlights stay aligned.
var showPluginCategory = a.kind === "plugin" && (typedQuery || isRecent);
var eyebrow = actionEyebrow(a, query, isRecent);
var eyebrowMatch = mi ? (showPluginCategory ? mi.plugin : (mi.useEyebrowGroup ? mi.group : mi.source)) : null;
shell.left.insertBefore(markedText("row-eyebrow", eyebrow, eyebrowMatch), shell.line);
shell.line.appendChild(markedText("row-name", a.title, mi ? mi.title : null));
var badge = modeBadge(a, USER_MODE);
@@ -1376,7 +1410,7 @@ function exitPhase() {
// It survives a second-phase exit (which never goes through exitPhase from the commands view),
// so without a reset the cached empty-query key would skip the rebuild and leave stale content.
builtKey = "";
qEl.placeholder = T("sd_search_n", "Search %s actions", ACTIONS.length);
qEl.placeholder = T("sd_search", "Search actions");
render({ resize: true, resetScroll: true });
qEl.focus();
}
@@ -82,6 +82,20 @@ assert.equal(ctx.searchActions(pool, "layer").length >= 2, true,
assert.equal(ctx.searchActions(pool, "surface")[0].id, "c2",
"a later-but-precise match still ranks by relevance, not by pool type");
const pluginPool = [
{ id: "plugin-action", title: "Optimize G-code", source: "Gcode Optimizer", group: "", kind: "plugin" },
{ id: "command-action", title: "Open Preferences", source: "OrcaSlicer", group: "Commands", kind: "command" }
];
assert.deepEqual(ctx.searchActions(pluginPool, "plugin").map(function (a) { return a.id; }), ["plugin-action"],
"the plugin kind makes runnable plugin actions searchable by plugin");
assert.deepEqual(ctx.searchActions(pluginPool, "plugins").map(function (a) { return a.id; }), ["plugin-action"],
"the plural Plugins category also finds plugin actions");
ctx.searchActions(pluginPool, "plugins");
assert.deepEqual(ctx.matchIndex["plugin-action"].plugin, [[0, 7]],
"a category match highlights the visible Plugins label");
assert.deepEqual(ctx.searchActions(pluginPool, "plugin optimize").map(function (a) { return a.id; }), ["plugin-action"],
"plugin kind can match one token while the action title matches another");
// A perfect match (the needle as one contiguous run) outranks a fuzzy match of the same field - and a
// contiguous GROUP/header hit ("Recent Projects") beats a scattered fuzzy TITLE hit ("Retraction Length"),
// which is what the old flat title-bonus ranking got backwards.
@@ -188,6 +202,12 @@ assert.equal(ctx.actionCategory({ id: "s", group: "", source: "Filament : Coolin
"a Filament setting groups under Filament");
assert.equal(ctx.actionCategory({ id: "plugin_script_action:Foo:bar.py", group: "", source: "Gcode Optimizer", kind: "plugin" }), "Plugins",
"every plugin shares one Plugins header");
assert.equal(ctx.actionEyebrow({ group: "", source: "Gcode Optimizer", kind: "plugin" }, "plugin"), "Plugins",
"typed results show only the Plugins category");
assert.equal(ctx.actionEyebrow({ group: "", source: "Gcode Optimizer", kind: "plugin" }, "", true), "Plugins",
"recent plugin actions show only the Plugins category");
assert.equal(ctx.actionEyebrow({ group: "", source: "Gcode Optimizer", kind: "plugin" }, ""), "Gcode Optimizer",
"the unfiltered plugin section keeps the source name on non-recent rows");
assert.equal(ctx.actionCategory({ id: "x", group: "", source: "", kind: "command" }), "Other",
"a category-less action falls back to Other");
@@ -436,4 +456,9 @@ assert.equal(ctx.stateFromPayload({}).tooltipExpanded, true, "expansion defaults
assert.equal(ctx.stateFromPayload({ tooltip_expanded: false }).tooltipExpanded, false, "a collapsed payload is honored");
assert.equal(ctx.stateFromPayload({ tooltip_expanded: true }).tooltipExpanded, true, "an expanded payload is honored");
// resultCountText: a search counts the shown matches only ("Showing N actions"); the total is used
// solely for the empty-query count.
assert.equal(ctx.resultCountText(100, 3, "lay"), "Showing 3 actions", "a search reports the shown match count only");
assert.equal(ctx.resultCountText(100, 100, ""), "100 actions", "an empty query reports the total");
console.log("ok");
+45
View File
@@ -405,6 +405,20 @@ class TestTripleResolution(unittest.TestCase):
self.assertEqual(afi.resolve_triple("MyPLA @P1", fmap, {}),
("MyVendor", "PLA", "MyPLA"))
def test_split_vendor_and_type_bases_resolve(self):
# A partial base is normal, not an error: vendor and type may live on
# different ancestors, with an intermediate supplying neither (the
# Snapmaker shape). The pair is complete at the instantiated preset.
recs = [
self.rec("APLA @P1", inherits="mid"),
self.rec("mid", inherits="typebase"),
self.rec("typebase", filament_type=["PLA"], inherits="vendorbase"),
self.rec("vendorbase", filament_vendor=["AV"]),
]
fmap = {r["name"]: r for r in recs}
self.assertEqual(afi.resolve_triple("APLA @P1", fmap, {}),
("AV", "PLA", "APLA"))
# ---------------------------------------------------------------------------
# checks on synthetic trees
@@ -417,6 +431,24 @@ class TestChecks(OfCleanTreeCase):
self.assertNotIn("[ERROR]", out)
self.assertNotIn("[WARNING]", out)
def test_instantiated_preset_over_partial_bases_is_silent(self):
# Vendor and type split across two non-instantiated bases, an
# intermediate base with neither: base profiles are allowed to be
# partial. Only the instantiated preset must resolve both.
self.t.write_preset("VendorA", preset("XPLA vendorbase", instantiation=False,
filament_vendor="XV"))
self.t.write_preset("VendorA", preset("XPLA typebase", instantiation=False,
filament_type="PLA",
inherits="XPLA vendorbase"))
self.t.write_preset("VendorA", preset("XPLA mid", instantiation=False,
inherits="XPLA typebase"))
self.t.write_preset("VendorA", preset(
"XPLA @P1", inherits="XPLA mid",
filament_id=afi.generate_filament_id("XV", "PLA", "XPLA"),
compatible_printers=["P1"]))
errors, out = self.t.check()
self.assertEqual(errors, 0, out)
def test_check1_unknown_non_of_id(self):
self.t.write_preset("VendorA", preset("BPLA @base", filament_id="BOGUS_9",
instantiation=False,
@@ -1523,6 +1555,19 @@ class TestRealTree(unittest.TestCase):
self.assertEqual(analysis["missing_effective"], [])
self.assertEqual(analysis["read_errors"], [])
def test_every_instantiated_filament_resolves_vendor_and_type(self):
# The property the web guide resolves at load: a partial base is fine as
# long as the instantiated preset ends up with both fields. Guards the
# split-base bundles (Snapmaker, Anker, SeeMeCNC).
analysis = afi.analyze_tree(REAL_PROFILES)
unresolved = [
(vendor, rec["name"], rec["triple"][0], rec["triple"][1])
for vendor, filaments in analysis["vendors"].items()
for rec in filaments.values()
if rec["instantiation"] and not (rec["triple"][0] and rec["triple"][1])
]
self.assertEqual(unresolved, [])
# ---------------------------------------------------------------------------
# review-fix regressions
# ---------------------------------------------------------------------------
+8
View File
@@ -286,6 +286,8 @@ set(SLIC3R_GUI_SOURCES
GUI/FilamentMapDialog.hpp
GUI/IconManager.cpp
GUI/IconManager.hpp
GUI/IdleScheduler.cpp
GUI/IdleScheduler.hpp
GUI/ImageGrid.cpp
GUI/ImageGrid.h
GUI/ImGuiWrapper.cpp
@@ -347,6 +349,10 @@ set(SLIC3R_GUI_SOURCES
GUI/KBShortcutsDialog.hpp
GUI/KeyChord.cpp
GUI/KeyChord.hpp
GUI/Lazy.cpp
GUI/Lazy.hpp
GUI/LazyPage.cpp
GUI/LazyPage.hpp
GUI/LibVGCode/LibVGCodeWrapper.hpp
GUI/LibVGCode/LibVGCodeWrapper.cpp
GUI/LinuxDisplayBackend.cpp
@@ -433,6 +439,7 @@ set(SLIC3R_GUI_SOURCES
GUI/Plater.hpp
GUI/PlateSettingsDialog.cpp
GUI/PlateSettingsDialog.hpp
GUI/PrebuildQueue.hpp
GUI/Preferences.cpp
GUI/Preferences.hpp
GUI/PresetBundleDialog.cpp
@@ -512,6 +519,7 @@ set(SLIC3R_GUI_SOURCES
GUI/SliceInfoPanel.hpp
GUI/SlicingProgressNotification.cpp
GUI/SlicingProgressNotification.hpp
GUI/StagedBuild.hpp
GUI/StatusPanel.cpp
GUI/StatusPanel.hpp
GUI/StepMeshDialog.cpp
+21 -11
View File
@@ -863,17 +863,27 @@ void AuxiliaryPanel::init_tabpanel()
m_tabpanel->SetBackgroundColour(wxColour("#FEFFFF"));
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [](wxBookCtrlEvent &e) { /* Event handling */ });
m_designer_panel = new DesignerPanel(m_tabpanel, AuxiliaryFolderType::DESIGNER);
m_pictures_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::MODEL_PICTURE);
m_bill_of_materials_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::BILL_OF_MATERIALS);
m_assembly_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::ASSEMBLY_GUIDE);
m_others_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::OTHERS);
m_tabpanel->AddPage(m_designer_panel, _L("Basic Info"), true);
m_tabpanel->AddPage(m_pictures_panel, _L("Pictures"), false);
m_tabpanel->AddPage(m_bill_of_materials_panel, _L("Bill of Materials"), false);
m_tabpanel->AddPage(m_assembly_panel, _L("Assembly Guide"), false);
m_tabpanel->AddPage(m_others_panel, _L("Others"), false);
add_build_step([this] {
m_designer_panel = new DesignerPanel(m_tabpanel, AuxiliaryFolderType::DESIGNER);
m_tabpanel->AddPage(m_designer_panel, _L("Basic Info"), true);
});
add_build_step([this] {
m_pictures_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::MODEL_PICTURE);
m_tabpanel->AddPage(m_pictures_panel, _L("Pictures"), false);
});
add_build_step([this] {
m_bill_of_materials_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::BILL_OF_MATERIALS);
m_tabpanel->AddPage(m_bill_of_materials_panel, _L("Bill of Materials"), false);
});
add_build_step([this] {
m_assembly_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::ASSEMBLY_GUIDE);
m_tabpanel->AddPage(m_assembly_panel, _L("Assembly Guide"), false);
});
add_build_step([this] {
m_others_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::OTHERS);
m_tabpanel->AddPage(m_others_panel, _L("Others"), false);
Layout();
});
}
wxWindow *AuxiliaryPanel::create_side_tools()
+2 -1
View File
@@ -46,6 +46,7 @@
#include "slic3r/GUI/UpgradePanel.hpp"
#include "slic3r/GUI/AmsWidgets.hpp"
#include "Widgets/SideTools.hpp"
#include "StagedBuild.hpp"
#define AUFILE_GREY700 wxColour(107, 107, 107)
#define AUFILE_GREY500 wxColour(158, 158, 158)
@@ -194,7 +195,7 @@ public:
};
class AuxiliaryPanel : public wxPanel
class AuxiliaryPanel : public wxPanel, public StagedBuild
{
private:
Tabbook *m_tabpanel = {nullptr};
+2 -1
View File
@@ -12,6 +12,7 @@
#include "libslic3r/CAD/CadDocument.hpp"
#include "slic3r/GUI/CAD/DesignInteraction.hpp" // CadLevel: what one Esc press means
#include "slic3r/GUI/Lazy.hpp"
class ComboBox; // Orca dropdown (Widgets/ComboBox.hpp) — replaces wxChoice everywhere here
class StaticBox; // Orca rounded card frame (Widgets/StaticBox.hpp)
@@ -46,7 +47,7 @@ class DesignCanvas;
// Design (CAD) tab: a sketch-first, Onshape-style form-driven CAD panel.
// Sketch and Extrude are independent tools: the user creates a Sketch first,
// then selects it and Extrudes to produce a solid.
class DesignPanel : public wxPanel
class DesignPanel : public wxPanel, public LazyInstance<DesignPanel>
{
public:
explicit DesignPanel(wxWindow* parent);
+1 -2
View File
@@ -1989,11 +1989,10 @@ json action_set_feature_expr(DesignPanel* panel, const json& params)
// Dispatch one parsed request ON THE MAIN THREAD. Returns a JSON-RPC reply string.
std::string handle_on_main(const std::string& method, const json& params, const json& id)
{
MainFrame* mf = wxGetApp().mainframe;
// The panel is built on first use, and in a headless session nobody clicks the tab that
// would build it -- so build it here rather than refusing. Safe: this runs on the main
// thread (see the CallAfter that dispatches us).
DesignPanel* panel = mf ? mf->ensure_design_panel() : nullptr;
DesignPanel* panel = DesignPanel::ensure();
if (!panel)
return rpc_error(id, -32001, "Design panel not ready");
+6 -3
View File
@@ -491,14 +491,15 @@ void CalibrationPanel::init_tabpanel() {
selected);
}
for (int i = 0; i < (int)CALI_MODE_COUNT; i++)
add_build_steps_of(*m_cali_panels[i]);
// ORCA use standard paddings and keep arrow icon for consistent look between sidebars
//for (int i = 0; i < (int)CALI_MODE_COUNT; i++)
// m_tabpanel->SetPageImage(i, "");
//auto padding_size = m_tabpanel->GetBtnsListCtrl()->GetPaddingSize(0);
//m_tabpanel->GetBtnsListCtrl()->SetPaddingSize({ FromDIP(15), padding_size.y });
m_initialized = true;
}
void CalibrationPanel::init_timer()
@@ -534,6 +535,8 @@ void CalibrationPanel::update_print_error_info(int code, std::string msg, std::s
}
void CalibrationPanel::update_all() {
// Every wizard's pages exist once the last build step has run.
if (!built()) return;
NetworkAgent* m_agent = wxGetApp().getAgent();
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
@@ -597,7 +600,7 @@ void CalibrationPanel::update_all() {
void CalibrationPanel::show_status(int status)
{
if (!m_initialized) return;
if (!built()) return;
if (last_status == status)return;
last_status = status;
+2 -2
View File
@@ -3,6 +3,7 @@
#include "CalibrationWizard.hpp"
#include "Tabbook.hpp"
#include "Lazy.hpp"
//#include "Widgets/SideTools.hpp"
namespace Slic3r { namespace GUI {
@@ -88,7 +89,7 @@ private:
};
class CalibrationPanel : public wxPanel
class CalibrationPanel : public wxPanel, public StagedBuild, public LazyInstance<CalibrationPanel>
{
public:
CalibrationPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
@@ -109,7 +110,6 @@ protected:
int last_status;
bool m_initialized { false };
std::string last_conn_type = "undedefined";
MachineObject* obj{ nullptr };
MachineObject* last_obj { nullptr };
+56 -65
View File
@@ -130,6 +130,15 @@ CalibrationWizard::~CalibrationWizard()
;
}
void CalibrationWizard::add_page_step(CalibrationWizardPageStep*& step, std::function<CalibrationWizardPage*()> make)
{
add_build_step([this, &step, make = std::move(make)] {
step = new CalibrationWizardPageStep(make());
m_all_pages_sizer->Add(step->page, 1, wxEXPAND | wxALL, FromDIP(25));
step->page->Hide();
});
}
void CalibrationWizard::on_cali_job_finished(wxCommandEvent& event)
{
this->on_cali_job_finished(event.GetString());
@@ -520,33 +529,28 @@ void PressureAdvanceWizard::on_cali_job_finished(wxString evt_data)
void PressureAdvanceWizard::create_pages()
{
start_step = new CalibrationWizardPageStep(new CalibrationPAStartPage(m_scrolledWindow));
preset_step = new CalibrationWizardPageStep(new CalibrationPresetPage(m_scrolledWindow, m_mode, false));
cali_step = new CalibrationWizardPageStep(new CalibrationCaliPage(m_scrolledWindow, m_mode));
save_step = new CalibrationWizardPageStep(new CalibrationPASavePage(m_scrolledWindow));
add_page_step(start_step, [this] { return new CalibrationPAStartPage(m_scrolledWindow); });
add_page_step(preset_step, [this] { return new CalibrationPresetPage(m_scrolledWindow, m_mode, false); });
add_page_step(cali_step, [this] { return new CalibrationCaliPage(m_scrolledWindow, m_mode); });
add_page_step(save_step, [this] { return new CalibrationPASavePage(m_scrolledWindow); });
m_all_pages_sizer->Add(start_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(preset_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(cali_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(save_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
add_build_step([this] {
m_page_steps.push_back(start_step);
m_page_steps.push_back(preset_step);
m_page_steps.push_back(cali_step);
m_page_steps.push_back(save_step);
for (int i = 0; i < m_page_steps.size() -1; i++) {
m_page_steps[i]->chain(m_page_steps[i+1]);
}
m_page_steps.push_back(start_step);
m_page_steps.push_back(preset_step);
m_page_steps.push_back(cali_step);
m_page_steps.push_back(save_step);
for (int i = 0; i < m_page_steps.size(); i++) {
m_page_steps[i]->page->Bind(EVT_CALI_ACTION, &PressureAdvanceWizard::on_cali_action, this);
}
for (int i = 0; i < m_page_steps.size() -1; i++) {
m_page_steps[i]->chain(m_page_steps[i+1]);
}
for (int i = 0; i < m_page_steps.size(); i++) {
m_page_steps[i]->page->Hide();
m_page_steps[i]->page->Bind(EVT_CALI_ACTION, &PressureAdvanceWizard::on_cali_action, this);
}
if (!m_page_steps.empty())
show_step(m_page_steps.front());
if (!m_page_steps.empty())
show_step(m_page_steps.front());
});
}
void PressureAdvanceWizard::on_cali_action(wxCommandEvent& evt)
@@ -1053,59 +1057,46 @@ FlowRateWizard::FlowRateWizard(wxWindow* parent, wxWindowID id, const wxPoint& p
void FlowRateWizard::create_pages()
{
start_step = new CalibrationWizardPageStep(new CalibrationFlowRateStartPage(m_scrolledWindow));
preset_step = new CalibrationWizardPageStep(new CalibrationPresetPage(m_scrolledWindow, m_mode, false));
add_page_step(start_step, [this] { return new CalibrationFlowRateStartPage(m_scrolledWindow); });
add_page_step(preset_step, [this] { return new CalibrationPresetPage(m_scrolledWindow, m_mode, false); });
// manual
cali_coarse_step = new CalibrationWizardPageStep(new CalibrationCaliPage(m_scrolledWindow, m_mode, CaliPageType::CALI_PAGE_CALI));
coarse_save_step = new CalibrationWizardPageStep(new CalibrationFlowCoarseSavePage(m_scrolledWindow));
cali_fine_step = new CalibrationWizardPageStep(new CalibrationCaliPage(m_scrolledWindow, m_mode, CaliPageType::CALI_PAGE_FINE_CALI));
fine_save_step = new CalibrationWizardPageStep(new CalibrationFlowFineSavePage(m_scrolledWindow));
add_page_step(cali_coarse_step, [this] { return new CalibrationCaliPage(m_scrolledWindow, m_mode, CaliPageType::CALI_PAGE_CALI); });
add_page_step(coarse_save_step, [this] { return new CalibrationFlowCoarseSavePage(m_scrolledWindow); });
add_page_step(cali_fine_step, [this] { return new CalibrationCaliPage(m_scrolledWindow, m_mode, CaliPageType::CALI_PAGE_FINE_CALI); });
add_page_step(fine_save_step, [this] { return new CalibrationFlowFineSavePage(m_scrolledWindow); });
// auto
cali_step = new CalibrationWizardPageStep(new CalibrationCaliPage(m_scrolledWindow, m_mode));
save_step = new CalibrationWizardPageStep(new CalibrationFlowX1SavePage(m_scrolledWindow));
add_page_step(cali_step, [this] { return new CalibrationCaliPage(m_scrolledWindow, m_mode); });
add_page_step(save_step, [this] { return new CalibrationFlowX1SavePage(m_scrolledWindow); });
m_all_pages_sizer->Add(start_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(preset_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(cali_coarse_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(coarse_save_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(cali_fine_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(fine_save_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
add_build_step([this] {
m_page_steps.push_back(start_step);
m_page_steps.push_back(preset_step);
m_page_steps.push_back(cali_coarse_step);
m_page_steps.push_back(coarse_save_step);
m_page_steps.push_back(cali_fine_step);
m_page_steps.push_back(fine_save_step);
m_all_pages_sizer->Add(cali_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
m_all_pages_sizer->Add(save_step->page, 1, wxEXPAND | wxALL, FromDIP(25));
//m_page_steps.push_back(cali_step);
//m_page_steps.push_back(save_step);
m_page_steps.push_back(start_step);
m_page_steps.push_back(preset_step);
m_page_steps.push_back(cali_coarse_step);
m_page_steps.push_back(coarse_save_step);
m_page_steps.push_back(cali_fine_step);
m_page_steps.push_back(fine_save_step);
for (int i = 0; i < m_page_steps.size() - 1; i++) {
m_page_steps[i]->chain(m_page_steps[i + 1]);
}
//m_page_steps.push_back(cali_step);
//m_page_steps.push_back(save_step);
for (int i = 0; i < m_page_steps.size(); i++) {
m_page_steps[i]->page->Bind(EVT_CALI_ACTION, &FlowRateWizard::on_cali_action, this);
}
for (int i = 0; i < m_page_steps.size() - 1; i++) {
m_page_steps[i]->chain(m_page_steps[i + 1]);
}
cali_step->page->Bind(EVT_CALI_ACTION, &FlowRateWizard::on_cali_action, this);
save_step->page->Bind(EVT_CALI_ACTION, &FlowRateWizard::on_cali_action, this);
// hide all pages
cali_step->page->Hide();
save_step->page->Hide();
for (int i = 0; i < m_page_steps.size(); i++) {
m_page_steps[i]->page->Hide();
m_page_steps[i]->page->Bind(EVT_CALI_ACTION, &FlowRateWizard::on_cali_action, this);
}
if (!m_page_steps.empty())
show_step(m_page_steps.front());
cali_step->page->Bind(EVT_CALI_ACTION, &FlowRateWizard::on_cali_action, this);
save_step->page->Bind(EVT_CALI_ACTION, &FlowRateWizard::on_cali_action, this);
if (!m_page_steps.empty())
show_step(m_page_steps.front());
set_cali_method(CalibrationMethod::CALI_METHOD_MANUAL);
set_cali_method(CalibrationMethod::CALI_METHOD_MANUAL);
});
}
void FlowRateWizard::on_cali_action(wxCommandEvent& evt)
+5 -1
View File
@@ -9,6 +9,7 @@
#include "CalibrationWizardPresetPage.hpp"
#include "CalibrationWizardCaliPage.hpp"
#include "CalibrationWizardSavePage.hpp"
#include "StagedBuild.hpp"
namespace Slic3r { namespace GUI {
@@ -36,7 +37,7 @@ struct ConfigIndexValue
int index{0};
};
class CalibrationWizard : public wxPanel {
class CalibrationWizard : public wxPanel, public StagedBuild {
public:
CalibrationWizard(wxWindow* parent, CalibMode mode,
wxWindowID id = wxID_ANY,
@@ -79,6 +80,9 @@ public:
protected:
void on_cali_go_home();
// Queues a page as a build step, created hidden and added to the pages sizer.
void add_page_step(CalibrationWizardPageStep*& step, std::function<CalibrationWizardPage*()> make);
protected:
/* wx widgets*/
wxScrolledWindow* m_scrolledWindow;
+3 -1
View File
@@ -192,8 +192,10 @@ void CalibrationCaliPage::update(MachineObject* obj)
set_cali_img();
}
// A calibration can run before the Device tab is ever opened, and only its status
// panel shows a print error.
if (obj->print_error > 0) {
StatusPanel* status_panel = Slic3r::GUI::wxGetApp().mainframe->m_monitor->get_status_panel();
StatusPanel* status_panel = MonitorPanel::ensure()->get_status_panel();
status_panel->obj = obj;
status_panel->update_error_message();
}
+6 -3
View File
@@ -538,7 +538,8 @@ void DeviceErrorDialog::on_button_click(ActionButton btn_id)
break;
}
case DeviceErrorDialog::CHECK_ASSISTANT: {
wxGetApp().mainframe->m_monitor->jump_to_HMS(); // go to assistant page
if (MonitorPanel* monitor = MonitorPanel::if_built())
monitor->jump_to_HMS(); // go to assistant page
break;
}
case DeviceErrorDialog::FILAMENT_EXTRUDED: {
@@ -568,7 +569,8 @@ void DeviceErrorDialog::on_button_click(ActionButton btn_id)
}
case DeviceErrorDialog::JUMP_TO_LIVEVIEW: {
Slic3r::GUI::wxGetApp().mainframe->jump_to_monitor();
Slic3r::GUI::wxGetApp().mainframe->m_monitor->jump_to_LiveView();
if (MonitorPanel* monitor = MonitorPanel::if_built())
monitor->jump_to_LiveView();
break;
}
case DeviceErrorDialog::NO_REMINDER_NEXT_TIME: {
@@ -618,7 +620,8 @@ void DeviceErrorDialog::on_button_click(ActionButton btn_id)
}
case DeviceErrorDialog::OK_JUMP_RACK: {
Slic3r::GUI::wxGetApp().mainframe->jump_to_monitor();
Slic3r::GUI::wxGetApp().mainframe->m_monitor->jump_to_Rack();
if (MonitorPanel* monitor = MonitorPanel::if_built())
monitor->jump_to_Rack();
break;
}
case DeviceErrorDialog::ABORT: {
@@ -934,7 +934,8 @@ void wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus(wxMouseEvent& evt)
dlg.AddButton(wxID_OK,_L("Jump to the upgrade page"), true);
if (dlg.ShowModal() == wxID_OK) {
wxGetApp().mainframe->m_monitor->jump_to_Upgrade();
if (MonitorPanel* monitor = MonitorPanel::if_built())
monitor->jump_to_Upgrade();
};
}
}
@@ -344,7 +344,8 @@ void wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick(wxMouseEvent& event)
if (dlg.ShowModal() == wxID_OK)
{
wxGetApp().mainframe->m_monitor->jump_to_Upgrade();
if (MonitorPanel* monitor = MonitorPanel::if_built())
monitor->jump_to_Upgrade();
wxCommandEvent evt(wxEVT_NOZZLE_JUMP_UPGRADE, GetId());
evt.SetEventObject(this);
+210 -51
View File
@@ -20,6 +20,7 @@
#include "libslic3r/AppConfig.hpp"
#include "3DScene.hpp"
#include "BackgroundSlicingProcess.hpp"
#include "CameraUtils.hpp"
#include "GLShader.hpp"
#include "GUI.hpp"
#include "Tab.hpp"
@@ -117,6 +118,36 @@ void GLCanvas3D::load_render_colors()
namespace Slic3r {
namespace GUI {
static void pan_camera(Camera& camera, const Vec2d& screen_delta, const Vec3d& anchor)
{
// Orca: Derive world-units-per-pixel from the projection which produced the visible frame.
// Perspective additionally scales with the eye-space depth of the point being dragged.
const auto& viewport = camera.get_viewport();
const auto& projection = camera.get_projection_matrix().matrix();
const double depth_scale = camera.get_type() == Camera::EType::Perspective ?
(anchor - camera.get_position()).dot(camera.get_dir_forward()) : 1.0;
const double projection_x = projection(0, 0) * viewport[2];
const double projection_y = projection(1, 1) * viewport[3];
// Orca: X/Y projection coefficients already include zoom. Using them directly avoids a
// project/unproject round-trip through window depth, whose precision depends on the scene frustum.
if (viewport[2] > 0 && viewport[3] > 0 && anchor.allFinite() && depth_scale > EPSILON &&
std::abs(projection_x) > EPSILON && std::abs(projection_y) > EPSILON) {
const Vec3d displacement = 2.0 * depth_scale *
(screen_delta.y() / projection_y * camera.get_dir_up() -
screen_delta.x() / projection_x * camera.get_dir_right());
if (displacement.allFinite()) {
camera.translate(displacement);
return;
}
}
// Orca: Preserve the former target-plane behavior if the projection or anchor is invalid.
// Screen Y grows downward, and the camera moves opposite to the drag.
camera.translate(camera.get_inv_zoom() *
(screen_delta.y() * camera.get_dir_up() - screen_delta.x() * camera.get_dir_right()));
}
#ifdef __WXGTK3__
// wxGTK3 seems to simulate OSX behavior in regard to HiDPI scaling support.
RetinaHelper::RetinaHelper(wxWindow* window) : m_window(window), m_self(nullptr) {}
@@ -2206,15 +2237,14 @@ void GLCanvas3D::_render_scene(const Camera& camera, const Size& cnv_size)
_render_background();
//BBS add partplater rendering logic
bool only_current = false, only_body = false, no_partplate = false;
bool only_current = false, only_body = false;
const bool show_bed = is_bed_visible();
bool show_grid = true;
GLGizmosManager::EType gizmo_type = m_gizmos.get_current_type();
if (!m_main_toolbar.is_enabled()) {
//only_body = true;
only_current = true;
}
else if ((gizmo_type == GLGizmosManager::FdmSupports) || (gizmo_type == GLGizmosManager::Seam) || (gizmo_type == GLGizmosManager::MmSegmentation) || (gizmo_type == GLGizmosManager::FuzzySkin))
no_partplate = true;
else if (gizmo_type == GLGizmosManager::BrimEars && !camera.is_looking_downward())
show_grid = false;
if (m_axes_at_bed_center)
@@ -2228,11 +2258,11 @@ void GLCanvas3D::_render_scene(const Camera& camera, const Size& cnv_size)
if (m_canvas_type == ECanvasType::CanvasView3D) {
// m_show_bed gates the plate list too: hiding the bed but leaving its grid and outline
// floating would read as a rendering fault rather than a deliberate view option.
if (!no_partplate && m_show_bed)
if (show_bed)
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), m_show_world_axes);
if (!no_partplate && m_show_bed) //BBS: add outline logic
if (show_bed) //BBS: add outline logic
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true, show_grid);
if (m_axes_at_bed_center && m_show_bed && !no_partplate)
if (m_axes_at_bed_center && show_bed)
// Design tab: replace the plate's corner-origin grid with the origin-centred CAD grid.
_render_cad_grid(camera.get_view_matrix(), camera.get_projection_matrix());
@@ -3281,6 +3311,9 @@ void GLCanvas3D::unbind_event_handlers()
m_canvas->Unbind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this);
m_canvas->Unbind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this);
m_canvas->Unbind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this);
#if __WXOSX__
initGestures(m_canvas->GetHandle(), nullptr);
#endif
}
}
@@ -4029,27 +4062,38 @@ void GLCanvas3D::on_gesture(wxGestureEvent &evt)
auto & camera = wxGetApp().plater()->get_camera();
if (evt.GetEventType() == wxEVT_GESTURE_PAN) {
auto p = evt.GetPosition();
// Orca: Gesture coordinates must use framebuffer pixels, and one stable world-space
// anchor must be retained for the complete gesture to prevent perspective drift.
const auto p = evt.GetPosition();
auto d = static_cast<wxPanGestureEvent&>(evt).GetDelta();
float z = 0;
const Vec3d &p2 = _mouse_to_3d({p.x, p.y}, &z);
const Vec3d &p1 = _mouse_to_3d({p.x - d.x, p.y - d.y}, &z);
camera.set_target(camera.get_target() + p1 - p2);
Vec2d screen_position(p.x, p.y);
Vec2d screen_delta(d.x, d.y);
apply_retina_scale(screen_position);
apply_retina_scale(screen_delta);
if (evt.IsGestureStart() || !m_gesture_pan_anchor.has_value())
m_gesture_pan_anchor = get_camera_pan_anchor(camera, ECameraNavigationType::Gesture,
screen_position - screen_delta);
pan_camera(camera, screen_delta, *m_gesture_pan_anchor);
if (evt.IsGestureEnd())
m_gesture_pan_anchor.reset();
} else if (evt.GetEventType() == wxEVT_GESTURE_ZOOM) {
static float zoom_start = 1;
if (evt.IsGestureStart())
zoom_start = camera.get_zoom();
camera.set_zoom(zoom_start * static_cast<wxZoomGestureEvent&>(evt).GetZoomFactor());
} else if (evt.GetEventType() == wxEVT_GESTURE_ROTATE) {
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
// Orca: Rotation starts a different navigation operation, so a previous pan anchor
// must not be reused; rotation and pan fallbacks share the same navigation pivot.
m_gesture_pan_anchor.reset();
bool rotate_limit = current_printer_technology() != ptSLA;
static double last_rotate = 0;
if (evt.IsGestureStart())
last_rotate = 0;
auto rotate = static_cast<wxRotateGestureEvent&>(evt).GetRotationAngle() - last_rotate;
last_rotate += rotate;
if (plate)
camera.rotate_on_sphere_with_target(-rotate, 0, rotate_limit, plate->get_bounding_box().center());
const std::optional<Vec3d> rotate_target = get_camera_orbit_target(ECameraNavigationType::Gesture);
if (rotate_target.has_value())
camera.rotate_on_sphere_with_target(-rotate, 0, rotate_limit, *rotate_target);
else
camera.rotate_on_sphere(-rotate, 0, rotate_limit);
camera.auto_type(Camera::EType::Perspective);
@@ -4339,6 +4383,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
post_event(SimpleEvent(EVT_GLCANVAS_SWITCH_TO_GLOBAL));
}
else if (evt.LeftDown() || evt.RightDown() || evt.MiddleDown()) {
// Orca: Retain the click position even if the first motion event crosses a surface edge.
m_mouse.set_start_position_2D_as_invalid();
m_mouse.drag.start_position_2D = pos;
//BBS: add orient deactivate logic
if (!m_gizmos.on_mouse(evt)) {
if (_deactivate_arrange_menu() || _deactivate_orient_menu())
@@ -4532,6 +4580,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
// do not process the dragging if the left mouse was set down in another canvas
else if (is_camera_rotate(evt, button_mappings)) {
// Orca: Rotation and panning use different drag coordinates and cached anchors.
// Clear the pan state before processing rotation or switching buttons mid-drag.
m_mouse.set_start_position_2D_as_invalid();
if (!has_mouse_capture()) // ORCA keep tracking mouse position while drag active and cursor not in window bounds
m_canvas->CaptureMouse();
@@ -4549,12 +4600,12 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (this->m_canvas_type == ECanvasType::CanvasAssembleView || m_gizmos.get_current_type() == GLGizmosManager::FdmSupports ||
m_gizmos.get_current_type() == GLGizmosManager::Seam || m_gizmos.get_current_type() == GLGizmosManager::MmSegmentation ||
m_gizmos.get_current_type() == GLGizmosManager::FuzzySkin) {
Vec3d rotate_target = Vec3d::Zero();
if (!m_selection.is_empty())
rotate_target = m_selection.get_bounding_box().center();
// Orca: Reuse the centralized pivot policy for scene-oriented tools.
const std::optional<Vec3d> rotate_target = get_camera_orbit_target(ECameraNavigationType::Mouse);
if (rotate_target.has_value())
camera.rotate_on_sphere_with_target(rot.x(), rot.y(), false, *rotate_target);
else
rotate_target = volumes_bounding_box().center();
camera.rotate_on_sphere_with_target(rot.x(), rot.y(), false, rotate_target);
camera.rotate_on_sphere(rot.x(), rot.y(), false);
}
else {
if (wxGetApp().app_config->get_bool("use_free_camera"))
@@ -4578,28 +4629,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
camera.rotate_on_sphere_with_target(rot.x(), rot.y(), rotate_limit, m_rotation_center);
} else {
Vec3d rotate_target = Vec3d::Zero();
if (m_canvas_type == ECanvasType::CanvasPreview) {
PartPlate *plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
if (plate)
rotate_target = plate->get_bounding_box().center();
}
else {
if (!m_selection.is_empty())
rotate_target = m_selection.get_bounding_box().center();
else {
// Rotate around the center of objects on current plate
auto bbox = volumes_bounding_box(true);
if (!bbox.defined) {
// Rotate around current plate center if current plate is empty
bbox = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_bounding_box();
}
rotate_target = bbox.center();
}
}
if (!rotate_target.isZero())
camera.rotate_on_sphere_with_target(rot.x(), rot.y(), rotate_limit, rotate_target);
// Orca: Keep regular mouse orbit and perspective-pan fallback centered
// on the same selection, active-plate, or scene reference.
const std::optional<Vec3d> rotate_target = get_camera_orbit_target(ECameraNavigationType::Mouse);
if (rotate_target.has_value())
camera.rotate_on_sphere_with_target(rot.x(), rot.y(), rotate_limit, *rotate_target);
else
camera.rotate_on_sphere(rot.x(), rot.y(), rotate_limit);
}
@@ -4615,16 +4649,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0);
}
else if (is_camera_pan(evt, button_mappings)) {
// Orca: Pan uses screen coordinates and must not inherit the rotation start point.
m_mouse.set_start_position_3D_as_invalid();
if (!has_mouse_capture()) // ORCA keep tracking mouse position while drag active and cursor not in window bounds
m_canvas->CaptureMouse();
// if dragging with right button or if button functions swapped and dragging with left button over blank area then pan
if (m_mouse.is_start_position_2D_defined()) {
// get point in model space at Z = 0
float z = 0.0f;
const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
Camera& camera = wxGetApp().plater()->get_camera();
if (this->m_canvas_type != ECanvasType::CanvasAssembleView) {
// Orca: Use a constrained camera when navigating the 3D scene with a regular mouse, if the free camera is not selected
@@ -4636,7 +4668,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
camera.recover_from_free_camera();
}
camera.set_target(camera.get_target() + orig - cur_pos);
// Orca: Cache the surface under the initial click and apply every incremental
// cursor delta at that depth, so perspective zoom and camera angle stay exact.
const Vec2d screen_delta =
pos.cast<double>() - m_mouse.drag.start_position_2D.cast<double>();
if (!m_mouse.drag.camera_pan_anchor.has_value())
m_mouse.drag.camera_pan_anchor = get_camera_pan_anchor(camera, ECameraNavigationType::Mouse,
m_mouse.drag.start_position_2D.cast<double>());
pan_camera(camera, screen_delta, *m_mouse.drag.camera_pan_anchor);
m_dirty = true;
m_mouse.ignore_right_up = true; // will be reset on button up event even if not right button is pressed
}
@@ -7329,11 +7368,8 @@ void GLCanvas3D::_picking_pass()
m_hover_volume_idxs.clear();
m_hover_plate_idxs.clear();
// Orca: ignore clipping plane if not applying
GLGizmoBase *current_gizmo = m_gizmos.get_current();
const ClippingPlane clipping_plane = ((!current_gizmo || current_gizmo->apply_clipping_plane()) ? m_gizmos.get_clipping_plane() :
ClippingPlane::ClipsNothing())
.inverted_normal();
// Orca: Picking and camera navigation must interpret the active gizmo clipping plane identically.
const ClippingPlane clipping_plane = get_raycaster_clipping_plane();
const SceneRaycaster::HitResult hit = m_scene_raycaster.hit(m_mouse.position, wxGetApp().plater()->get_camera(), &clipping_plane);
if (hit.is_valid()) {
switch (hit.type)
@@ -10627,6 +10663,129 @@ Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos)
return mouse_ray(mouse_pos).intersect_plane(0.0);
}
ClippingPlane GLCanvas3D::get_raycaster_clipping_plane() const
{
// Orca: Ignore the gizmo clipping plane when the active tool does not apply it, and
// invert the result into the convention expected by SceneRaycaster.
GLGizmoBase* current_gizmo = m_gizmos.get_current();
return ((!current_gizmo || current_gizmo->apply_clipping_plane()) ? m_gizmos.get_clipping_plane() :
ClippingPlane::ClipsNothing())
.inverted_normal();
}
std::optional<Vec3d> GLCanvas3D::get_camera_orbit_target(ECameraNavigationType navigation_type) const
{
// Orca: Centralize the pre-existing pivot rules so orbiting and pan fallback cannot
// choose different reference depths for the same canvas and active tool.
PartPlate* current_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
if (navigation_type == ECameraNavigationType::Gesture)
return current_plate == nullptr ? std::nullopt :
std::make_optional(current_plate->get_bounding_box().center());
const GLGizmosManager::EType gizmo_type = m_gizmos.get_current_type();
const bool use_scene_target = m_canvas_type == ECanvasType::CanvasAssembleView ||
gizmo_type == GLGizmosManager::FdmSupports || gizmo_type == GLGizmosManager::Seam ||
gizmo_type == GLGizmosManager::MmSegmentation || gizmo_type == GLGizmosManager::FuzzySkin;
if (use_scene_target) {
if (!m_selection.is_empty())
return m_selection.get_bounding_box().center();
// Orca: Preserve the world-origin fallback used by orbit in an empty scene.
return volumes_bounding_box().center();
}
// Orca: Free-camera rotation uses Camera::m_target rather than a plate or selection pivot.
if (wxGetApp().app_config->get_bool("use_free_camera"))
return std::nullopt;
Vec3d target = Vec3d::Zero();
if (m_canvas_type == ECanvasType::CanvasPreview) {
if (current_plate != nullptr)
target = current_plate->get_bounding_box().center();
} else if (!m_selection.is_empty()) {
target = m_selection.get_bounding_box().center();
} else {
// Orca: Match regular mouse orbit: objects on the active plate, then the plate itself.
BoundingBoxf3 bbox = volumes_bounding_box(true);
if (!bbox.defined && current_plate != nullptr)
bbox = current_plate->get_bounding_box();
if (bbox.defined)
target = bbox.center();
}
// Orca: Preserve the existing zero sentinel used by regular mouse orbit.
return target.isZero() ? std::nullopt : std::make_optional(target);
}
bool GLCanvas3D::is_bed_visible() const
{
if (m_canvas_type == ECanvasType::CanvasPreview)
return m_render_preview;
if (m_canvas_type != ECanvasType::CanvasView3D || !m_show_bed)
return false;
if (!m_main_toolbar.is_enabled())
return true;
const auto type = m_gizmos.get_current_type();
return type != GLGizmosManager::FdmSupports && type != GLGizmosManager::Seam &&
type != GLGizmosManager::MmSegmentation && type != GLGizmosManager::FuzzySkin;
}
Vec3d GLCanvas3D::get_camera_pan_anchor(Camera& camera, ECameraNavigationType navigation_type,
const Vec2d& screen_position) const
{
// Orthographic panning has the same scale at every depth, so no raycast is needed.
if (camera.get_type() != Camera::EType::Perspective)
return camera.get_target();
// Orca: Reject non-finite anchors and points behind the camera before their depth is
// allowed to scale a perspective pan.
const Vec3d camera_position = camera.get_position();
const Vec3d camera_forward = camera.get_dir_forward();
const auto is_valid_anchor = [&camera_position, &camera_forward](const Vec3d& anchor) {
return anchor.allFinite() && (anchor - camera_position).dot(camera_forward) > EPSILON;
};
// Orca: Prefer the nearest visible bed or volume surface and exclude gizmos and
// selected-volume picking priority from navigation depth selection.
const ClippingPlane clipping_plane = get_raycaster_clipping_plane();
const bool bed_visible = is_bed_visible();
const SceneRaycaster::HitResult hit = m_scene_raycaster.hit(screen_position, camera, &clipping_plane,
bed_visible ? SceneRaycaster::EHitMode::SceneOnly : SceneRaycaster::EHitMode::VolumesOnly);
if (hit.is_valid()) {
const Vec3d hit_position = hit.position.cast<double>();
if (is_valid_anchor(hit_position))
return hit_position;
}
// Orca: When the cursor is just outside the visible plate, use the point under it on the active
// plate plane. Using the plate center here would give it a different perspective depth.
PartPlate* current_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
// Orca: An almost edge-on perspective makes intersection depth extremely sensitive to
// the cursor's vertical position. Use the stable orbit depth around horizontal views.
static constexpr double min_plate_plane_forward_z = 0.05;
if (bed_visible && std::abs(camera_forward.z()) >= min_plate_plane_forward_z &&
current_plate != nullptr && current_plate->get_bounding_box().defined) {
Vec3d ray_origin;
Vec3d ray_direction;
CameraUtils::ray_from_screen_pos(camera, screen_position, ray_origin, ray_direction);
const double z_direction = ray_direction.z();
if (ray_origin.allFinite() && ray_direction.allFinite() && std::abs(z_direction) > EPSILON) {
const double plate_z = current_plate->get_bounding_box().center().z();
const double distance = (plate_z - ray_origin.z()) / z_direction;
const Vec3d plate_position = ray_origin + distance * ray_direction;
const double eye_depth = (plate_position - camera_position).dot(camera_forward);
if (distance >= 0.0 && is_valid_anchor(plate_position) &&
eye_depth >= camera.get_near_z() && eye_depth <= camera.get_far_z())
return plate_position;
}
}
// Orca: Near-horizontal rays and points outside the scene depth use the orbit reference point.
const std::optional<Vec3d> orbit_target = get_camera_orbit_target(navigation_type);
return orbit_target.has_value() && is_valid_anchor(*orbit_target) ? *orbit_target : camera.get_target();
}
// While it looks like we can call
// this->reload_scene(true, true)
// the two functions are quite different:
+24 -1
View File
@@ -338,6 +338,8 @@ class GLCanvas3D
int move_volume_idx{ -1 };
bool move_requires_threshold{ false };
Point move_start_threshold_position_2D{ Invalid_2D_Point };
// Orca: Keep the world-space point selected at the start of a mouse pan.
std::optional<Vec3d> camera_pan_anchor;
};
bool dragging{ false };
@@ -346,7 +348,12 @@ class GLCanvas3D
Drag drag;
bool ignore_right_up;
void set_start_position_2D_as_invalid() { drag.start_position_2D = Drag::Invalid_2D_Point; }
// Orca: The screen-space start and world-space anchor describe the same pan session.
// Invalidating one must invalidate the other so a new drag cannot reuse stale depth.
void set_start_position_2D_as_invalid() {
drag.start_position_2D = Drag::Invalid_2D_Point;
drag.camera_pan_anchor.reset();
}
void set_start_position_3D_as_invalid() { drag.start_position_3D = Drag::Invalid_3D_Point; }
void set_move_start_threshold_position_2D_as_invalid() { drag.move_start_threshold_position_2D = Drag::Invalid_2D_Point; }
@@ -549,6 +556,8 @@ private:
bool m_fps_overlay_tick{ false };
LayersEditing m_layers_editing;
Mouse m_mouse;
// Orca: Gesture pans have their own lifecycle and stable world-space anchor.
std::optional<Vec3d> m_gesture_pan_anchor;
GLGizmosManager m_gizmos;
//BBS: GUI refactor: GLToolbar
mutable GLToolbar m_main_toolbar;
@@ -1406,6 +1415,20 @@ private:
// Convert the screen space coordinate to world coordinate on the bed.
Vec3d _mouse_to_bed_3d(const Point& mouse_pos);
// Orca: Navigation type selects the legacy pivot policy used when no visible surface is hit.
enum class ECameraNavigationType : unsigned char
{
Mouse,
Gesture
};
// Orca: These helpers keep clipping, orbit pivots, and perspective-pan depth selection consistent.
ClippingPlane get_raycaster_clipping_plane() const;
bool is_bed_visible() const;
std::optional<Vec3d> get_camera_orbit_target(ECameraNavigationType navigation_type) const;
Vec3d get_camera_pan_anchor(Camera& camera, ECameraNavigationType navigation_type,
const Vec2d& screen_position) const;
void _start_timer() { m_timer.Start(100, wxTIMER_CONTINUOUS); }
void _stop_timer() { m_timer.Stop(); }
+60 -32
View File
@@ -863,8 +863,11 @@ void GUI_App::post_init()
mainframe->Freeze();
#endif
plater_->canvas3D()->enable_render(false);
mainframe->select_tab(TAB_ID_PREPARE);
mainframe->select_prepare_for_gl_init();
plater_->select_view_3D("3D");
// The first render happens before the queued new_project() sets the same view.
plater_->get_camera().select_view("topfront");
plater_->get_camera().requires_zoom_to_bed = true;
//BBS init the opengl resource here
if (!plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen() ||
!plater_->canvas3D()->make_current_for_postinit()) {
@@ -900,10 +903,10 @@ void GUI_App::post_init()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
}
}
if (is_editor())
mainframe->select_tab(TAB_ID_HOME);
if (app_config->get("default_page") == "1")
if (starts_on_prepare())
mainframe->select_tab(TAB_ID_PREPARE);
else if (is_editor())
mainframe->select_tab(TAB_ID_HOME);
#ifndef __linux__
mainframe->Thaw();
#endif
@@ -912,6 +915,7 @@ void GUI_App::post_init()
plater_->trigger_restore_project(1);
//#endif
mainframe->prebuild_pages_when_idle();
//BBS: remove GCodeViewer as seperate APP logic
/*if (this->init_params->start_as_gcodeviewer) {
@@ -1926,9 +1930,9 @@ bool GUI_App::hot_reload_network_plugin()
m_device_manager->add_user_subscribe();
}
if (mainframe && mainframe->m_monitor) {
mainframe->m_monitor->update_network_version_footer();
mainframe->m_monitor->set_default();
if (MonitorPanel* monitor = MonitorPanel::if_built()) {
monitor->update_network_version_footer();
monitor->set_default();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": reset monitor panel";
}
@@ -3419,14 +3423,16 @@ bool GUI_App::on_init_inner()
}
BOOST_LOG_TRIVIAL(info) << "create the main window";
mainframe = new MainFrame();
// hide settings tabs after first Layout
if (is_editor()) {
mainframe->select_tab(TAB_ID_HOME);
if (starts_on_prepare()) {
mainframe->select_tab(TAB_ID_PREPARE);
} else {
mainframe->select_tab(TAB_ID_HOME);
}
}
sidebar().obj_list()->init();
//sidebar().aux_list()->init_auxiliary();
mainframe->m_project->init_auxiliary();
// update_mode(); // !!! do that later
SetTopWindow(mainframe);
@@ -4137,13 +4143,13 @@ void GUI_App::select_machine(const std::string& agent_id)
// Use MonitorPanel::select_machine() to trigger full selection flow
// This reuses existing logic for machine switching (UI updates, callbacks, etc.)
if (mainframe && mainframe->m_monitor) {
mainframe->m_monitor->select_machine(dev_id);
if (MonitorPanel* monitor = MonitorPanel::if_built()) {
monitor->select_machine(dev_id);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": triggered select_machine for dev_id=" << dev_id;
} else {
// Fallback if MonitorPanel not available
m_device_manager->set_selected_machine(dev_id);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": fallback set_selected_machine dev_id=" << dev_id;
} else if (m_device_manager->set_selected_machine(dev_id)) {
// The Device tab's own state is set when the tab is built.
MonitorPanel::on_machine_selected(m_device_manager->get_selected_machine());
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": set_selected_machine dev_id=" << dev_id;
}
}
@@ -4667,6 +4673,7 @@ void GUI_App::recreate_GUI(const wxString &msg_name)
//BBS: trigger restore project logic here, and skip confirm
plater_->trigger_restore_project(1);
mainframe->prebuild_pages_when_idle();
// #ys_FIXME_delete_after_testing Do we still need this ?
// CallAfter([]() {
@@ -5008,7 +5015,8 @@ void GUI_App::get_login_info(const std::string& provider/* = ORCA_CLOUD_PROVIDER
wxString strJS = wxString::Format("window.postMessage(%s)", from_u8(logout_cmd));
GUI::wxGetApp().run_script(strJS);
}
mainframe->m_webview->SetLoginPanelVisibility(true);
if (WebViewPanel* home = WebViewPanel::if_built())
home->SetLoginPanelVisibility(true);
}
}
@@ -5140,9 +5148,9 @@ std::string GUI_App::handle_web_request(std::string cmd)
"homepage_bambu_login_or_register",
};
if (app_config->get_stealth_mode() && stealth_blocked_info_commands.count(command_str)) {
CallAfter([this] {
if (mainframe && mainframe->m_webview)
mainframe->m_webview->SendCloudProvidersInfo();
CallAfter([] {
if (WebViewPanel* home = WebViewPanel::if_built())
home->SendCloudProvidersInfo();
});
return "";
}
@@ -5156,8 +5164,8 @@ std::string GUI_App::handle_web_request(std::string cmd)
if (dlg.ShowModal() == wxID_OK) {
app_config->set_bool("stealth_mode", false);
app_config->save();
if (mainframe && mainframe->m_webview)
mainframe->m_webview->SendCloudProvidersInfo();
if (WebViewPanel* home = WebViewPanel::if_built())
home->SendCloudProvidersInfo();
// Continue with login
if (command_str == "homepage_login_or_register")
this->request_login(true);
@@ -5238,8 +5246,8 @@ std::string GUI_App::handle_web_request(std::string cmd)
}
else if (command_str.compare("get_recent_projects") == 0) {
if (mainframe) {
if (mainframe->m_webview) {
mainframe->m_webview->SendRecentList(INT_MAX);
if (WebViewPanel* home = WebViewPanel::if_built()) {
home->SendRecentList(INT_MAX);
}
}
}
@@ -7772,8 +7780,8 @@ void GUI_App::on_stealth_mode_enter()
BOOST_LOG_TRIVIAL(info) << "logout: on_stealth_mode_enter";
request_user_logout(ORCA_CLOUD_PROVIDER);
request_user_logout(BBL_CLOUD_PROVIDER);
if (mainframe && mainframe->m_webview) {
mainframe->m_webview->SendCloudProvidersInfo();
if (WebViewPanel* home = WebViewPanel::if_built()) {
home->SendCloudProvidersInfo();
}
}
@@ -8183,6 +8191,24 @@ ConfigOptionMode GUI_App::get_saved_mode()
return saved_mode_from_string(app_config->get("user_mode"));
}
bool GUI_App::starts_on_prepare() const
{
return app_config->get("default_page") == "1";
}
int GUI_App::input_idle_ms() const
{
return int(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - m_last_input).count());
}
// Every wxCommandEvent claims the user-input category, so only real mouse and key events count.
int GUI_App::FilterEvent(wxEvent& event)
{
if (!event.IsCommandEvent() && (event.GetEventCategory() & wxEVT_CATEGORY_USER_INPUT))
m_last_input = std::chrono::steady_clock::now();
return Event_Skip;
}
ConfigOptionMode GUI_App::get_mode()
{
return app_config->get_bool("developer_mode") ? comDevelop : get_saved_mode();
@@ -8234,9 +8260,10 @@ void GUI_App::update_mode()
mainframe->m_param_panel->update_mode();
if (mainframe->m_param_dialog)
mainframe->m_param_dialog->panel()->update_mode();
if (mainframe->m_printer_view)
mainframe->m_printer_view->update_mode();
mainframe->m_webview->update_mode();
if (PrinterWebView* view = PrinterWebView::if_built())
view->update_mode();
if (WebViewPanel* home = WebViewPanel::if_built())
home->update_mode();
#ifdef _MSW_DARK_MODE
if (!wxGetApp().tabs_as_menu())
@@ -8254,9 +8281,10 @@ void GUI_App::update_mode()
}
void GUI_App::update_internal_development() {
mainframe->m_webview->update_mode();
if (mainframe->m_printer_view)
mainframe->m_printer_view->update_mode();
if (WebViewPanel* home = WebViewPanel::if_built())
home->update_mode();
if (PrinterWebView* view = PrinterWebView::if_built())
view->update_mode();
}
void GUI_App::show_ip_address_enter_dialog(wxString title)
+7
View File
@@ -1,6 +1,7 @@
#ifndef slic3r_GUI_App_hpp_
#define slic3r_GUI_App_hpp_
#include <chrono>
#include <functional>
#include <memory>
#include <string>
@@ -248,6 +249,7 @@ private:
bool m_app_conf_exists{ false };
EAppMode m_app_mode{ EAppMode::Editor };
bool m_is_recreating_gui{ false };
std::chrono::steady_clock::time_point m_last_input{ std::chrono::steady_clock::now() };
#ifdef __linux__
bool m_opengl_initialized{ false };
#endif
@@ -387,6 +389,11 @@ public:
bool is_editor() const { return m_app_mode == EAppMode::Editor; }
bool is_gcode_viewer() const { return m_app_mode == EAppMode::GCodeViewer; }
bool is_recreating_gui() const { return m_is_recreating_gui; }
// Milliseconds since the last mouse or keyboard event the app processed.
int input_idle_ms() const;
int FilterEvent(wxEvent& event) override;
// The Preferences "Default page" choice, stored as its index: 0 Home, 1 Prepare.
bool starts_on_prepare() const;
std::string logo_name() const { return is_editor() ? "OrcaSlicer" : "OrcaSlicer-gcodeviewer"; }
bool is_closing() const { return m_is_closing.load(std::memory_order_acquire); }
+2 -1
View File
@@ -122,7 +122,8 @@ HMSNotifyItem::HMSNotifyItem(const std::string& dev_id, wxWindow *parent, DevHMS
m_hms_content->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
wxCommandEvent evt(EVT_ALREADY_READ_HMS);
evt.SetString(long_error_code);
wxPostEvent(wxGetApp().mainframe->m_monitor, evt);
if (MonitorPanel* monitor = MonitorPanel::if_built())
wxPostEvent(monitor, evt);
if (!m_url.empty()) wxLaunchDefaultBrowser(m_url);
});
+100
View File
@@ -0,0 +1,100 @@
#include "IdleScheduler.hpp"
#include <chrono>
#include <boost/log/trivial.hpp>
#include "libslic3r/Utils.hpp"
#ifdef _WIN32
#include <windows.h>
#endif
namespace Slic3r { namespace GUI {
namespace {
// The timer's period while waiting for the user to go quiet.
constexpr int tick_ms = 250;
// Input-free time before a slice may start, about a double-click interval, so a user
// mid-gesture is left alone.
constexpr int quiet_ms = 500;
// Budget of one slice. The next slice is a timer message, so paint, timers and input
// queued meanwhile are handled first; a click waits at most a slice plus the unit that
// overran it.
constexpr int slice_ms = 40;
// On GTK a due timer runs ahead of repaints and posted events, so the next slice waits a few ms.
#ifdef __WXGTK__
constexpr int next_slice_ms = 5;
#else
constexpr int next_slice_ms = 0;
#endif
// True when unhandled keyboard, button, touch or pen input is queued; only Windows can ask.
bool input_pending()
{
#ifdef _WIN32
// Windows synthesizes a mouse move whenever a window appears under the cursor, so those
// do not count.
return (GetQueueStatus(QS_INPUT & ~QS_MOUSEMOVE) >> 16) != 0;
#else
return false;
#endif
}
} // namespace
IdleScheduler::IdleScheduler(std::function<int()> input_idle_ms) : m_input_idle_ms(std::move(input_idle_ms))
{
m_timer.Bind(wxEVT_TIMER, [this](wxTimerEvent&) { tick(); });
}
void IdleScheduler::start()
{
if (!m_timer.IsRunning())
m_timer.Start(tick_ms);
}
void IdleScheduler::stop()
{
m_timer.Stop();
}
void IdleScheduler::tick()
{
// A unit that pumps the event loop lets the timer fire inside its own slice.
if (m_in_slice)
return;
if (!m_queue.pending()) {
stop();
return;
}
if (m_input_idle_ms() < quiet_ms || input_pending()) {
start();
return;
}
const auto now_ms = [] {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
};
const char* const fn = __FUNCTION__;
m_in_slice = true;
PrebuildQueue::Slice slice;
{
ScopeGuard in_slice([this] { m_in_slice = false; });
slice = m_queue.run_slice(slice_ms, now_ms, input_pending, [fn](const std::string& name, long long ms) {
BOOST_LOG_TRIVIAL(debug) << fn << ": " << name << ": unit took " << ms << " ms";
});
}
if (slice.completed)
BOOST_LOG_TRIVIAL(info) << fn << ": task complete: " << slice.name << ", " << slice.units << " unit(s) in " << slice.ms << " ms this slice";
else
BOOST_LOG_TRIVIAL(debug) << fn << ": " << slice.name << ": " << slice.units << " unit(s) in " << slice.ms << " ms, yielding";
if (!slice.remaining)
stop();
else if (input_pending())
m_timer.Start(tick_ms);
else
m_timer.StartOnce(next_slice_ms);
}
}} // namespace Slic3r::GUI

Some files were not shown because too many files have changed in this diff Show More