mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-28 11:21:30 +00:00
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35dc1ca6ef | ||
|
|
7f30eb8a49 | ||
|
|
b5d1866445 | ||
|
|
3b1a5c0630 | ||
|
|
18867094fa | ||
|
|
5ae88ae5c7 | ||
|
|
ea3a40d073 | ||
|
|
806568287c | ||
|
|
0342ddbe26 | ||
|
|
33af0651b7 | ||
|
|
781a5d8516 | ||
|
|
38446ab77a | ||
|
|
9080269f6f |
+45
-19
@@ -28,8 +28,8 @@ Per-vendor granularity is what makes the system practical:
|
|||||||
- A vendor whose profile is bumped invalidates only its own cache. The other 60-odd
|
- A vendor whose profile is bumped invalidates only its own cache. The other 60-odd
|
||||||
vendors keep theirs — even when the bumped vendor is the shared Orca filament
|
vendors keep theirs — even when the bumped vendor is the shared Orca filament
|
||||||
library everyone else inherits from.
|
library everyone else inherits from.
|
||||||
- The setup wizard, which loads vendors one at a time, gets the same speedup as
|
- The setup wizard loads its vendors through the same routine as startup, so it
|
||||||
startup without a second code path.
|
gets the same speedup without a second code path.
|
||||||
- A vendor with no cache, or a broken one, costs only that vendor a parse.
|
- A vendor with no cache, or a broken one, costs only that vendor a parse.
|
||||||
|
|
||||||
A cache holds *system* presets only. User presets, project settings and modified
|
A cache holds *system* presets only. User presets, project settings and modified
|
||||||
@@ -162,15 +162,20 @@ cache nothing can invalidate is worse than no cache.
|
|||||||
|
|
||||||
Vendors load in a fixed order, because filament inheritance crosses exactly one
|
Vendors load in a fixed order, because filament inheritance crosses exactly one
|
||||||
boundary: any vendor's filament may inherit from the shared Orca filament library,
|
boundary: any vendor's filament may inherit from the shared Orca filament library,
|
||||||
and nothing else reaches across vendors — an `include` is always vendor-local. The
|
and nothing else reaches across vendors — an `include` is always vendor-local. Only
|
||||||
library therefore goes first, alone; every other vendor follows in parallel, resolving
|
installing a vendor's presets crosses it; reading the vendor, from its cache or its
|
||||||
against it; and the results are merged in a stable order:
|
JSONs, needs nothing from the library. So every other vendor is read while the library
|
||||||
|
loads, each is installed against it as soon as both are done, and the results are
|
||||||
|
merged in a stable order:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart LR
|
flowchart LR
|
||||||
lib["1 · OrcaFilamentLibrary<br/>loaded first, synchronously"] --> par["2 · every other vendor in parallel,<br/>each into its own bundle, filaments<br/>resolving against the loaded library"] --> merge["3 · bundles merged into one,<br/>sequentially, in stable vendor order"]
|
lib["1 · OrcaFilamentLibrary loaded;<br/>meanwhile every other vendor read<br/>from its cache or its JSONs"] --> par["2 · every other vendor installed<br/>in parallel, each into its own bundle,<br/>filaments resolving against the library"] --> merge["3 · bundles merged into one,<br/>in one pass per collection,<br/>in stable vendor order"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`PresetBundle::load_vendors` runs these steps for startup and for the setup wizard,
|
||||||
|
which hand it the vendors to load and the directory each is installed in.
|
||||||
|
|
||||||
Whether a vendor comes from its cache or from a parse changes nothing in that
|
Whether a vendor comes from its cache or from a parse changes nothing in that
|
||||||
order — both produce the same bundle, so cached and parsed vendors mix freely in
|
order — both produce the same bundle, so cached and parsed vendors mix freely in
|
||||||
one startup.
|
one startup.
|
||||||
@@ -211,11 +216,12 @@ shipped cache answered first, so the profile in `<data_dir>/system/` was never p
|
|||||||
and its cache was never written back.
|
and its cache was never written back.
|
||||||
|
|
||||||
Serving from a cache is not a memory-image restore. The entries are deserialized and
|
Serving from a cache is not a memory-image restore. The entries are deserialized and
|
||||||
then installed one by one — inheritance resolved against the presets installed before
|
then installed by `install_vendor`, the routine the JSON path hands the vendor's entries
|
||||||
them and the currently loaded filament library, includes layered in, configs flattened
|
to once it has parsed the sub-files: inheritance resolved against the presets installed
|
||||||
onto the collection defaults, validated and registered — by the same function the JSON
|
before them and the currently loaded filament library, includes layered in, configs
|
||||||
path calls straight after parsing a sub-file. An `include` layers what the included
|
flattened onto the collection defaults, validated and registered. An `include` layers
|
||||||
base states, between the parent and the preset's own keys: the base's diff against the
|
what the included base states, between the parent and the preset's own keys: the base's
|
||||||
|
diff against the
|
||||||
default, taken when the base itself was installed and before the per-variant padding
|
default, taken when the base itself was installed and before the per-variant padding
|
||||||
`inherits` sees, so only what a template sets reaches the presets including it. The two
|
`inherits` sees, so only what a template sets reaches the presets including it. The two
|
||||||
paths share everything below the parse, which is what makes a cache-loaded bundle
|
paths share everything below the parse, which is what makes a cache-loaded bundle
|
||||||
@@ -223,6 +229,16 @@ indistinguishable from a JSON-loaded one by construction rather than by test cov
|
|||||||
Installation also rebuilds each preset's file path from the local data directory, so a
|
Installation also rebuilds each preset's file path from the local data directory, so a
|
||||||
shipped cache never carries the generating machine's paths.
|
shipped cache never carries the generating machine's paths.
|
||||||
|
|
||||||
|
Installing an entry is split in two. `resolve_vendor_preset` flattens it, reading only
|
||||||
|
what is registered under the names it inherits and includes, and `commit_vendor_preset`
|
||||||
|
registers it, the only step that writes anything shared. Entries resolve across threads
|
||||||
|
in runs and commit in the order the vendor lists them. A run ends before an entry that
|
||||||
|
inherits or includes one already in it, since that one's commit registers what the
|
||||||
|
entry resolves against, so no entry in a run reads what another in it registers. An
|
||||||
|
entry's parse messages are held until it commits. The bundle, the log's parse and
|
||||||
|
install messages and the error count therefore come out as parsing and installing one
|
||||||
|
entry at a time would leave them, whatever the listing order.
|
||||||
|
|
||||||
App upgrades work because a cache normally survives one. Only a deliberate
|
App upgrades work because a cache normally survives one. Only a deliberate
|
||||||
`CACHE_VERSION` bump makes an installed cache unreadable, and that is handled at
|
`CACHE_VERSION` bump makes an installed cache unreadable, and that is handled at
|
||||||
install time rather than at load: a vendor whose cache this build cannot read counts
|
install time rather than at load: a vendor whose cache this build cannot read counts
|
||||||
@@ -254,17 +270,20 @@ the wizard caches the *derived JSON*, not another form of the inputs:
|
|||||||
open, the wizard computes the current stamps (one version peek per vendor) and, when
|
open, the wizard computes the current stamps (one version peek per vendor) and, when
|
||||||
they match, serves the catalog from the file — no bundle built, no preset installed.
|
they match, serves the catalog from the file — no bundle built, no preset installed.
|
||||||
Caching bundle inputs instead was tried and measured: rebuilding the bundle from
|
Caching bundle inputs instead was tried and measured: rebuilding the bundle from
|
||||||
per-vendor caches costs ~2 s of preset installation whatever feeds it, so only
|
per-vendor caches costs over a second of preset installation whatever feeds it, so
|
||||||
skipping the rebuild entirely wins.
|
only skipping the rebuild entirely wins.
|
||||||
|
|
||||||
Any change to the set — a vendor added, removed or updated, or its cache-only
|
Any change to the set — a vendor added, removed or updated, or its cache-only
|
||||||
`.opc` replaced by a newer one — changes the stamps and retires the whole file;
|
`.opc` replaced by a newer one — changes the stamps and retires the whole file;
|
||||||
the wizard then rebuilds the bundle vendor by vendor (per-vendor caches serving where
|
the wizard then rebuilds the bundle with `PresetBundle::load_vendors`, the load
|
||||||
they cover) and writes the catalog back. Selections, region and per-open decorations
|
startup uses (per-vendor caches serving where they cover), and writes the catalog
|
||||||
are applied downstream of the cache either way, so a served catalog is
|
back. When a vendor fails to load, the filament library included, that open falls
|
||||||
indistinguishable from a rebuilt one. Nothing ships this file and the updater never
|
back to the wizard's own scan of the vendor JSONs, as when no bundle can be built,
|
||||||
touches it; it is a locally written artifact, re-derived whenever stale, written
|
and writes nothing. Selections, region and per-open decorations are applied
|
||||||
through a temp file and rename so half a cache is never readable.
|
downstream of the cache either way, so a served catalog is indistinguishable from a
|
||||||
|
rebuilt one. Nothing ships this file and the updater never touches it; it is a
|
||||||
|
locally written artifact, re-derived whenever stale, written through a temp file and
|
||||||
|
rename so half a cache is never readable.
|
||||||
|
|
||||||
The cache lives under `<data_dir>/cache/`, not beside the vendors: everything that
|
The cache lives under `<data_dir>/cache/`, not beside the vendors: everything that
|
||||||
scans `<data_dir>/system/` treats any `.opc` there as a vendor, so a non-vendor
|
scans `<data_dir>/system/` treats any `.opc` there as a vendor, so a non-vendor
|
||||||
@@ -378,6 +397,13 @@ enumerates only `*.json` will find no vendors at all in a packaged build.
|
|||||||
the `CachedPreset` field list — written and read by `visit_entry` in
|
the `CachedPreset` field list — written and read by `visit_entry` in
|
||||||
`PresetCacheFormat.cpp`, one list for the save, the load and the name peek alike — or
|
`PresetCacheFormat.cpp`, one list for the save, the load and the name peek alike — or
|
||||||
the cache's own layout or stamps, requires bumping `CACHE_VERSION` by hand.
|
the cache's own layout or stamps, requires bumping `CACHE_VERSION` by hand.
|
||||||
|
- **Adding a kind of reference between presets**, as `inherits` and `include` are:
|
||||||
|
parse the names into `CachedPreset` (a field change, so `CACHE_VERSION` is bumped),
|
||||||
|
have `install_vendor_entries` end a run before an entry that names one already in it
|
||||||
|
and retain what the names point at, look them up only in `resolve_vendor_preset`, and
|
||||||
|
register what they point at only in `commit_vendor_preset`. The listing-order test in
|
||||||
|
`test_vendor_cache.cpp` fails for a kind the runs do not check once its fixture uses
|
||||||
|
it.
|
||||||
- **The dictionary indexes with a `uint16`**, so `print_config_def` may hold at most
|
- **The dictionary indexes with a `uint16`**, so `print_config_def` may hold at most
|
||||||
65535 options and one cache at most 65535 distinct enum value names.
|
65535 options and one cache at most 65535 distinct enum value names.
|
||||||
`CacheDictionary::save` throws past that, which surfaces when CI generates the
|
`CacheDictionary::save` throws past that, which surfaces when CI generates the
|
||||||
|
|||||||
+55
-155
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Blocks",
|
"name": "Blocks",
|
||||||
"version": "02.04.00.13",
|
"version": "02.04.00.04",
|
||||||
"force_update": "0",
|
"force_update": "0",
|
||||||
"description": "Blocks configurations",
|
"description": "Blocks configurations",
|
||||||
"machine_model_list": [
|
"machine_model_list": [
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
"sub_path": "process/0.16mm Optimal 0.4 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.16mm Optimal 0.4 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.20mm Standard 0.4 nozzle @Blocks_Pro_S100",
|
"name": "0.20mm Standard 0.4 nozzle @Blocks",
|
||||||
"sub_path": "process/0.20mm Standard 0.4 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.20mm Standard 0.4 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.20mm Standard 0.4 nozzle @Blocks_RD50_V2",
|
"name": "0.20mm Standard 0.4 nozzle @Blocks_RD50_V2",
|
||||||
@@ -55,8 +55,8 @@
|
|||||||
"sub_path": "process/0.20mm Standard 0.4 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.20mm Standard 0.4 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.24mm Draft 0.4 nozzle @Blocks_Pro_S100",
|
"name": "0.24mm Draft 0.4 nozzle @Blocks",
|
||||||
"sub_path": "process/0.24mm Draft 0.4 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.24mm Draft 0.4 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.24mm Draft 0.4 nozzle @Blocks_RD50_V2",
|
"name": "0.24mm Draft 0.4 nozzle @Blocks_RD50_V2",
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
"sub_path": "process/0.28mm Extra Draft 0.4 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.28mm Extra Draft 0.4 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Extra Draft 0.4 nozzle @Blocks",
|
||||||
"sub_path": "process/0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.30mm Extra Draft 0.4 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "fdm_process_common 0.6 nozzle",
|
"name": "fdm_process_common 0.6 nozzle",
|
||||||
@@ -111,8 +111,8 @@
|
|||||||
"sub_path": "process/0.26mm Standard 0.6 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.26mm Standard 0.6 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.30mm Standard 0.6 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Standard 0.6 nozzle @Blocks",
|
||||||
"sub_path": "process/0.30mm Standard 0.6 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.30mm Standard 0.6 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.32mm Draft 0.6 nozzle @Blocks_RD50_V2",
|
"name": "0.32mm Draft 0.6 nozzle @Blocks_RD50_V2",
|
||||||
@@ -131,12 +131,12 @@
|
|||||||
"sub_path": "process/0.38mm Extra Draft 0.6 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.38mm Extra Draft 0.6 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.40mm Draft 0.6 nozzle @Blocks_Pro_S100",
|
"name": "0.40mm Draft 0.6 nozzle @Blocks",
|
||||||
"sub_path": "process/0.40mm Draft 0.6 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.40mm Draft 0.6 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Optimal 0.8 nozzle @Blocks",
|
||||||
"sub_path": "process/0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.30mm Optimal 0.8 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.30mm Optimal 0.8 nozzle @Blocks_RD50_V2",
|
"name": "0.30mm Optimal 0.8 nozzle @Blocks_RD50_V2",
|
||||||
@@ -155,8 +155,8 @@
|
|||||||
"sub_path": "process/0.38mm Standard 0.8 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.38mm Standard 0.8 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.40mm Standard 0.8 nozzle @Blocks_Pro_S100",
|
"name": "0.40mm Standard 0.8 nozzle @Blocks",
|
||||||
"sub_path": "process/0.40mm Standard 0.8 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.40mm Standard 0.8 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.46mm Draft 0.8 nozzle @Blocks_RD50_V2",
|
"name": "0.46mm Draft 0.8 nozzle @Blocks_RD50_V2",
|
||||||
@@ -167,8 +167,8 @@
|
|||||||
"sub_path": "process/0.46mm Draft 0.8 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.46mm Draft 0.8 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.50mm Draft 0.8 nozzle @Blocks_Pro_S100",
|
"name": "0.50mm Draft 0.8 nozzle @Blocks",
|
||||||
"sub_path": "process/0.50mm Draft 0.8 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.50mm Draft 0.8 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.54mm Extra Draft 0.8 nozzle @Blocks_RD50_V2",
|
"name": "0.54mm Extra Draft 0.8 nozzle @Blocks_RD50_V2",
|
||||||
@@ -179,36 +179,36 @@
|
|||||||
"sub_path": "process/0.54mm Extra Draft 0.8 nozzle @Blocks_RF50.json"
|
"sub_path": "process/0.54mm Extra Draft 0.8 nozzle @Blocks_RF50.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Optimal 1.0 nozzle @Blocks",
|
||||||
"sub_path": "process/0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.30mm Optimal 1.0 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.50mm Standard 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.50mm Standard 1.0 nozzle @Blocks",
|
||||||
"sub_path": "process/0.50mm Standard 1.0 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.50mm Standard 1.0 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.60mm Draft 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.60mm Draft 1.0 nozzle @Blocks",
|
||||||
"sub_path": "process/0.60mm Draft 1.0 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.60mm Draft 1.0 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.70mm Extra Draft 1.0 nozzle @Blocks",
|
||||||
"sub_path": "process/0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.70mm Extra Draft 1.0 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.50mm Optimal 1.2 nozzle @Blocks",
|
||||||
"sub_path": "process/0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.50mm Optimal 1.2 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.60mm Standard 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.60mm Standard 1.2 nozzle @Blocks",
|
||||||
"sub_path": "process/0.60mm Standard 1.2 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.60mm Standard 1.2 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.70mm Draft 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.70mm Draft 1.2 nozzle @Blocks",
|
||||||
"sub_path": "process/0.70mm Draft 1.2 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.70mm Draft 1.2 nozzle @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.80mm Extra Draft 1.2 nozzle @Blocks",
|
||||||
"sub_path": "process/0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100.json"
|
"sub_path": "process/0.80mm Extra Draft 1.2 nozzle @Blocks.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filament_list": [
|
"filament_list": [
|
||||||
@@ -249,148 +249,48 @@
|
|||||||
"sub_path": "filament/fdm_filament_tpu.json"
|
"sub_path": "filament/fdm_filament_tpu.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks ABS @base",
|
"name": "Generic ABS @Blocks",
|
||||||
"sub_path": "filament/Blocks ABS @base.json"
|
"sub_path": "filament/Generic ABS @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks ASA @base",
|
"name": "Generic ASA @Blocks",
|
||||||
"sub_path": "filament/Blocks ASA @base.json"
|
"sub_path": "filament/Generic ASA @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks ASA-CF @base",
|
"name": "Generic ASA-CF @Blocks",
|
||||||
"sub_path": "filament/Blocks ASA-CF @base.json"
|
"sub_path": "filament/Generic ASA-CF @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PA @base",
|
"name": "Generic PA @Blocks",
|
||||||
"sub_path": "filament/Blocks PA @base.json"
|
"sub_path": "filament/Generic PA @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PA-CF @base",
|
"name": "Generic PA-CF @Blocks",
|
||||||
"sub_path": "filament/Blocks PA-CF @base.json"
|
"sub_path": "filament/Generic PA-CF @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PC @base",
|
"name": "Generic PC @Blocks",
|
||||||
"sub_path": "filament/Blocks PC @base.json"
|
"sub_path": "filament/Generic PC @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PETG @base",
|
"name": "Generic PETG @Blocks",
|
||||||
"sub_path": "filament/Blocks PETG @base.json"
|
"sub_path": "filament/Generic PETG @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PLA @base",
|
"name": "Generic PLA @Blocks",
|
||||||
"sub_path": "filament/Blocks PLA @base.json"
|
"sub_path": "filament/Generic PLA @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PLA-CF @base",
|
"name": "Generic PLA-CF @Blocks",
|
||||||
"sub_path": "filament/Blocks PLA-CF @base.json"
|
"sub_path": "filament/Generic PLA-CF @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks PVA @base",
|
"name": "Generic PVA @Blocks",
|
||||||
"sub_path": "filament/Blocks PVA @base.json"
|
"sub_path": "filament/Generic PVA @Blocks.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Blocks TPU @base",
|
"name": "Generic TPU @Blocks",
|
||||||
"sub_path": "filament/Blocks TPU @base.json"
|
"sub_path": "filament/Generic TPU @Blocks.json"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks ABS @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks ABS @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks ABS @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks ABS @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks ASA @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks ASA @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks ASA @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks ASA @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks ASA-CF @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks ASA-CF @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks ASA-CF @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks ASA-CF @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PA @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PA @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PA @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PA @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PA-CF @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PA-CF @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PA-CF @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PA-CF @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PC @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PC @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PC @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PC @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PETG @Blocks_Pro_S100",
|
|
||||||
"sub_path": "filament/Blocks PETG @Blocks_Pro_S100.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PETG @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PETG @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PETG @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PETG @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PLA @Blocks_Pro_S100",
|
|
||||||
"sub_path": "filament/Blocks PLA @Blocks_Pro_S100.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PLA @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PLA @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PLA @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PLA @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PLA-CF @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PLA-CF @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PLA-CF @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PLA-CF @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PVA @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks PVA @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks PVA @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks PVA @Blocks_RF50.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks TPU @Blocks_Pro_S100",
|
|
||||||
"sub_path": "filament/Blocks TPU @Blocks_Pro_S100.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks TPU @Blocks_RD50_V2",
|
|
||||||
"sub_path": "filament/Blocks TPU @Blocks_RD50_V2.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Blocks TPU @Blocks_RF50",
|
|
||||||
"sub_path": "filament/Blocks TPU @Blocks_RF50.json"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"machine_list": [
|
"machine_list": [
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks ABS @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks ABS @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "qhQ0qQDGJgsueCAF",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic ABS;Generic ABS @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks ABS @Blocks_RF50",
|
|
||||||
"inherits": "Blocks ABS @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "bGYMFFdKiROKuSiY",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks ASA @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks ASA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "HW7xDXThvpVFbMq5",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic ASA;Generic ASA @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks ASA @Blocks_RF50",
|
|
||||||
"inherits": "Blocks ASA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "lBW7SCsvawi4icNU",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks ASA-CF @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks ASA-CF @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "x5ksnGLGGy1PgDns",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic ASA-CF;Generic ASA-CF @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks ASA-CF @Blocks_RF50",
|
|
||||||
"inherits": "Blocks ASA-CF @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "pcbd5qFiMZAvDPg1",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PA @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "gxD81n2jjrReLD29",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PA;Generic PA @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PA @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "PzKxRMDnQUzVWRer",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PA @base",
|
|
||||||
"inherits": "fdm_filament_pa",
|
|
||||||
"from": "system",
|
|
||||||
"filament_id": "OFidOgK4",
|
|
||||||
"instantiation": "false",
|
|
||||||
"filament_vendor": [
|
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
|
||||||
"0.98"
|
|
||||||
],
|
|
||||||
"filament_max_volumetric_speed": [
|
|
||||||
"10"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PA-CF @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PA-CF @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "EtbeKx3rbhUo1TtM",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PA-CF;Generic PA-CF @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PA-CF @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PA-CF @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "udI8Q4X7HaPIaPt4",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PC @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PC @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "HLc0shWnKwJzSFyW",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PC;Generic PC @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PC @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PC @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "9a6bccZopMTeNHYu",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PC @base",
|
|
||||||
"inherits": "fdm_filament_pc",
|
|
||||||
"from": "system",
|
|
||||||
"filament_id": "OFlGY0MN",
|
|
||||||
"instantiation": "false",
|
|
||||||
"filament_vendor": [
|
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
|
||||||
"0.94"
|
|
||||||
],
|
|
||||||
"filament_max_volumetric_speed": [
|
|
||||||
"10"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PETG @Blocks_Pro_S100",
|
|
||||||
"inherits": "Blocks PETG @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "AhMR49fcFqtrQ6hI",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS Pro S100 0.4 nozzle",
|
|
||||||
"BLOCKS Pro S100 0.6 nozzle",
|
|
||||||
"BLOCKS Pro S100 0.8 nozzle",
|
|
||||||
"BLOCKS Pro S100 1.0 nozzle",
|
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PETG;Generic PETG @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PETG @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PETG @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "3v7ah1zVG8MERPSJ",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PETG @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PETG @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "S7weR19wo9meJ6Yz",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PLA @Blocks_Pro_S100",
|
|
||||||
"inherits": "Blocks PLA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "vWojuLYIfduLGFLL",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS Pro S100 0.4 nozzle",
|
|
||||||
"BLOCKS Pro S100 0.6 nozzle",
|
|
||||||
"BLOCKS Pro S100 0.8 nozzle",
|
|
||||||
"BLOCKS Pro S100 1.0 nozzle",
|
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PLA;Generic PLA @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PLA @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PLA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "y7y8NcXNdp17sJUs",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PLA @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PLA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "jt1MJF4eZzkkscEJ",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PLA-CF @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PLA-CF @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "lhBtMKP1DmOB3HOI",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PLA-CF;Generic PLA-CF @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PLA-CF @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PLA-CF @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "6CU83mAyhcZ4FCPI",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PLA-CF @base",
|
|
||||||
"inherits": "fdm_filament_pla",
|
|
||||||
"from": "system",
|
|
||||||
"filament_id": "OF6FfwOP",
|
|
||||||
"instantiation": "false",
|
|
||||||
"filament_vendor": [
|
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
|
||||||
"0.95"
|
|
||||||
],
|
|
||||||
"filament_max_volumetric_speed": [
|
|
||||||
"20"
|
|
||||||
],
|
|
||||||
"filament_type": [
|
|
||||||
"PLA-CF"
|
|
||||||
],
|
|
||||||
"slow_down_layer_time": [
|
|
||||||
"7"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PVA @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks PVA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "hREDqwKF6qyKkakp",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic PVA;Generic PVA @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PVA @Blocks_RF50",
|
|
||||||
"inherits": "Blocks PVA @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "q6pKqHY7Iz4OZaAC",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks PVA @base",
|
|
||||||
"inherits": "fdm_filament_pva",
|
|
||||||
"from": "system",
|
|
||||||
"filament_id": "OFqcNuE1",
|
|
||||||
"instantiation": "false",
|
|
||||||
"filament_vendor": [
|
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
|
||||||
"0.98"
|
|
||||||
],
|
|
||||||
"filament_max_volumetric_speed": [
|
|
||||||
"20"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks TPU @Blocks_Pro_S100",
|
|
||||||
"inherits": "Blocks TPU @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "6Rkz2je91JRTRoTi",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS Pro S100 0.4 nozzle",
|
|
||||||
"BLOCKS Pro S100 0.6 nozzle",
|
|
||||||
"BLOCKS Pro S100 0.8 nozzle",
|
|
||||||
"BLOCKS Pro S100 1.0 nozzle",
|
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
|
||||||
],
|
|
||||||
"renamed_from": "Blocks Generic TPU;Generic TPU @Blocks"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks TPU @Blocks_RD50_V2",
|
|
||||||
"inherits": "Blocks TPU @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "mkCqRQTtXldzoEUg",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RD50 V2 0.4 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.6 nozzle",
|
|
||||||
"BLOCKS RD50 V2 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "filament",
|
|
||||||
"name": "Blocks TPU @Blocks_RF50",
|
|
||||||
"inherits": "Blocks TPU @base",
|
|
||||||
"from": "system",
|
|
||||||
"setting_id": "bCCvu5Ow1JkwIrRR",
|
|
||||||
"instantiation": "true",
|
|
||||||
"compatible_printers": [
|
|
||||||
"BLOCKS RF50 0.4 nozzle",
|
|
||||||
"BLOCKS RF50 0.6 nozzle",
|
|
||||||
"BLOCKS RF50 0.8 nozzle"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
+13
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks ABS @base",
|
"name": "Generic ABS @Blocks",
|
||||||
"inherits": "fdm_filament_abs",
|
"inherits": "fdm_filament_abs",
|
||||||
|
"renamed_from": "Blocks Generic ABS",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OFBBhiX8",
|
"setting_id": "TL1Q1kA4t36GGObG",
|
||||||
"instantiation": "false",
|
"filament_id": "OFY9muEs",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
"filament_flow_ratio": [
|
||||||
"0.95"
|
"0.95"
|
||||||
],
|
],
|
||||||
@@ -82,5 +81,13 @@
|
|||||||
],
|
],
|
||||||
"during_print_exhaust_fan_speed": [
|
"during_print_exhaust_fan_speed": [
|
||||||
"100"
|
"100"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+13
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks ASA @base",
|
"name": "Generic ASA @Blocks",
|
||||||
"inherits": "fdm_filament_asa",
|
"inherits": "fdm_filament_asa",
|
||||||
|
"renamed_from": "Blocks Generic ASA",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OFTz2YXa",
|
"setting_id": "xP7cB4RHgbm4cYDD",
|
||||||
"instantiation": "false",
|
"filament_id": "OFLPAxz3",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
"filament_flow_ratio": [
|
||||||
"0.95"
|
"0.95"
|
||||||
],
|
],
|
||||||
@@ -82,5 +81,13 @@
|
|||||||
],
|
],
|
||||||
"during_print_exhaust_fan_speed": [
|
"during_print_exhaust_fan_speed": [
|
||||||
"100"
|
"100"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+13
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks ASA-CF @base",
|
"name": "Generic ASA-CF @Blocks",
|
||||||
"inherits": "fdm_filament_asa",
|
"inherits": "fdm_filament_asa",
|
||||||
|
"renamed_from": "Blocks Generic ASA-CF",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OF8b9I7o",
|
"setting_id": "ju4ue7yJoz3ujny6",
|
||||||
"instantiation": "false",
|
"filament_id": "OF53eLVD",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_type": [
|
"filament_type": [
|
||||||
"ASA-CF"
|
"ASA-CF"
|
||||||
],
|
],
|
||||||
@@ -85,5 +84,13 @@
|
|||||||
],
|
],
|
||||||
"during_print_exhaust_fan_speed": [
|
"during_print_exhaust_fan_speed": [
|
||||||
"100"
|
"100"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "Generic PA @Blocks",
|
||||||
|
"inherits": "fdm_filament_pa",
|
||||||
|
"renamed_from": "Blocks Generic PA",
|
||||||
|
"from": "system",
|
||||||
|
"setting_id": "hL3p8gAeciwDkjNK",
|
||||||
|
"filament_id": "OFg8ndtj",
|
||||||
|
"instantiation": "true",
|
||||||
|
"filament_flow_ratio": [
|
||||||
|
"0.98"
|
||||||
|
],
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"10"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
|
]
|
||||||
|
}
|
||||||
+13
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks PA-CF @base",
|
"name": "Generic PA-CF @Blocks",
|
||||||
"inherits": "fdm_filament_pa",
|
"inherits": "fdm_filament_pa",
|
||||||
|
"renamed_from": "Blocks Generic PA-CF",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OFdWrXpL",
|
"setting_id": "T6SO0WRdnG6wcyG8",
|
||||||
"instantiation": "false",
|
"filament_id": "OFQLcbps",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_type": [
|
"filament_type": [
|
||||||
"PA-CF"
|
"PA-CF"
|
||||||
],
|
],
|
||||||
@@ -88,5 +87,13 @@
|
|||||||
],
|
],
|
||||||
"during_print_exhaust_fan_speed": [
|
"during_print_exhaust_fan_speed": [
|
||||||
"80"
|
"80"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "Generic PC @Blocks",
|
||||||
|
"inherits": "fdm_filament_pc",
|
||||||
|
"renamed_from": "Blocks Generic PC",
|
||||||
|
"from": "system",
|
||||||
|
"setting_id": "Xhs8PjtmwwVj0ksE",
|
||||||
|
"filament_id": "OFLakOUI",
|
||||||
|
"instantiation": "true",
|
||||||
|
"filament_flow_ratio": [
|
||||||
|
"0.94"
|
||||||
|
],
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"10"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
|
]
|
||||||
|
}
|
||||||
+18
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks PETG @base",
|
"name": "Generic PETG @Blocks",
|
||||||
"inherits": "fdm_filament_petg",
|
"inherits": "fdm_filament_petg",
|
||||||
|
"renamed_from": "Blocks Generic PETG",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OF9t1Ga0",
|
"setting_id": "NgzPlYItKHbmGgv3",
|
||||||
"instantiation": "false",
|
"filament_id": "OFYPdQJh",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
"filament_flow_ratio": [
|
||||||
"0.94"
|
"0.94"
|
||||||
],
|
],
|
||||||
@@ -82,5 +81,18 @@
|
|||||||
],
|
],
|
||||||
"slow_down_layer_time": [
|
"slow_down_layer_time": [
|
||||||
"5"
|
"5"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS Pro S100 0.4 nozzle",
|
||||||
|
"BLOCKS Pro S100 0.6 nozzle",
|
||||||
|
"BLOCKS Pro S100 0.8 nozzle",
|
||||||
|
"BLOCKS Pro S100 1.0 nozzle",
|
||||||
|
"BLOCKS Pro S100 1.2 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+18
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks PLA @base",
|
"name": "Generic PLA @Blocks",
|
||||||
"inherits": "fdm_filament_pla",
|
"inherits": "fdm_filament_pla",
|
||||||
|
"renamed_from": "Blocks Generic PLA",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OFVGAC8g",
|
"setting_id": "kjhuttx4T8OtTNmV",
|
||||||
"instantiation": "false",
|
"filament_id": "OFDSrzZ8",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_flow_ratio": [
|
"filament_flow_ratio": [
|
||||||
"0.95"
|
"0.95"
|
||||||
],
|
],
|
||||||
@@ -40,5 +39,18 @@
|
|||||||
],
|
],
|
||||||
"during_print_exhaust_fan_speed": [
|
"during_print_exhaust_fan_speed": [
|
||||||
"100"
|
"100"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS Pro S100 0.4 nozzle",
|
||||||
|
"BLOCKS Pro S100 0.6 nozzle",
|
||||||
|
"BLOCKS Pro S100 0.8 nozzle",
|
||||||
|
"BLOCKS Pro S100 1.0 nozzle",
|
||||||
|
"BLOCKS Pro S100 1.2 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "Generic PLA-CF @Blocks",
|
||||||
|
"inherits": "fdm_filament_pla",
|
||||||
|
"renamed_from": "Blocks Generic PLA-CF",
|
||||||
|
"from": "system",
|
||||||
|
"setting_id": "oKUqzwAWMrpiyGLf",
|
||||||
|
"filament_id": "OFWbdGsC",
|
||||||
|
"instantiation": "true",
|
||||||
|
"filament_flow_ratio": [
|
||||||
|
"0.95"
|
||||||
|
],
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"20"
|
||||||
|
],
|
||||||
|
"filament_type": [
|
||||||
|
"PLA-CF"
|
||||||
|
],
|
||||||
|
"slow_down_layer_time": [
|
||||||
|
"7"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "Generic PVA @Blocks",
|
||||||
|
"inherits": "fdm_filament_pva",
|
||||||
|
"renamed_from": "Blocks Generic PVA",
|
||||||
|
"from": "system",
|
||||||
|
"setting_id": "tNw3oe7VovLkgUbB",
|
||||||
|
"filament_id": "OFDvXujf",
|
||||||
|
"instantiation": "true",
|
||||||
|
"filament_flow_ratio": [
|
||||||
|
"0.98"
|
||||||
|
],
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"20"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
|
]
|
||||||
|
}
|
||||||
+18
-6
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"type": "filament",
|
"type": "filament",
|
||||||
"name": "Blocks TPU @base",
|
"name": "Generic TPU @Blocks",
|
||||||
"inherits": "fdm_filament_tpu",
|
"inherits": "fdm_filament_tpu",
|
||||||
|
"renamed_from": "Blocks Generic TPU",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OFYnedOZ",
|
"setting_id": "6iVYOCZo8ugs4JA0",
|
||||||
"instantiation": "false",
|
"filament_id": "OFgbpcy9",
|
||||||
"filament_vendor": [
|
"instantiation": "true",
|
||||||
"Blocks"
|
|
||||||
],
|
|
||||||
"filament_max_volumetric_speed": [
|
"filament_max_volumetric_speed": [
|
||||||
"4"
|
"4"
|
||||||
],
|
],
|
||||||
@@ -55,5 +54,18 @@
|
|||||||
],
|
],
|
||||||
"during_print_exhaust_fan_speed": [
|
"during_print_exhaust_fan_speed": [
|
||||||
"80"
|
"80"
|
||||||
|
],
|
||||||
|
"compatible_printers": [
|
||||||
|
"BLOCKS Pro S100 0.4 nozzle",
|
||||||
|
"BLOCKS Pro S100 0.6 nozzle",
|
||||||
|
"BLOCKS Pro S100 0.8 nozzle",
|
||||||
|
"BLOCKS Pro S100 1.0 nozzle",
|
||||||
|
"BLOCKS Pro S100 1.2 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.4 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.6 nozzle",
|
||||||
|
"BLOCKS RD50 V2 0.8 nozzle",
|
||||||
|
"BLOCKS RF50 0.4 nozzle",
|
||||||
|
"BLOCKS RF50 0.6 nozzle",
|
||||||
|
"BLOCKS RF50 0.8 nozzle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
"setting_id": "G7HQgaspHXduDM8O",
|
"setting_id": "G7HQgaspHXduDM8O",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"printer_model": "BLOCKS Pro S100",
|
"printer_model": "BLOCKS Pro S100",
|
||||||
"default_print_profile": "0.20mm Standard 0.4 nozzle @Blocks_Pro_S100",
|
"default_print_profile": "0.20mm Standard 0.4 nozzle @Blocks",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.30"
|
"0.30"
|
||||||
],
|
],
|
||||||
@@ -25,8 +25,5 @@
|
|||||||
"printable_height": "900",
|
"printable_height": "900",
|
||||||
"upward_compatible_machine": [
|
"upward_compatible_machine": [
|
||||||
"BLOCKS Pro S100"
|
"BLOCKS Pro S100"
|
||||||
],
|
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_Pro_S100"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"setting_id": "XkWdS210oUMQN17N",
|
"setting_id": "XkWdS210oUMQN17N",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"printer_model": "BLOCKS Pro S100",
|
"printer_model": "BLOCKS Pro S100",
|
||||||
"default_print_profile": "0.30mm Standard 0.6 nozzle @Blocks_Pro_S100",
|
"default_print_profile": "0.30mm Standard 0.6 nozzle @Blocks",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.50"
|
"0.50"
|
||||||
],
|
],
|
||||||
@@ -26,8 +26,5 @@
|
|||||||
"upward_compatible_machine": [
|
"upward_compatible_machine": [
|
||||||
"BLOCKS Pro S100"
|
"BLOCKS Pro S100"
|
||||||
],
|
],
|
||||||
"printer_variant": "0.6",
|
"printer_variant": "0.6"
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_Pro_S100"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"setting_id": "I6PdeCS7SbvIlkZf",
|
"setting_id": "I6PdeCS7SbvIlkZf",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"printer_model": "BLOCKS Pro S100",
|
"printer_model": "BLOCKS Pro S100",
|
||||||
"default_print_profile": "0.40mm Standard 0.8 nozzle @Blocks_Pro_S100",
|
"default_print_profile": "0.40mm Standard 0.8 nozzle @Blocks",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.56"
|
"0.56"
|
||||||
],
|
],
|
||||||
@@ -26,8 +26,5 @@
|
|||||||
"upward_compatible_machine": [
|
"upward_compatible_machine": [
|
||||||
"BLOCKS Pro S100"
|
"BLOCKS Pro S100"
|
||||||
],
|
],
|
||||||
"printer_variant": "0.8",
|
"printer_variant": "0.8"
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_Pro_S100"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"setting_id": "elLdUyy9RhUoa37o",
|
"setting_id": "elLdUyy9RhUoa37o",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"printer_model": "BLOCKS Pro S100",
|
"printer_model": "BLOCKS Pro S100",
|
||||||
"default_print_profile": "0.50mm Standard 1.0 nozzle @Blocks_Pro_S100",
|
"default_print_profile": "0.50mm Standard 1.0 nozzle @Blocks",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.7"
|
"0.7"
|
||||||
],
|
],
|
||||||
@@ -26,8 +26,5 @@
|
|||||||
"upward_compatible_machine": [
|
"upward_compatible_machine": [
|
||||||
"BLOCKS Pro S100"
|
"BLOCKS Pro S100"
|
||||||
],
|
],
|
||||||
"printer_variant": "1.0",
|
"printer_variant": "1.0"
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_Pro_S100"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"setting_id": "xtsGSJ4JkbHTPi44",
|
"setting_id": "xtsGSJ4JkbHTPi44",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"printer_model": "BLOCKS Pro S100",
|
"printer_model": "BLOCKS Pro S100",
|
||||||
"default_print_profile": "0.60mm Standard 1.2 nozzle @Blocks_Pro_S100",
|
"default_print_profile": "0.60mm Standard 1.2 nozzle @Blocks",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.8"
|
"0.8"
|
||||||
],
|
],
|
||||||
@@ -26,8 +26,5 @@
|
|||||||
"upward_compatible_machine": [
|
"upward_compatible_machine": [
|
||||||
"BLOCKS Pro S100"
|
"BLOCKS Pro S100"
|
||||||
],
|
],
|
||||||
"printer_variant": "1.2",
|
"printer_variant": "1.2"
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_Pro_S100"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,5 @@
|
|||||||
"bed_model": "PRO S100 HotBed model.stl",
|
"bed_model": "PRO S100 HotBed model.stl",
|
||||||
"bed_texture": "PRO S100 HotBed texture.svg",
|
"bed_texture": "PRO S100 HotBed texture.svg",
|
||||||
"hotend_model": "BLOCKS PrintCore.stl",
|
"hotend_model": "BLOCKS PrintCore.stl",
|
||||||
"default_materials": "Blocks PLA @Blocks_Pro_S100;Blocks PETG @Blocks_Pro_S100;Blocks TPU @Blocks_Pro_S100"
|
"default_materials": "Generic PLA @Blocks;Generic PETG @Blocks;Generic TPU @Blocks"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,5 @@
|
|||||||
"printable_height": "500",
|
"printable_height": "500",
|
||||||
"upward_compatible_machine": [
|
"upward_compatible_machine": [
|
||||||
"BLOCKS RD50 V2"
|
"BLOCKS RD50 V2"
|
||||||
],
|
|
||||||
"printer_variant": "0.4",
|
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_RD50_V2"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,5 @@
|
|||||||
"deretraction_speed": [
|
"deretraction_speed": [
|
||||||
"80"
|
"80"
|
||||||
],
|
],
|
||||||
"printer_variant": "0.6",
|
"printer_variant": "0.6"
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_RD50_V2"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,5 @@
|
|||||||
"deretraction_speed": [
|
"deretraction_speed": [
|
||||||
"80"
|
"80"
|
||||||
],
|
],
|
||||||
"printer_variant": "0.8",
|
"printer_variant": "0.8"
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_RD50_V2"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,5 @@
|
|||||||
"bed_model": "RD50 V2 HotBed model.stl",
|
"bed_model": "RD50 V2 HotBed model.stl",
|
||||||
"bed_texture": "RD50 V2 HotBed texture.svg",
|
"bed_texture": "RD50 V2 HotBed texture.svg",
|
||||||
"hotend_model": "BLOCKS PrintCore.stl",
|
"hotend_model": "BLOCKS PrintCore.stl",
|
||||||
"default_materials": "Blocks PLA @Blocks_RD50_V2;Blocks PETG @Blocks_RD50_V2;Blocks TPU @Blocks_RD50_V2"
|
"default_materials": "Generic PLA @Blocks;Generic PETG @Blocks;Generic TPU @Blocks"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"retraction_length": [
|
"retraction_length": [
|
||||||
"1.2"
|
"1"
|
||||||
],
|
],
|
||||||
"retraction_speed": [
|
"retraction_speed": [
|
||||||
"60"
|
"60"
|
||||||
@@ -79,10 +79,5 @@
|
|||||||
],
|
],
|
||||||
"retract_before_wipe": [
|
"retract_before_wipe": [
|
||||||
"0"
|
"0"
|
||||||
],
|
]
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_RF50"
|
|
||||||
],
|
|
||||||
"support_multi_bed_types": "1",
|
|
||||||
"default_bed_type": "Textured PEI Plate"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"retraction_length": [
|
"retraction_length": [
|
||||||
"1.2"
|
"1"
|
||||||
],
|
],
|
||||||
"retraction_speed": [
|
"retraction_speed": [
|
||||||
"60"
|
"60"
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
"BLOCKS RF50"
|
"BLOCKS RF50"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": [
|
"machine_start_gcode": [
|
||||||
"PRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer]\n",
|
"PRINT_START EXTRUDER=[nozzle_temperature_initial_layer] BED=[bed_temperature_initial_layer]",
|
||||||
"SET_PRESSURE_ADVANCE ADVANCE=0.046\n"
|
"SET_PRESSURE_ADVANCE ADVANCE=0.046"
|
||||||
],
|
],
|
||||||
"printer_variant": "0.6",
|
"printer_variant": "0.6",
|
||||||
"wipe_distance": [
|
"wipe_distance": [
|
||||||
@@ -84,10 +84,5 @@
|
|||||||
],
|
],
|
||||||
"retract_before_wipe": [
|
"retract_before_wipe": [
|
||||||
"0"
|
"0"
|
||||||
],
|
]
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_RF50"
|
|
||||||
],
|
|
||||||
"support_multi_bed_types": "1",
|
|
||||||
"default_bed_type": "Textured PEI Plate"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"retraction_length": [
|
"retraction_length": [
|
||||||
"1.2"
|
"1"
|
||||||
],
|
],
|
||||||
"retraction_speed": [
|
"retraction_speed": [
|
||||||
"60"
|
"60"
|
||||||
@@ -80,10 +80,5 @@
|
|||||||
],
|
],
|
||||||
"retract_before_wipe": [
|
"retract_before_wipe": [
|
||||||
"0"
|
"0"
|
||||||
],
|
]
|
||||||
"default_filament_profile": [
|
|
||||||
"Blocks PLA @Blocks_RF50"
|
|
||||||
],
|
|
||||||
"support_multi_bed_types": "1",
|
|
||||||
"default_bed_type": "Textured PEI Plate"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,5 @@
|
|||||||
"bed_model": "RF50 HotBed model.stl",
|
"bed_model": "RF50 HotBed model.stl",
|
||||||
"bed_texture": "RF50 HotBed texture.svg",
|
"bed_texture": "RF50 HotBed texture.svg",
|
||||||
"hotend_model": "BLOCKS PrintCore.stl",
|
"hotend_model": "BLOCKS PrintCore.stl",
|
||||||
"default_materials": "Blocks PLA @Blocks_RF50;Blocks PETG @Blocks_RF50;Blocks TPU @Blocks_RF50",
|
"default_materials": "Generic PLA @Blocks;Generic PETG @Blocks;Generic TPU @Blocks"
|
||||||
"not_support_bed_type": "Smooth Cool Plate;Engineering Plate;Textured Cool Plate;Cool Plate (SuperTack)"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,9 @@
|
|||||||
"wipe": [
|
"wipe": [
|
||||||
"1"
|
"1"
|
||||||
],
|
],
|
||||||
|
"default_filament_profile": [
|
||||||
|
"Generic PLA @Blocks"
|
||||||
|
],
|
||||||
"bed_exclude_area": [
|
"bed_exclude_area": [
|
||||||
"0x0"
|
"0x0"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.20mm Standard 0.4 nozzle @Blocks_Pro_S100",
|
"name": "0.20mm Standard 0.4 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_blocks_common",
|
"inherits": "fdm_process_blocks_common",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "QSEguMMChNFZsK5H",
|
"setting_id": "47aDtVL6E5DVr7Mt",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"layer_height": "0.2",
|
"layer_height": "0.2",
|
||||||
"bottom_shell_layers": "4",
|
"bottom_shell_layers": "4",
|
||||||
"top_shell_layers": "5",
|
"top_shell_layers": "5",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.4 nozzle"
|
"BLOCKS Pro S100 0.4 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.20mm Standard 0.4 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -61,7 +61,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.24mm Draft 0.4 nozzle @Blocks_Pro_S100",
|
"name": "0.24mm Draft 0.4 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_blocks_common",
|
"inherits": "fdm_process_blocks_common",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "uALfEFHGmup6vBYI",
|
"setting_id": "ETADjxV6ViJQdnHA",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"layer_height": "0.24",
|
"layer_height": "0.24",
|
||||||
"bottom_shell_layers": "4",
|
"bottom_shell_layers": "4",
|
||||||
"top_shell_layers": "5",
|
"top_shell_layers": "5",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.4 nozzle"
|
"BLOCKS Pro S100 0.4 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.24mm Draft 0.4 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.30mm Extra Draft 0.4 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Extra Draft 0.4 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_blocks_common",
|
"inherits": "fdm_process_blocks_common",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "HYKF5l2OGvpugSQy",
|
"setting_id": "UbuICsmppKDsaaZ4",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "3",
|
"bottom_shell_layers": "3",
|
||||||
"top_shell_layers": "4",
|
"top_shell_layers": "4",
|
||||||
"layer_height": "0.30",
|
"layer_height": "0.30",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.4 nozzle"
|
"BLOCKS Pro S100 0.4 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.30mm Extra Draft 0.4 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.30mm Optimal 0.8 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Optimal 0.8 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 0.8 nozzle",
|
"inherits": "fdm_process_common 0.8 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "OUfZvizM5MGnvHfp",
|
"setting_id": "YqkYzp5zdH4R5upm",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "3",
|
"bottom_shell_layers": "3",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.3",
|
"layer_height": "0.3",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.8 nozzle"
|
"BLOCKS Pro S100 0.8 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.30mm Optimal 0.8 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.30mm Optimal 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Optimal 1.0 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.0 nozzle",
|
"inherits": "fdm_process_common 1.0 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "HGG9WxKVr89qNFDx",
|
"setting_id": "8pBawPScHkyQu0SW",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "4",
|
"bottom_shell_layers": "4",
|
||||||
"top_shell_layers": "4",
|
"top_shell_layers": "4",
|
||||||
"layer_height": "0.30",
|
"layer_height": "0.30",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.0 nozzle"
|
"BLOCKS Pro S100 1.0 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.30mm Optimal 1.0 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.30mm Standard 0.6 nozzle @Blocks_Pro_S100",
|
"name": "0.30mm Standard 0.6 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 0.6 nozzle",
|
"inherits": "fdm_process_common 0.6 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "gO2I1YjBl4nf8yzr",
|
"setting_id": "EPI3PAVK9LpJOZWO",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "3",
|
"bottom_shell_layers": "3",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.30",
|
"layer_height": "0.30",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.6 nozzle"
|
"BLOCKS Pro S100 0.6 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.30mm Standard 0.6 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.40mm Draft 0.6 nozzle @Blocks_Pro_S100",
|
"name": "0.40mm Draft 0.6 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 0.6 nozzle",
|
"inherits": "fdm_process_common 0.6 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "OjsLUl1heqv1cevs",
|
"setting_id": "CShVKoGspbMJNPw8",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "2",
|
"top_shell_layers": "2",
|
||||||
"layer_height": "0.40",
|
"layer_height": "0.40",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.6 nozzle"
|
"BLOCKS Pro S100 0.6 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.40mm Draft 0.6 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.40mm Standard 0.8 nozzle @Blocks_Pro_S100",
|
"name": "0.40mm Standard 0.8 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 0.8 nozzle",
|
"inherits": "fdm_process_common 0.8 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "laOTioBGySeudJpl",
|
"setting_id": "TSRjmfWaatY7oLJB",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "3",
|
"bottom_shell_layers": "3",
|
||||||
"top_shell_layers": "4",
|
"top_shell_layers": "4",
|
||||||
"layer_height": "0.40",
|
"layer_height": "0.40",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.8 nozzle"
|
"BLOCKS Pro S100 0.8 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.40mm Standard 0.8 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.50mm Draft 0.8 nozzle @Blocks_Pro_S100",
|
"name": "0.50mm Draft 0.8 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 0.8 nozzle",
|
"inherits": "fdm_process_common 0.8 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "oAhgUZdADR7kP87e",
|
"setting_id": "vOtZHrDS88Shmf2m",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "3",
|
"bottom_shell_layers": "3",
|
||||||
"top_shell_layers": "4",
|
"top_shell_layers": "4",
|
||||||
"layer_height": "0.50",
|
"layer_height": "0.50",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 0.8 nozzle"
|
"BLOCKS Pro S100 0.8 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.50mm Draft 0.8 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.50mm Optimal 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.50mm Optimal 1.2 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.2 nozzle",
|
"inherits": "fdm_process_common 1.2 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "0eqNgX26jemsBfV5",
|
"setting_id": "BKrEAKqDYzdH43wc",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.50",
|
"layer_height": "0.50",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
"BLOCKS Pro S100 1.2 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.50mm Optimal 1.2 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.50mm Standard 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.50mm Standard 1.0 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.0 nozzle",
|
"inherits": "fdm_process_common 1.0 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "z1qCW1cEMc4QvBbV",
|
"setting_id": "D40iksDm7mFjhSKn",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "3",
|
"bottom_shell_layers": "3",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.50",
|
"layer_height": "0.50",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.0 nozzle"
|
"BLOCKS Pro S100 1.0 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.50mm Standard 1.0 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"top_solid_infill_flow_ratio": "0.97",
|
"top_solid_infill_flow_ratio": "0.97",
|
||||||
"bottom_solid_infill_flow_ratio": "1.08",
|
"bottom_solid_infill_flow_ratio": "1.08",
|
||||||
"seam_position": "aligned",
|
"seam_position": "aligned",
|
||||||
"sparse_infill_pattern": "grid",
|
"sparse_infill_patter": "grid",
|
||||||
"initial_layer_speed": "60",
|
"initial_layer_speed": "60",
|
||||||
"initial_layer_infill_speed": "80",
|
"initial_layer_infill_speed": "80",
|
||||||
"initial_travel_speed": "100%",
|
"initial_travel_speed": "100%",
|
||||||
@@ -57,7 +57,5 @@
|
|||||||
"accel_to_decel_enable": "1",
|
"accel_to_decel_enable": "1",
|
||||||
"accel_to_decel_factor": "50%",
|
"accel_to_decel_factor": "50%",
|
||||||
"elefant_foot_compensation": "0.25",
|
"elefant_foot_compensation": "0.25",
|
||||||
"elefant_foot_compensation_layers": "1",
|
"elefant_foot_compensation_layers": "1"
|
||||||
"skirt_loops": "2",
|
|
||||||
"skirt_type": "perobject"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.60mm Draft 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.60mm Draft 1.0 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.0 nozzle",
|
"inherits": "fdm_process_common 1.0 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "gTTgtfG8qb9My3hH",
|
"setting_id": "UJUe8XCBzZf8NyCL",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.60",
|
"layer_height": "0.60",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.0 nozzle"
|
"BLOCKS Pro S100 1.0 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.60mm Draft 1.0 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.60mm Standard 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.60mm Standard 1.2 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.2 nozzle",
|
"inherits": "fdm_process_common 1.2 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "ApcyToENCIANrI71",
|
"setting_id": "PSBFrTykpkytPI2Q",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.60",
|
"layer_height": "0.60",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
"BLOCKS Pro S100 1.2 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.60mm Standard 1.2 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.70mm Draft 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.70mm Draft 1.2 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.2 nozzle",
|
"inherits": "fdm_process_common 1.2 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "DEv7X7zaTfxRQmjo",
|
"setting_id": "0ZQ0USGX9SwAKr29",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.70",
|
"layer_height": "0.70",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
"BLOCKS Pro S100 1.2 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.70mm Draft 1.2 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.70mm Extra Draft 1.0 nozzle @Blocks_Pro_S100",
|
"name": "0.70mm Extra Draft 1.0 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.0 nozzle",
|
"inherits": "fdm_process_common 1.0 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "nUW7N9dJmTyQT4AG",
|
"setting_id": "69PFmjOVFBOIp3Qg",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "3",
|
"top_shell_layers": "3",
|
||||||
"layer_height": "0.70",
|
"layer_height": "0.70",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.0 nozzle"
|
"BLOCKS Pro S100 1.0 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.70mm Extra Draft 1.0 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "0.80mm Extra Draft 1.2 nozzle @Blocks_Pro_S100",
|
"name": "0.80mm Extra Draft 1.2 nozzle @Blocks",
|
||||||
"inherits": "fdm_process_common 1.2 nozzle",
|
"inherits": "fdm_process_common 1.2 nozzle",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"setting_id": "JMy62SonRfK0cAdL",
|
"setting_id": "iBwRI5JJewW5HJSv",
|
||||||
"instantiation": "true",
|
"instantiation": "true",
|
||||||
"bottom_shell_layers": "2",
|
"bottom_shell_layers": "2",
|
||||||
"top_shell_layers": "2",
|
"top_shell_layers": "2",
|
||||||
"layer_height": "0.80",
|
"layer_height": "0.80",
|
||||||
"compatible_printers": [
|
"compatible_printers": [
|
||||||
"BLOCKS Pro S100 1.2 nozzle"
|
"BLOCKS Pro S100 1.2 nozzle"
|
||||||
],
|
]
|
||||||
"renamed_from": "0.80mm Extra Draft 1.2 nozzle @Blocks"
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "OrcaFilamentLibrary",
|
"name": "OrcaFilamentLibrary",
|
||||||
"version": "02.04.00.13",
|
"version": "02.04.00.12",
|
||||||
"force_update": "0",
|
"force_update": "0",
|
||||||
"description": "Orca Filament Library",
|
"description": "Orca Filament Library",
|
||||||
"filament_list": [
|
"filament_list": [
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"filament_id": "OFvgE0Zh",
|
"filament_id": "OFvgE0Zh",
|
||||||
"instantiation": "false",
|
"instantiation": "false",
|
||||||
"fan_cooling_layer_time": [
|
"fan_cooling_layer_time": [
|
||||||
"81"
|
"80"
|
||||||
],
|
],
|
||||||
"fan_min_speed": [
|
"fan_min_speed": [
|
||||||
"50"
|
"50"
|
||||||
|
|||||||
+46
-64
@@ -5,6 +5,7 @@
|
|||||||
//BBS
|
//BBS
|
||||||
#include "Preset.hpp"
|
#include "Preset.hpp"
|
||||||
#include "Exception.hpp"
|
#include "Exception.hpp"
|
||||||
|
#include "InstanceLock.hpp"
|
||||||
#include "LocalesUtils.hpp"
|
#include "LocalesUtils.hpp"
|
||||||
#include "Thread.hpp"
|
#include "Thread.hpp"
|
||||||
#include "format.hpp"
|
#include "format.hpp"
|
||||||
@@ -739,10 +740,13 @@ static bool verify_config_file_checksum(boost::nowide::ifstream &ifs)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef USE_JSON_CONFIG
|
#ifdef USE_JSON_CONFIG
|
||||||
std::string AppConfig::load()
|
std::string AppConfig::load(bool read_only)
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
|
|
||||||
|
// Keep another instance from replacing or restoring the file mid-read.
|
||||||
|
InstanceLock instance_lock(read_only ? std::string() : lock_path());
|
||||||
|
|
||||||
// 1) Read the complete config file into a boost::property_tree.
|
// 1) Read the complete config file into a boost::property_tree.
|
||||||
namespace pt = boost::property_tree;
|
namespace pt = boost::property_tree;
|
||||||
pt::ptree tree;
|
pt::ptree tree;
|
||||||
@@ -992,7 +996,6 @@ void AppConfig::save()
|
|||||||
// The config is first written to a file with a PID suffix and then moved
|
// The config is first written to a file with a PID suffix and then moved
|
||||||
// to avoid race conditions with multiple instances of Slic3r
|
// to avoid race conditions with multiple instances of Slic3r
|
||||||
const auto path = config_path();
|
const auto path = config_path();
|
||||||
std::string path_pid = (boost::format("%1%.%2%") % path % get_current_pid()).str();
|
|
||||||
|
|
||||||
json j;
|
json j;
|
||||||
|
|
||||||
@@ -1122,43 +1125,18 @@ void AppConfig::save()
|
|||||||
|
|
||||||
j["local_machines"][local_machine.first] = m_json;
|
j["local_machines"][local_machine.first] = m_json;
|
||||||
}
|
}
|
||||||
boost::nowide::ofstream c;
|
const std::string config_str = j.dump(1, '\t');
|
||||||
c.open(path_pid, std::ios::out | std::ios::trunc);
|
if (write_config_file(path, config_str + "\n", config_str))
|
||||||
c << j.dump(1, '\t') << std::endl;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
// WIN32 specific: The final "rename_file()" call is not safe in case of an application crash, there is no atomic "rename file" API
|
|
||||||
// provided by Windows (sic!). Therefore we save a MD5 checksum to be able to verify file corruption. In addition,
|
|
||||||
// we save the config file into a backup first before moving it to the final destination.
|
|
||||||
c << appconfig_md5_hash_line(j.dump(1, '\t'));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
c.close();
|
|
||||||
if (c.fail()) {
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Failed to write new configuration to " << path_pid << "; aborting attempt to overwrite original configuration";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
// Make a backup of the configuration file before copying it to the final destination.
|
|
||||||
std::string error_message;
|
|
||||||
std::string backup_path = (boost::format("%1%.bak") % path).str();
|
|
||||||
// Copy configuration file with PID suffix into the configuration file with "bak" suffix.
|
|
||||||
if (copy_file(path_pid, backup_path, error_message, false) != SUCCESS)
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Copying from " << path_pid << " to " << backup_path << " failed. Failed to create a backup configuration.";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Rename the config atomically.
|
|
||||||
// On Windows, the rename is likely NOT atomic, thus it may fail if PrusaSlicer crashes on another thread in the meanwhile.
|
|
||||||
// To cope with that, we already made a backup of the config on Windows.
|
|
||||||
rename_file(path_pid, path);
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
std::string AppConfig::load()
|
std::string AppConfig::load(bool read_only)
|
||||||
{
|
{
|
||||||
|
// Keep another instance from replacing or restoring the file mid-read.
|
||||||
|
InstanceLock instance_lock(read_only ? std::string() : lock_path());
|
||||||
|
|
||||||
// 1) Read the complete config file into a boost::property_tree.
|
// 1) Read the complete config file into a boost::property_tree.
|
||||||
namespace pt = boost::property_tree;
|
namespace pt = boost::property_tree;
|
||||||
pt::ptree tree;
|
pt::ptree tree;
|
||||||
@@ -1296,7 +1274,6 @@ void AppConfig::save()
|
|||||||
// The config is first written to a file with a PID suffix and then moved
|
// The config is first written to a file with a PID suffix and then moved
|
||||||
// to avoid race conditions with multiple instances of Slic3r
|
// to avoid race conditions with multiple instances of Slic3r
|
||||||
const auto path = config_path();
|
const auto path = config_path();
|
||||||
std::string path_pid = (boost::format("%1%.%2%") % path % get_current_pid()).str();
|
|
||||||
|
|
||||||
std::stringstream config_ss;
|
std::stringstream config_ss;
|
||||||
if (m_mode == EAppMode::Editor)
|
if (m_mode == EAppMode::Editor)
|
||||||
@@ -1332,39 +1309,39 @@ void AppConfig::save()
|
|||||||
// One empty line before the MD5 sum.
|
// One empty line before the MD5 sum.
|
||||||
config_ss << std::endl;
|
config_ss << std::endl;
|
||||||
|
|
||||||
std::string config_str = config_ss.str();
|
const std::string config_str = config_ss.str();
|
||||||
boost::nowide::ofstream c;
|
if (write_config_file(path, config_str, config_str))
|
||||||
c.open(path_pid, std::ios::out | std::ios::trunc);
|
|
||||||
c << config_str;
|
|
||||||
#ifdef WIN32
|
|
||||||
// WIN32 specific: The final "rename_file()" call is not safe in case of an application crash, there is no atomic "rename file" API
|
|
||||||
// provided by Windows (sic!). Therefore we save a MD5 checksum to be able to verify file corruption. In addition,
|
|
||||||
// we save the config file into a backup first before moving it to the final destination.
|
|
||||||
c << appconfig_md5_hash_line(config_str);
|
|
||||||
#endif
|
|
||||||
c.close();
|
|
||||||
if (c.fail()) {
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Failed to write new configuration to " << path_pid << "; aborting attempt to overwrite original configuration";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
// Make a backup of the configuration file before copying it to the final destination.
|
|
||||||
std::string error_message;
|
|
||||||
std::string backup_path = (boost::format("%1%.bak") % path).str();
|
|
||||||
// Copy configuration file with PID suffix into the configuration file with "bak" suffix.
|
|
||||||
if (copy_file(path_pid, backup_path, error_message, false) != SUCCESS)
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Copying from " << path_pid << " to " << backup_path << " failed. Failed to create a backup configuration.";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Rename the config atomically.
|
|
||||||
// On Windows, the rename is likely NOT atomic, thus it may fail if PrusaSlicer crashes on another thread in the meanwhile.
|
|
||||||
// To cope with that, we already made a backup of the config on Windows.
|
|
||||||
rename_file(path_pid, path);
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool AppConfig::write_config_file(const std::string &path, std::string body, const std::string &checksum_source)
|
||||||
|
{
|
||||||
|
// Everything before this is assembly; only the writes need the other instances kept out.
|
||||||
|
InstanceLock instance_lock(lock_path());
|
||||||
|
#ifdef WIN32
|
||||||
|
// WIN32 specific: the final replace is not safe in case of an application crash, there is no atomic "rename file" API
|
||||||
|
// provided by Windows (sic!). Therefore we save a MD5 checksum to be able to verify file corruption. In addition,
|
||||||
|
// we save the config file into a backup first before moving it to the final destination.
|
||||||
|
body += appconfig_md5_hash_line(checksum_source);
|
||||||
|
#endif
|
||||||
|
// Not flushed to the device: the idle handler saves on the GUI thread after
|
||||||
|
// any change, and the rename already gives a complete old or new file.
|
||||||
|
if (const std::error_code ec = write_file_atomically(path, body)) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Failed to write the configuration " << path << ": " << ec.message() << "; trying again in 10 s";
|
||||||
|
m_retry_save_at = std::chrono::steady_clock::now() + std::chrono::seconds(10);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_retry_save_at = {};
|
||||||
|
#ifdef WIN32
|
||||||
|
// Written after the config, so the backup never holds a state that was not confirmed written.
|
||||||
|
const std::string backup_path = (boost::format("%1%.bak") % path).str();
|
||||||
|
if (const std::error_code ec = write_file_atomically(backup_path, body))
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Failed to write the backup configuration " << backup_path << ": " << ec.message();
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
|
bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
|
||||||
{
|
{
|
||||||
const auto it_v = m_vendors.find(vendor);
|
const auto it_v = m_vendors.find(vendor);
|
||||||
@@ -1853,6 +1830,11 @@ void AppConfig::reset_selections()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string AppConfig::lock_path()
|
||||||
|
{
|
||||||
|
return Slic3r::data_dir().empty() ? std::string() : config_path() + ".lock";
|
||||||
|
}
|
||||||
|
|
||||||
std::string AppConfig::config_path()
|
std::string AppConfig::config_path()
|
||||||
{
|
{
|
||||||
#ifdef USE_JSON_CONFIG
|
#ifdef USE_JSON_CONFIG
|
||||||
@@ -1889,7 +1871,7 @@ bool AppConfig::exists()
|
|||||||
|
|
||||||
std::string AppConfig::load_if_exists()
|
std::string AppConfig::load_if_exists()
|
||||||
{
|
{
|
||||||
return boost::filesystem::exists(loading_path()) ? load() : std::string();
|
return boost::filesystem::exists(loading_path()) ? load(/*read_only=*/true) : std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace Slic3r
|
}; // namespace Slic3r
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define slic3r_AppConfig_hpp_
|
#define slic3r_AppConfig_hpp_
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <chrono>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
@@ -122,14 +123,18 @@ public:
|
|||||||
|
|
||||||
// Load the slic3r.ini from a user profile directory (or a datadir, if configured).
|
// Load the slic3r.ini from a user profile directory (or a datadir, if configured).
|
||||||
// Return an error string, or an empty string on success.
|
// Return an error string, or an empty string on success.
|
||||||
std::string load();
|
std::string load(bool read_only = false);
|
||||||
// Treat a missing config as default state; otherwise load it normally.
|
// Treat a missing config as default state; otherwise load it normally.
|
||||||
|
// The CLI's load: it never saves, so it takes no lock and creates no lock file.
|
||||||
std::string load_if_exists();
|
std::string load_if_exists();
|
||||||
// Store the slic3r.ini into a user profile directory (or a datadir, if configured).
|
// Store the slic3r.ini into a user profile directory (or a datadir, if configured).
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
// Does this config need to be saved?
|
// Does this config need to be saved?
|
||||||
bool dirty() const { return m_dirty; }
|
bool dirty() const { return m_dirty; }
|
||||||
|
// False for ten seconds after a failed write, so the idle handler does not
|
||||||
|
// repeat a hopeless attempt on every event; an explicit save() always tries.
|
||||||
|
bool save_due() const { return std::chrono::steady_clock::now() >= m_retry_save_at; }
|
||||||
|
|
||||||
|
|
||||||
void set_dirty() { m_dirty = true; }
|
void set_dirty() { m_dirty = true; }
|
||||||
@@ -339,6 +344,8 @@ public:
|
|||||||
|
|
||||||
// Get the default config path from Slic3r::data_dir().
|
// Get the default config path from Slic3r::data_dir().
|
||||||
std::string config_path();
|
std::string config_path();
|
||||||
|
// Lock file guarding config_path() against other running instances; empty without a data dir.
|
||||||
|
std::string lock_path();
|
||||||
|
|
||||||
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
|
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
|
||||||
bool legacy_datadir() const { return m_legacy_datadir; }
|
bool legacy_datadir() const { return m_legacy_datadir; }
|
||||||
@@ -449,8 +456,16 @@ private:
|
|||||||
|
|
||||||
// Preset for each machine
|
// Preset for each machine
|
||||||
MachineSettingMap m_printer_settings;
|
MachineSettingMap m_printer_settings;
|
||||||
|
// Writes the assembled config text, and on Windows its checksum and a backup copy; false when the
|
||||||
|
// config itself could not be written, in which case the caller stays dirty and retries. `checksum_source`
|
||||||
|
// is the text load() will verify, which for the JSON config ends before the trailing newline.
|
||||||
|
bool write_config_file(const std::string &path, std::string body, const std::string &checksum_source);
|
||||||
|
|
||||||
// Has any value been modified since the config.ini has been last saved or loaded?
|
// Has any value been modified since the config.ini has been last saved or loaded?
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
// After a failed write, save_due() is false for the next ten seconds, so the
|
||||||
|
// idle handler does not repeat a hopeless write on every event.
|
||||||
|
std::chrono::steady_clock::time_point m_retry_save_at{};
|
||||||
// Original version found in the ini file before it was overwritten
|
// Original version found in the ini file before it was overwritten
|
||||||
Semver m_orig_version;
|
Semver m_orig_version;
|
||||||
// Whether the existing version is before system profiles & configuration updating
|
// Whether the existing version is before system profiles & configuration updating
|
||||||
|
|||||||
@@ -2673,10 +2673,10 @@ void CadDocument::apply_feature(TopoDS_Shape& result, bool& have_body,
|
|||||||
ridge = pipe.Shape();
|
ridge = pipe.Shape();
|
||||||
have_ridge = !ridge.IsNull();
|
have_ridge = !ridge.IsNull();
|
||||||
}
|
}
|
||||||
} catch (const Standard_Failure&) {
|
|
||||||
have_ridge = false; // OCCT failure — on OCCT >= 8 Standard_Failure derives from std::exception, so this handler must come first
|
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
have_ridge = false; // fall back to the bare cylinder/bore below
|
have_ridge = false; // fall back to the bare cylinder/bore below
|
||||||
|
} catch (const Standard_Failure&) {
|
||||||
|
have_ridge = false; // OCCT failure (not a std::exception) — must be caught here too
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.thread_internal) {
|
if (f.thread_internal) {
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
#include <TopExp.hxx>
|
#include <TopExp.hxx>
|
||||||
#include <TopTools.hxx>
|
#include <TopTools.hxx>
|
||||||
#include <TopTools_IndexedMapOfShape.hxx>
|
#include <TopTools_IndexedMapOfShape.hxx>
|
||||||
#include <TopTools_ListOfShape.hxx>
|
|
||||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
||||||
#include <Poly_Triangulation.hxx>
|
#include <Poly_Triangulation.hxx>
|
||||||
#include <gp_Ax2.hxx>
|
#include <gp_Ax2.hxx>
|
||||||
#include <gp_Dir.hxx>
|
#include <gp_Dir.hxx>
|
||||||
|
|||||||
@@ -304,6 +304,8 @@ set(lisbslic3r_sources
|
|||||||
Geometry/VoronoiUtils.cpp
|
Geometry/VoronoiUtils.cpp
|
||||||
Geometry/VoronoiUtils.hpp
|
Geometry/VoronoiUtils.hpp
|
||||||
Geometry/VoronoiVisualUtils.hpp
|
Geometry/VoronoiVisualUtils.hpp
|
||||||
|
InstanceLock.cpp
|
||||||
|
InstanceLock.hpp
|
||||||
Int128.hpp
|
Int128.hpp
|
||||||
KDTreeIndirect.hpp
|
KDTreeIndirect.hpp
|
||||||
Layer.cpp
|
Layer.cpp
|
||||||
@@ -353,6 +355,7 @@ set(lisbslic3r_sources
|
|||||||
Optimize/Optimizer.hpp
|
Optimize/Optimizer.hpp
|
||||||
Orient.cpp
|
Orient.cpp
|
||||||
Orient.hpp
|
Orient.hpp
|
||||||
|
ParallelResolve.hpp
|
||||||
ParameterUtils.cpp
|
ParameterUtils.cpp
|
||||||
ParameterUtils.hpp
|
ParameterUtils.hpp
|
||||||
pchheader.cpp
|
pchheader.cpp
|
||||||
|
|||||||
+29
-18
@@ -849,6 +849,19 @@ ConfigSubstitutions ConfigBase::load_from_json(const std::string &file, ForwardC
|
|||||||
return std::move(substitutions_ctxt.substitutions);
|
return std::move(substitutions_ctxt.substitutions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Case-insensitive compare of a JSON key against a fixed ASCII one, without
|
||||||
|
// boost::iequals, whose std::locale() takes a lock the whole process shares in the
|
||||||
|
// MSVC runtime.
|
||||||
|
static bool ascii_iequals(const std::string &key, const char *literal)
|
||||||
|
{
|
||||||
|
auto lower = [](char c) { return (c >= 'A' && c <= 'Z') ? char(c - 'A' + 'a') : c; };
|
||||||
|
size_t i = 0;
|
||||||
|
for (; i < key.size() && literal[i] != '\0'; ++ i)
|
||||||
|
if (lower(key[i]) != lower(literal[i]))
|
||||||
|
return false;
|
||||||
|
return i == key.size() && literal[i] == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContext& substitution_context, bool load_inherits_to_config, std::map<std::string, std::string>& key_values, std::string& reason)
|
int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContext& substitution_context, bool load_inherits_to_config, std::map<std::string, std::string>& key_values, std::string& reason)
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
@@ -916,44 +929,44 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
|
|||||||
}
|
}
|
||||||
//parse the json elements
|
//parse the json elements
|
||||||
for (auto it = j.begin(); it != j.end(); it++) {
|
for (auto it = j.begin(); it != j.end(); it++) {
|
||||||
if (boost::iequals(it.key(),BBL_JSON_KEY_VERSION)) {
|
if (ascii_iequals(it.key(), BBL_JSON_KEY_VERSION)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_VERSION, it.value());
|
key_values.emplace(BBL_JSON_KEY_VERSION, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_IS_CUSTOM)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_IS_CUSTOM)) {
|
||||||
//skip it
|
//skip it
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_NAME)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_NAME)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_NAME, it.value());
|
key_values.emplace(BBL_JSON_KEY_NAME, it.value());
|
||||||
if (it.value() == "project_settings")
|
if (it.value() == "project_settings")
|
||||||
is_project_settings = true;
|
is_project_settings = true;
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_URL)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_URL)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_URL, it.value());
|
key_values.emplace(BBL_JSON_KEY_URL, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_TYPE)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_TYPE)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_TYPE, it.value());
|
key_values.emplace(BBL_JSON_KEY_TYPE, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_SETTING_ID)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_SETTING_ID)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_SETTING_ID, it.value());
|
key_values.emplace(BBL_JSON_KEY_SETTING_ID, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_FILAMENT_ID)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_FILAMENT_ID)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_FILAMENT_ID, it.value());
|
key_values.emplace(BBL_JSON_KEY_FILAMENT_ID, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_FROM)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_FROM)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_FROM, it.value());
|
key_values.emplace(BBL_JSON_KEY_FROM, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_DESCRIPTION)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_DESCRIPTION)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_DESCRIPTION, it.value());
|
key_values.emplace(BBL_JSON_KEY_DESCRIPTION, it.value());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(it.key(), BBL_JSON_KEY_INSTANTIATION)) {
|
else if (ascii_iequals(it.key(), BBL_JSON_KEY_INSTANTIATION)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_INSTANTIATION, it.value());
|
key_values.emplace(BBL_JSON_KEY_INSTANTIATION, it.value());
|
||||||
}
|
}
|
||||||
else if (!load_inherits_to_config && boost::iequals(it.key(), BBL_JSON_KEY_INHERITS)) {
|
else if (!load_inherits_to_config && ascii_iequals(it.key(), BBL_JSON_KEY_INHERITS)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_INHERITS, it.value());
|
key_values.emplace(BBL_JSON_KEY_INHERITS, it.value());
|
||||||
}
|
}
|
||||||
else if (!load_inherits_to_config && boost::iequals(it.key(), BBL_JSON_KEY_INCLUDES)) {
|
else if (!load_inherits_to_config && ascii_iequals(it.key(), BBL_JSON_KEY_INCLUDES)) {
|
||||||
key_values.emplace(BBL_JSON_KEY_INCLUDES, it.value().dump());
|
key_values.emplace(BBL_JSON_KEY_INCLUDES, it.value().dump());
|
||||||
} else if (boost::iequals(it.key(), ORCA_JSON_KEY_RENAMED_FROM)) {
|
} else if (ascii_iequals(it.key(), ORCA_JSON_KEY_RENAMED_FROM)) {
|
||||||
key_values.emplace(ORCA_JSON_KEY_RENAMED_FROM, it.value());
|
key_values.emplace(ORCA_JSON_KEY_RENAMED_FROM, it.value());
|
||||||
} else {
|
} else {
|
||||||
t_config_option_key opt_key = it.key();
|
t_config_option_key opt_key = it.key();
|
||||||
@@ -1525,11 +1538,9 @@ void ConfigBase::save_to_json(const std::string &file, const std::string &name,
|
|||||||
// Serialize first: if that throws (invalid UTF-8), the existing file stays untouched.
|
// Serialize first: if that throws (invalid UTF-8), the existing file stays untouched.
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
this->save_to_json(ss, name, from, version);
|
this->save_to_json(ss, name, from, version);
|
||||||
boost::nowide::ofstream c;
|
if (const std::error_code ec = write_file_atomically(file, ss.str()))
|
||||||
c.open(file, std::ios::out | std::ios::trunc);
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to save config to %1%: %2%") % file % ec.message();
|
||||||
c << ss.str();
|
else
|
||||||
c.close();
|
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", saved config to %1%\n")%file;
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", saved config to %1%\n")%file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "XCAFDoc_DocumentTool.hxx"
|
#include "XCAFDoc_DocumentTool.hxx"
|
||||||
#include "XCAFDoc_ShapeTool.hxx"
|
#include "XCAFDoc_ShapeTool.hxx"
|
||||||
#include "XCAFApp_Application.hxx"
|
#include "XCAFApp_Application.hxx"
|
||||||
#include "TDF_LabelSequence.hxx"
|
|
||||||
#include "TopoDS_Solid.hxx"
|
#include "TopoDS_Solid.hxx"
|
||||||
#include "TopoDS_Compound.hxx"
|
#include "TopoDS_Compound.hxx"
|
||||||
#include "TopoDS_Builder.hxx"
|
#include "TopoDS_Builder.hxx"
|
||||||
|
|||||||
+28
-38
@@ -2504,8 +2504,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
|||||||
|
|
||||||
{
|
{
|
||||||
LifecycleEventContext ctx;
|
LifecycleEventContext ctx;
|
||||||
ctx.id = std::to_string(print->model().id().id);
|
ctx.name = std::to_string(print->model().id().id);
|
||||||
ctx.name = print->get_model_name();
|
|
||||||
ctx.code = LifecycleEvtCode::Ok;
|
ctx.code = LifecycleEvtCode::Ok;
|
||||||
ctx.msg = path;
|
ctx.msg = path;
|
||||||
ctx.cancellation_check = [print]() { return print->canceled(); };
|
ctx.cancellation_check = [print]() { return print->canceled(); };
|
||||||
@@ -2557,8 +2556,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
LifecycleEventContext ctx;
|
LifecycleEventContext ctx;
|
||||||
ctx.id = std::to_string(print->model().id().id);
|
ctx.name = std::to_string(print->model().id().id);
|
||||||
ctx.name = print->get_model_name();
|
|
||||||
ctx.code = LifecycleEvtCode::Error;
|
ctx.code = LifecycleEvtCode::Error;
|
||||||
ctx.msg = std::string(path) + "\n" + err_msg;
|
ctx.msg = std::string(path) + "\n" + err_msg;
|
||||||
ctx.cancellation_check = [print]() { return print->canceled(); };
|
ctx.cancellation_check = [print]() { return print->canceled(); };
|
||||||
@@ -2582,8 +2580,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
|||||||
boost::nowide::remove(path_tmp.c_str());
|
boost::nowide::remove(path_tmp.c_str());
|
||||||
{
|
{
|
||||||
LifecycleEventContext ctx;
|
LifecycleEventContext ctx;
|
||||||
ctx.id = std::to_string(print->model().id().id);
|
ctx.name = std::to_string(print->model().id().id);
|
||||||
ctx.name = print->get_model_name();
|
|
||||||
ctx.code = LifecycleEvtCode::Error;
|
ctx.code = LifecycleEvtCode::Error;
|
||||||
ctx.msg = std::string(path) + "\n" + ex.what();
|
ctx.msg = std::string(path) + "\n" + ex.what();
|
||||||
ctx.cancellation_check = [print]() { return print->canceled(); };
|
ctx.cancellation_check = [print]() { return print->canceled(); };
|
||||||
@@ -2696,8 +2693,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
{
|
{
|
||||||
LifecycleEventContext ctx;
|
LifecycleEventContext ctx;
|
||||||
ctx.id = std::to_string(print->model().id().id);
|
ctx.name = std::to_string(print->model().id().id);
|
||||||
ctx.name = print->get_model_name();
|
|
||||||
ctx.code = LifecycleEvtCode::Error;
|
ctx.code = LifecycleEvtCode::Error;
|
||||||
ctx.msg = std::string(path) + "\nFailed to rename the output G-code file: " + ret.message();
|
ctx.msg = std::string(path) + "\nFailed to rename the output G-code file: " + ret.message();
|
||||||
ctx.cancellation_check = [print]() { return print->canceled(); };
|
ctx.cancellation_check = [print]() { return print->canceled(); };
|
||||||
@@ -2716,8 +2712,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
|||||||
|
|
||||||
{
|
{
|
||||||
LifecycleEventContext ctx;
|
LifecycleEventContext ctx;
|
||||||
ctx.id = std::to_string(print->model().id().id);
|
ctx.name = std::to_string(print->model().id().id);
|
||||||
ctx.name = print->get_model_name();
|
|
||||||
ctx.code = LifecycleEvtCode::Ok;
|
ctx.code = LifecycleEvtCode::Ok;
|
||||||
ctx.msg = path;
|
ctx.msg = path;
|
||||||
ctx.cancellation_check = [print]() { return print->canceled(); };
|
ctx.cancellation_check = [print]() { return print->canceled(); };
|
||||||
@@ -7969,20 +7964,6 @@ double GCode::calc_max_volumetric_speed(const double layer_height, const double
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ORCA: Overlap at or below which the overhang fan switches on; negative when it does not depend on overlap
|
|
||||||
// (Overhang_threshold_none cools every external perimeter).
|
|
||||||
static float overhang_fan_overlap_threshold(int overhang_fan_threshold)
|
|
||||||
{
|
|
||||||
switch (overhang_fan_threshold) {
|
|
||||||
case (int) Overhang_threshold_1_4: return 0.9f;
|
|
||||||
case (int) Overhang_threshold_2_4: return 0.75f;
|
|
||||||
case (int) Overhang_threshold_3_4: return 0.5f;
|
|
||||||
case (int) Overhang_threshold_4_4: return 0.25f;
|
|
||||||
case (int) Overhang_threshold_bridge: return 0.05f;
|
|
||||||
default: return -1.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed)
|
std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed)
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
@@ -8325,13 +8306,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
|
|
||||||
ConfigOptionPercents overhang_overlap_levels({90, 75, 50, 25, 13, 0});
|
ConfigOptionPercents overhang_overlap_levels({90, 75, 50, 25, 13, 0});
|
||||||
|
|
||||||
// ORCA: Lets the path be split where the overhang fan switches, not only where the speed changes.
|
|
||||||
// Bridges and overhang perimeters are cooled regardless of overlap.
|
|
||||||
float fan_overlap_threshold = -1.f;
|
|
||||||
if (FILAMENT_CONFIG(enable_overhang_bridge_fan) && m_enable_cooling_markers && path.role() != erBridgeInfill &&
|
|
||||||
path.role() != erOverhangPerimeter)
|
|
||||||
fan_overlap_threshold = overhang_fan_overlap_threshold(FILAMENT_CONFIG(overhang_fan_threshold));
|
|
||||||
|
|
||||||
if (NOZZLE_CONFIG(slowdown_for_curled_perimeters)){
|
if (NOZZLE_CONFIG(slowdown_for_curled_perimeters)){
|
||||||
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
||||||
{FloatOrPercent{100, true},
|
{FloatOrPercent{100, true},
|
||||||
@@ -8352,8 +8326,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true}});
|
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true}});
|
||||||
|
|
||||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
||||||
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters),
|
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters));
|
||||||
fan_overlap_threshold);
|
|
||||||
}else{
|
}else{
|
||||||
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
||||||
{FloatOrPercent{100, true},
|
{FloatOrPercent{100, true},
|
||||||
@@ -8372,8 +8345,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
FloatOrPercent{NOZZLE_CONFIG(bridge_speed) * 100 / ref_speed, true}});
|
FloatOrPercent{NOZZLE_CONFIG(bridge_speed) * 100 / ref_speed, true}});
|
||||||
|
|
||||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
||||||
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters),
|
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters));
|
||||||
fan_overlap_threshold);
|
|
||||||
}
|
}
|
||||||
variable_speed = std::any_of(new_points.begin(), new_points.end(),
|
variable_speed = std::any_of(new_points.begin(), new_points.end(),
|
||||||
[speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec)
|
[speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec)
|
||||||
@@ -8525,10 +8497,28 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
if (role == erBridgeInfill || role == erOverhangPerimeter) { // ORCA: Split out bridge infill to internal and external to apply separate fan settings
|
if (role == erBridgeInfill || role == erOverhangPerimeter) { // ORCA: Split out bridge infill to internal and external to apply separate fan settings
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (overhang_fan_threshold == Overhang_threshold_none)
|
switch (overhang_fan_threshold) {
|
||||||
|
case (int)Overhang_threshold_1_4:
|
||||||
|
return overlap <= 0.9f;
|
||||||
|
break;
|
||||||
|
case (int)Overhang_threshold_2_4:
|
||||||
|
return overlap <= 0.75f;
|
||||||
|
break;
|
||||||
|
case (int)Overhang_threshold_3_4:
|
||||||
|
return overlap <= 0.5f;
|
||||||
|
break;
|
||||||
|
case (int)Overhang_threshold_4_4:
|
||||||
|
return overlap <= 0.25f;
|
||||||
|
break;
|
||||||
|
case (int)Overhang_threshold_bridge:
|
||||||
|
return overlap <= 0.05f;
|
||||||
|
break;
|
||||||
|
case (int)Overhang_threshold_none:
|
||||||
return is_external_perimeter(role);
|
return is_external_perimeter(role);
|
||||||
const float overlap_threshold = overhang_fan_overlap_threshold(overhang_fan_threshold);
|
break;
|
||||||
return overlap_threshold >= 0.f && overlap <= overlap_threshold;
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string comment;
|
std::string comment;
|
||||||
|
|||||||
@@ -41,12 +41,10 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
|||||||
float flow_width,
|
float flow_width,
|
||||||
float max_line_length = -1.0f,
|
float max_line_length = -1.0f,
|
||||||
float min_distance = -1.0f,
|
float min_distance = -1.0f,
|
||||||
// Speed an overhang distance prints at. Without it, interior sampling
|
// Maps an overhang distance onto the speed it will be printed at. Interior sampling
|
||||||
// is skipped and every line over 4mm is split.
|
// needs it to tell which of the points it could add would change the G-code, and is
|
||||||
const std::function<float(float)>& distance_to_speed = {},
|
// skipped without it.
|
||||||
// Overlap (1 - distance / flow_width) at or below which the overhang
|
const std::function<float(float)>& distance_to_speed = {})
|
||||||
// fan switches on; negative when the fan does not depend on overlap.
|
|
||||||
float fan_overlap_threshold = -1.0f)
|
|
||||||
{
|
{
|
||||||
bool looped = input_points.front() == input_points.back();
|
bool looped = input_points.front() == input_points.back();
|
||||||
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
|
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
|
||||||
@@ -127,43 +125,29 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
|||||||
points.push_back(next_point);
|
points.push_back(next_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ORCA: How an overhang distance prints, which is what the passes below compare. A segment is printed at the lower
|
|
||||||
// of the speeds at its two ends, and with the overhang fan on if the overlap at either end turns it on. A point
|
|
||||||
// added to a path can therefore only change the G-code where it prints at a different speed or fan state from the
|
|
||||||
// points either side of it, and the passes below add points there and nowhere else.
|
|
||||||
const float width_inv = 1.f / flow_width;
|
|
||||||
// Whether an overhang distance turns the overhang fan on. The overlap test check_overhang_fan applies in GCode.cpp.
|
|
||||||
auto fan_on = [fan_overlap_threshold, width_inv](float distance) {
|
|
||||||
return fan_overlap_threshold >= 0.f && 1.f - distance * width_inv <= fan_overlap_threshold;
|
|
||||||
};
|
|
||||||
// Whether two overhang distances are interchangeable ie have the same speed (beyond a 1mm/sec threshold that gcode.cpp filters out on)
|
|
||||||
// and the same fan state.
|
|
||||||
auto same_speed_and_fan = [&distance_to_speed, &fan_on](float a, float b) {
|
|
||||||
return std::abs(distance_to_speed(a) - distance_to_speed(b)) <= 1.f && fan_on(a) == fan_on(b);
|
|
||||||
};
|
|
||||||
// Whether the first overhang distance prints slower than the second, beyond the 1mm/sec gcode.cpp tolerance, or turns the overhang
|
|
||||||
// fan on where the second does not. Against a supported point (overhang distance 0) it tells whether an end is
|
|
||||||
// affected by the overhang.
|
|
||||||
auto slower_or_cooled = [&distance_to_speed, &fan_on](float a, float b) {
|
|
||||||
return distance_to_speed(a) < distance_to_speed(b) - 1.f || (fan_on(a) && !fan_on(b));
|
|
||||||
};
|
|
||||||
|
|
||||||
// ORCA: Interior sampling
|
// ORCA: Interior sampling
|
||||||
// The passes below infer the support under a span from its endpoints alone, so a part that is supported
|
// The passes below infer the support under a span from its endpoints alone, so an interior that is supported
|
||||||
// differently from both ends is invisible to them. The outer perimeter of an overhang whose ends are supported by
|
// differently from both ends is invisible to them: the outer perimeter of an overhang whose ends are caged by
|
||||||
// reads as supported along its whole length. Probe the interior, keep the samples the endpoint interpolation fails to predict,
|
// full height walls reads as supported along its whole length. Probe the interior, keep the samples the
|
||||||
// and bisect either side of each one, so a span that is only partly unsupported gets points where its support actually changes
|
// endpoint interpolation fails to predict, and bisect either side of each one, so a span that is only partly
|
||||||
// instead of one reading being spread across all of it.
|
// unsupported gets points where its support actually changes instead of one reading spread across all of it.
|
||||||
// Skipped where there is nothing to find: min_distance <= 0 when no overhang can slow this path down, and
|
if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS && min_distance > 0 && distance_to_speed) {
|
||||||
// fan_overlap_threshold < 0 when no overhang switches the fan on. It also needs distance_to_speed to tell which of
|
|
||||||
// the points it could add would change the G-code.
|
|
||||||
if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS && distance_to_speed && (min_distance > 0 || fan_overlap_threshold >= 0.f)) {
|
|
||||||
// Probe at least this densely before treating matching samples as evidence that a span is uniform. The
|
// Probe at least this densely before treating matching samples as evidence that a span is uniform. The
|
||||||
// segmentation pass below only splits lines of 2mm or more, and every pass here drops points closer
|
// segmentation pass below only splits lines of 2mm or more, and every pass here drops points closer
|
||||||
// together than min_spacing, so finer discovery would not produce a more precise transition.
|
// together than min_spacing, so finer discovery would not produce a more precise speed transition.
|
||||||
const double max_probe_spacing = std::max(2., 4. * min_spacing);
|
const double max_probe_spacing = std::max(2., 4. * min_spacing);
|
||||||
// A backstop for that length test, which on a non-finite length would never be met.
|
// A backstop for that length test, which on a non-finite length would never be met.
|
||||||
constexpr int max_bisection_depth = 10;
|
constexpr int max_bisection_depth = 10;
|
||||||
|
// Whether two readings are interchangeable. A segment is printed at the lower of the speeds its ends
|
||||||
|
// read, so a sample that agrees on speed with what is already known cannot change the G-code, whatever
|
||||||
|
// its distance says. The distances themselves are far too coarse a stand-in for this: the speed sections
|
||||||
|
// interpolate, so readings a small fraction of min_distance apart can still be tens of mm/s apart.
|
||||||
|
// The tolerance matches the one GCode.cpp applies when it decides a path has a variable speed at all.
|
||||||
|
auto same_speed = [&distance_to_speed](float a, float b) {
|
||||||
|
return std::abs(distance_to_speed(a) - distance_to_speed(b)) <= 1.f;
|
||||||
|
};
|
||||||
|
// Whether the first reading is printed slower than the second, once they are known to differ.
|
||||||
|
auto prints_slower = [&distance_to_speed](float a, float b) { return distance_to_speed(a) < distance_to_speed(b); };
|
||||||
|
|
||||||
// Part of a segment still to bisect: its positions along the segment and bisections left.
|
// Part of a segment still to bisect: its positions along the segment and bisections left.
|
||||||
struct Subspan { double t0, t1; int depth; };
|
struct Subspan { double t0, t1; int depth; };
|
||||||
@@ -201,8 +185,8 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
|||||||
if (!interior.empty()) {
|
if (!interior.empty()) {
|
||||||
std::sort(interior.begin(), interior.end(),
|
std::sort(interior.begin(), interior.end(),
|
||||||
[](const std::pair<double, float>& l, const std::pair<double, float>& r) { return l.first < r.first; });
|
[](const std::pair<double, float>& l, const std::pair<double, float>& r) { return l.first < r.first; });
|
||||||
// Coarse probing keeps every sample it took until this pass can see which ones bracket a speed or
|
// Coarse probing keeps every sample it took until this pass can see which ones bracket a speed
|
||||||
// fan transition. Matching samples cannot be discarded during discovery: one may be the last
|
// transition. Matching samples cannot be discarded during discovery: one may be the last
|
||||||
// supported point before a narrow unsupported pocket found by a later probe.
|
// supported point before a narrow unsupported pocket found by a later probe.
|
||||||
size_t kept = 0;
|
size_t kept = 0;
|
||||||
for (size_t i = 0; i < interior.size(); ++i) {
|
for (size_t i = 0; i < interior.size(); ++i) {
|
||||||
@@ -211,15 +195,15 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
|||||||
const bool at_end = i + 1 == interior.size(); // And nothing follows the last sample but the segment's end
|
const bool at_end = i + 1 == interior.size(); // And nothing follows the last sample but the segment's end
|
||||||
const float before = at_start ? curr.distance : interior[kept - 1].second;
|
const float before = at_start ? curr.distance : interior[kept - 1].second;
|
||||||
const float after = at_end ? next.distance : interior[i + 1].second;
|
const float after = at_end ? next.distance : interior[i + 1].second;
|
||||||
// A sample is worth a point in the path only where it prints differently, in speed or fan state,
|
// A sample is worth a point in the path only where it prints at a different speed from the
|
||||||
// from the points either side of it. Differing from one of the segment's own ends is not enough on
|
// readings either side of it. Differing from one of the segment's own ends is not enough on
|
||||||
// its own where the sample is not the slower or cooled of the two: the segmentation pass below
|
// its own where the sample is the faster of the two: the segmentation pass below already
|
||||||
// already confines the slowdown and cooling at an end, at a distance taken from how far out that
|
// ends the slowdown an end reads, at a distance taken from how far out that end is rather
|
||||||
// end is rather than from wherever bisection happened to stop, and a point here would leave the
|
// than from wherever bisection happened to stop, and a point here would leave the span
|
||||||
// span beside the end too short for that pass to run at all. Support an end cannot account for,
|
// beside the end too short for that pass to run at all. Support an end cannot account for,
|
||||||
// where the interior is the slower or cooled of the two, is exactly what this pass is here to find.
|
// where the interior is the slower reading, is exactly what this pass is here to find.
|
||||||
const bool worth_before = !same_speed_and_fan(sample, before) && (!at_start || slower_or_cooled(sample, before));
|
const bool worth_before = !same_speed(sample, before) && (!at_start || prints_slower(sample, before));
|
||||||
const bool worth_after = !same_speed_and_fan(sample, after) && (!at_end || slower_or_cooled(sample, after));
|
const bool worth_after = !same_speed(sample, after) && (!at_end || prints_slower(sample, after));
|
||||||
if (worth_before || worth_after)
|
if (worth_before || worth_after)
|
||||||
interior[kept++] = interior[i];
|
interior[kept++] = interior[i];
|
||||||
}
|
}
|
||||||
@@ -255,59 +239,51 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
|||||||
(next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) {
|
(next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) {
|
||||||
double line_len = (next.position - curr.position).norm();
|
double line_len = (next.position - curr.position).norm();
|
||||||
|
|
||||||
// ORCA: A line prints as slow as its slower end and is cooled if either end is, so an overhang at one
|
// ORCA: Segment path to smaller lines by adding additional points only if the path has an overhang that
|
||||||
// end would otherwise slow down or cool the whole line. Split the line so that only the part beside
|
// will trigger a slowdown and the path is also reasonably large, i.e. 2mm in length or more
|
||||||
// that end prints that way, if the line is reasonably long (2mm or more) and at least one end prints
|
// If there is no overhang in the start/end point, dont segment it.
|
||||||
// slower or cooled compared with a supported point (overhang distance 0). Deciding on how the end
|
// Ignore this check if the control of segmentation for overhangs is disabled (min_distance=-1)
|
||||||
// prints, rather than on its overhang distance against min_distance, also catches an end whose overhang
|
if ((min_distance > 0 && ((std::abs(curr.distance) > min_distance) || (std::abs(next.distance) > min_distance)) && line_len >= 2.f) ||
|
||||||
// distance is exactly where the slowdown begins, such as an outline crossing at half a line width.
|
(min_distance <= 0 && line_len > 4.0f)) {
|
||||||
// Without distance_to_speed, split every line over 4mm.
|
|
||||||
const bool split_line = distance_to_speed ?
|
|
||||||
line_len >= 2.f && (slower_or_cooled(curr.distance, 0.f) || slower_or_cooled(next.distance, 0.f)) :
|
|
||||||
line_len > 4.0f;
|
|
||||||
if (split_line) {
|
|
||||||
// Each end's piece is that end's overhang distance plus 1.5 line widths (3 * boundary_offset) long:
|
|
||||||
// a0 ends the piece beside curr, a1 starts the piece beside next.
|
|
||||||
double a0 = std::clamp((curr.distance + 3 * boundary_offset) / line_len, 0.0, 1.0);
|
double a0 = std::clamp((curr.distance + 3 * boundary_offset) / line_len, 0.0, 1.0);
|
||||||
double a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0);
|
double a1 = std::clamp(1.0f - (next.distance + 3 * boundary_offset) / line_len, 0.0, 1.0);
|
||||||
double t0 = std::min(a0, a1);
|
double t0 = std::min(a0, a1);
|
||||||
double t1 = std::max(a0, a1);
|
double t1 = std::max(a0, a1);
|
||||||
|
|
||||||
// Up to two cut points, in order along the line. Each takes its own overhang distance, so every
|
if (t0 < 1.0) {
|
||||||
// piece prints by the overhang distances at its own two ends. t0 >= 1 or t1 <= 0 falls on the
|
Vec p0 = curr.position + t0 * (next.position - curr.position);
|
||||||
// line's own end, so there is no cut. A cut closer than min_spacing to either end of the line is
|
auto [p0_dist, p0_near_l, p0_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||||
// not meaningful and is filtered out (#6714).
|
p0.template cast<AABBScalar>());
|
||||||
ExtendedPoint<L::Dim> cut[2]{};
|
ExtendedPoint<L::Dim> new_p{};
|
||||||
bool keep[2] = {false, false};
|
new_p.position = p0;
|
||||||
for (int k = 0; k < 2; ++k) {
|
new_p.distance = float(p0_dist + boundary_offset);
|
||||||
const double t = k == 0 ? t0 : t1;
|
// ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change
|
||||||
if (k == 0 ? t >= 1.0 : t <= 0.0)
|
// or if this option is disabled (min_distance<=0)
|
||||||
continue;
|
if( (std::abs(p0_dist) > min_distance) || (min_distance<=0)){
|
||||||
const Vec p = curr.position + t * (next.position - curr.position);
|
// ORCA: also filter out points that are introduced to the start of the path when their distance from the start point is
|
||||||
auto [p_dist, p_near_l, p_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
// not meaningful
|
||||||
p.template cast<AABBScalar>());
|
if ((p0 - curr.position).norm() > min_spacing && (next.position - p0).norm() > min_spacing) {
|
||||||
cut[k].position = p;
|
new_points.push_back(new_p);
|
||||||
cut[k].distance = float(p_dist + boundary_offset);
|
}
|
||||||
keep[k] = (p - curr.position).norm() > min_spacing && (next.position - p).norm() > min_spacing;
|
}
|
||||||
|
}
|
||||||
|
if (t1 > 0.0) {
|
||||||
|
Vec p1 = curr.position + t1 * (next.position - curr.position);
|
||||||
|
auto [p1_dist, p1_near_l, p1_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||||
|
p1.template cast<AABBScalar>());
|
||||||
|
ExtendedPoint<L::Dim> new_p{};
|
||||||
|
new_p.position = p1;
|
||||||
|
new_p.distance = float(p1_dist + boundary_offset);
|
||||||
|
// ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change
|
||||||
|
// or if this option is disabled (min_distance<=0)
|
||||||
|
if( (std::abs(p1_dist) > min_distance) || (min_distance<=0)){
|
||||||
|
// ORCA: filter out points that are introduced to the end of the path when their distance from the end point is
|
||||||
|
// not meaningful
|
||||||
|
if ((p1 - curr.position).norm() > min_spacing && (next.position - p1).norm() > min_spacing) {
|
||||||
|
new_points.push_back(new_p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (distance_to_speed) {
|
|
||||||
// Only keep a cut that changes the G-code: one that prints differently from at least one of the
|
|
||||||
// points either side of it, which are the line's ends or the other cut where that is kept. A cut
|
|
||||||
// that prints like both would only split a move into two identical ones.
|
|
||||||
if (keep[0])
|
|
||||||
keep[0] = !same_speed_and_fan(cut[0].distance, curr.distance) ||
|
|
||||||
!same_speed_and_fan(cut[0].distance, keep[1] ? cut[1].distance : next.distance);
|
|
||||||
if (keep[1])
|
|
||||||
keep[1] = !same_speed_and_fan(cut[1].distance, keep[0] ? cut[0].distance : curr.distance) ||
|
|
||||||
!same_speed_and_fan(cut[1].distance, next.distance);
|
|
||||||
// Two cuts closer together than min_spacing would leave a micro segment between them, so only the
|
|
||||||
// first is kept.
|
|
||||||
if (keep[0] && keep[1] && (cut[1].position - cut[0].position).norm() <= min_spacing)
|
|
||||||
keep[1] = false;
|
|
||||||
}
|
}
|
||||||
for (int k = 0; k < 2; ++k)
|
|
||||||
if (keep[k])
|
|
||||||
new_points.push_back(cut[k]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_points.push_back(next);
|
new_points.push_back(next);
|
||||||
@@ -447,10 +423,7 @@ public:
|
|||||||
const ConfigOptionFloatsOrPercents &speeds,
|
const ConfigOptionFloatsOrPercents &speeds,
|
||||||
float ext_perimeter_speed,
|
float ext_perimeter_speed,
|
||||||
float original_speed,
|
float original_speed,
|
||||||
bool slowdown_for_curled_edges,
|
bool slowdown_for_curled_edges)
|
||||||
// Overlap at or below which the overhang fan switches on; negative when the fan
|
|
||||||
// does not depend on overlap.
|
|
||||||
float fan_overlap_threshold = -1.0f)
|
|
||||||
{
|
{
|
||||||
size_t speed_sections_count = std::min(overlaps.values.size(), speeds.values.size());
|
size_t speed_sections_count = std::min(overlaps.values.size(), speeds.values.size());
|
||||||
std::vector<std::pair<float, float>> speed_sections;
|
std::vector<std::pair<float, float>> speed_sections;
|
||||||
@@ -490,8 +463,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no overhang distance slows this path down, -1 turns interior sampling off unless the overhang fan can switch.
|
// If a meaningful (i.e. needing slowdown) overhang distance was not found, then we shouldn't split the lines
|
||||||
// Lines are only split where an end prints slower or cooled, so here only a fan switch splits them.
|
|
||||||
if (!found)
|
if (!found)
|
||||||
smallest_distance_with_lower_speed=-1.f;
|
smallest_distance_with_lower_speed=-1.f;
|
||||||
|
|
||||||
@@ -515,17 +487,9 @@ public:
|
|||||||
return round(final_speed);
|
return round(final_speed);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ORCA: The speed sections are built from ext_perimeter_speed, which can be above the speed this path prints at
|
|
||||||
// (original_speed, e.g. held down by resonance avoidance). Every segment is capped at original_speed below, so
|
|
||||||
// overhang distances whose speeds differ only above it print the same and must not count as a speed change when
|
|
||||||
// the path is split.
|
|
||||||
auto effective_speed = [&calculate_speed, original_speed](float distance) {
|
|
||||||
return std::min(calculate_speed(distance), original_speed);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<ExtendedPoint<3>> extended_points =
|
std::vector<ExtendedPoint<3>> extended_points =
|
||||||
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width, -1,
|
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width, -1,
|
||||||
smallest_distance_with_lower_speed, effective_speed, fan_overlap_threshold);
|
smallest_distance_with_lower_speed, calculate_speed);
|
||||||
const auto width_inv = 1.0f / path.width;
|
const auto width_inv = 1.0f / path.width;
|
||||||
std::vector<ProcessedPoint> processed_points;
|
std::vector<ProcessedPoint> processed_points;
|
||||||
processed_points.reserve(extended_points.size());
|
processed_points.reserve(extended_points.size());
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
#include "InstanceLock.hpp"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <system_error>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
#include <boost/nowide/fstream.hpp>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <boost/interprocess/sync/file_lock.hpp>
|
||||||
|
#include <boost/nowide/convert.hpp>
|
||||||
|
#else
|
||||||
|
#include <cerrno>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// LockFileEx, held by this handle alone.
|
||||||
|
using NativeFileLock = boost::interprocess::file_lock;
|
||||||
|
#else
|
||||||
|
// flock(2) rather than an fcntl lock: it belongs to this open file description,
|
||||||
|
// so any other code in the process that opens and closes the lock file, as a
|
||||||
|
// backup or an export walking the data dir might, cannot drop it. An fcntl
|
||||||
|
// lock would go with the first such close.
|
||||||
|
class NativeFileLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NativeFileLock(const char *path) : m_fd(::open(path, O_RDWR | O_CREAT | O_CLOEXEC, 0644))
|
||||||
|
{
|
||||||
|
if (m_fd < 0)
|
||||||
|
throw std::system_error(errno, std::generic_category(), path);
|
||||||
|
}
|
||||||
|
~NativeFileLock() { ::close(m_fd); }
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
if (::flock(m_fd, LOCK_EX | LOCK_NB) == 0)
|
||||||
|
return true;
|
||||||
|
// A signal (a child exiting, for one) interrupts the call like any other; the caller polls again.
|
||||||
|
if (errno == EWOULDBLOCK || errno == EINTR)
|
||||||
|
return false;
|
||||||
|
throw std::system_error(errno, std::generic_category(), "flock");
|
||||||
|
}
|
||||||
|
void unlock() { ::flock(m_fd, LOCK_UN); }
|
||||||
|
private:
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// One slot per lock file, shared by every guard in the process: one lock
|
||||||
|
// object per path behind a mutex is what makes the guard re-entrant and safe
|
||||||
|
// to use from the preset sync thread and the GUI thread at once. The lock
|
||||||
|
// file is opened by the outermost guard and closed when it goes, so the file
|
||||||
|
// is never held open between guards: whatever is at the path is what gets
|
||||||
|
// locked, and a data dir can be removed once nothing is saving into it. The
|
||||||
|
// file is kept rather than deleted on release because the lock state lives in
|
||||||
|
// the kernel on the open file, and deleting it would let a third instance
|
||||||
|
// lock a fresh file while the second still holds the old one.
|
||||||
|
struct InstanceLock::Slot
|
||||||
|
{
|
||||||
|
std::recursive_mutex mutex;
|
||||||
|
// Non-null exactly while this process holds the file lock.
|
||||||
|
std::unique_ptr<NativeFileLock> file_lock;
|
||||||
|
int depth{0};
|
||||||
|
// Until this point, after a guard could not open, lock or wait out the
|
||||||
|
// file, guards do not touch it.
|
||||||
|
std::chrono::steady_clock::time_point cooldown_until{};
|
||||||
|
};
|
||||||
|
|
||||||
|
InstanceLock::Slot &InstanceLock::slot_for(const std::string &lock_file_path)
|
||||||
|
{
|
||||||
|
// Never freed: a save during static destruction still needs its slot.
|
||||||
|
static auto *registry_mutex = new std::mutex();
|
||||||
|
static auto *registry = new std::map<std::string, std::unique_ptr<Slot>>();
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(*registry_mutex);
|
||||||
|
std::unique_ptr<Slot> &slot = (*registry)[lock_file_path];
|
||||||
|
if (! slot)
|
||||||
|
slot = std::make_unique<Slot>();
|
||||||
|
return *slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts the cool-down. Called with the slot mutex held.
|
||||||
|
void InstanceLock::defer(Slot &slot, const std::string &reason)
|
||||||
|
{
|
||||||
|
slot.cooldown_until = std::chrono::steady_clock::now() + cooldown;
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << reason << "; proceeding without the lock for the next " << cooldown.count() << " ms";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates the lock file if needed and opens it, or starts the cool-down.
|
||||||
|
// Called with the slot mutex held.
|
||||||
|
bool InstanceLock::open_lock_file(Slot &slot, const std::string &lock_file_path)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// The lock opens an existing file; created once, on the first miss.
|
||||||
|
const std::wstring wide_path = boost::nowide::widen(lock_file_path);
|
||||||
|
try {
|
||||||
|
slot.file_lock = std::make_unique<NativeFileLock>(wide_path.c_str());
|
||||||
|
} catch (const std::exception &) {
|
||||||
|
boost::nowide::ofstream(lock_file_path, std::ios::app).close();
|
||||||
|
slot.file_lock = std::make_unique<NativeFileLock>(wide_path.c_str());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
slot.file_lock = std::make_unique<NativeFileLock>(lock_file_path.c_str());
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
defer(slot, "Cannot open lock file " + lock_file_path + ": " + e.what() + " (check its owner and permissions)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceLock::InstanceLock(const std::string &lock_file_path, std::chrono::milliseconds timeout)
|
||||||
|
{
|
||||||
|
if (lock_file_path.empty())
|
||||||
|
return;
|
||||||
|
m_slot = &slot_for(lock_file_path);
|
||||||
|
m_slot_guard = std::unique_lock<std::recursive_mutex>(m_slot->mutex);
|
||||||
|
const auto now = std::chrono::steady_clock::now();
|
||||||
|
if (m_slot->depth == 0 && now >= m_slot->cooldown_until && open_lock_file(*m_slot, lock_file_path)) {
|
||||||
|
const auto deadline = now + timeout;
|
||||||
|
bool taken = false;
|
||||||
|
for (;;) {
|
||||||
|
try {
|
||||||
|
if ((taken = m_slot->file_lock->try_lock()))
|
||||||
|
break;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
defer(*m_slot, "Cannot lock " + lock_file_path + ": " + e.what());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (std::chrono::steady_clock::now() >= deadline) {
|
||||||
|
defer(*m_slot, "Another instance has held " + lock_file_path + " for over " + std::to_string(timeout.count()) + " ms");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
}
|
||||||
|
if (! taken)
|
||||||
|
m_slot->file_lock.reset();
|
||||||
|
}
|
||||||
|
// Counted last, so a throw above leaves the slot exactly as it was found.
|
||||||
|
++ m_slot->depth;
|
||||||
|
m_locked = m_slot->file_lock != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceLock::~InstanceLock()
|
||||||
|
{
|
||||||
|
if (m_slot == nullptr)
|
||||||
|
return;
|
||||||
|
if (-- m_slot->depth == 0 && m_slot->file_lock) {
|
||||||
|
try {
|
||||||
|
m_slot->file_lock->unlock();
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << "Cannot unlock instance lock: " << e.what();
|
||||||
|
}
|
||||||
|
m_slot->file_lock.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Scoped write lock on a file shared by every running instance of the
|
||||||
|
// application, such as the app config or the user preset directory: threads
|
||||||
|
// of this process are serialised through a recursive mutex, other processes
|
||||||
|
// through an advisory OS file lock on `lock_file_path`. The lock file is
|
||||||
|
// created on first use and kept; the OS releases the lock when its holder
|
||||||
|
// exits, so a crashed instance never leaves a stale lock behind.
|
||||||
|
//
|
||||||
|
// Best effort: when the lock file cannot be opened or locked, or another
|
||||||
|
// instance still holds it after `timeout`, the guard keeps only the in-process
|
||||||
|
// mutex, locked() reports false and the write proceeds, since a hung instance
|
||||||
|
// must never block another one from saving. For `cooldown` afterwards guards
|
||||||
|
// leave the file alone. The wait for the in-process mutex is bounded only by
|
||||||
|
// the longest critical section, so a guard covers a few file operations and
|
||||||
|
// nothing slower.
|
||||||
|
//
|
||||||
|
// Lock order: the preset collection mutex may be held when a guard is taken
|
||||||
|
// (set_sync_info_and_save() calls save_info() under it), never the reverse;
|
||||||
|
// that is why the guards sit at the leaf readers and writers and why a guard
|
||||||
|
// must not be added around save_user_presets(), which takes the collection
|
||||||
|
// mutex through delete_preset().
|
||||||
|
class InstanceLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Long against a critical section of milliseconds, short against the GUI
|
||||||
|
// thread, which is where most guards are taken.
|
||||||
|
static constexpr std::chrono::milliseconds default_timeout{1000};
|
||||||
|
// Long enough that a holder stuck in a debugger does not cost a stall per
|
||||||
|
// save; mutable so tests can shorten it.
|
||||||
|
static inline std::chrono::milliseconds cooldown{10000};
|
||||||
|
|
||||||
|
// An empty path makes the guard a no-op.
|
||||||
|
explicit InstanceLock(const std::string &lock_file_path, std::chrono::milliseconds timeout = default_timeout);
|
||||||
|
~InstanceLock();
|
||||||
|
|
||||||
|
InstanceLock(const InstanceLock &) = delete;
|
||||||
|
InstanceLock &operator=(const InstanceLock &) = delete;
|
||||||
|
|
||||||
|
// True while this process holds the cross-process file lock.
|
||||||
|
bool locked() const { return m_locked; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Slot;
|
||||||
|
static Slot &slot_for(const std::string &lock_file_path);
|
||||||
|
static bool open_lock_file(Slot &slot, const std::string &lock_file_path);
|
||||||
|
static void defer(Slot &slot, const std::string &reason);
|
||||||
|
|
||||||
|
Slot *m_slot{nullptr};
|
||||||
|
std::unique_lock<std::recursive_mutex> m_slot_guard;
|
||||||
|
bool m_locked{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
@@ -13,8 +13,19 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
|
||||||
|
// How many setters this thread holds, so the ones nested in another can skip
|
||||||
|
// setlocale, which takes a lock the whole process shares on Windows.
|
||||||
|
static thread_local int s_numeric_locale_depth = 0;
|
||||||
|
|
||||||
CNumericLocalesSetter::CNumericLocalesSetter()
|
CNumericLocalesSetter::CNumericLocalesSetter()
|
||||||
{
|
{
|
||||||
|
// Nested in another setter on this thread, whose "C" the separator check
|
||||||
|
// confirms is still set.
|
||||||
|
if (s_numeric_locale_depth > 0 && is_decimal_separator_point()) {
|
||||||
|
m_nested = true;
|
||||||
|
++ s_numeric_locale_depth;
|
||||||
|
return;
|
||||||
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
|
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
|
||||||
m_orig_numeric_locale = std::setlocale(LC_NUMERIC, nullptr);
|
m_orig_numeric_locale = std::setlocale(LC_NUMERIC, nullptr);
|
||||||
@@ -29,12 +40,17 @@ CNumericLocalesSetter::CNumericLocalesSetter()
|
|||||||
m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_new_locale);
|
m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_new_locale);
|
||||||
uselocale(m_new_locale);
|
uselocale(m_new_locale);
|
||||||
#endif
|
#endif
|
||||||
|
// Counted last, since the destructor does not run for a constructor that throws.
|
||||||
|
++ s_numeric_locale_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CNumericLocalesSetter::~CNumericLocalesSetter()
|
CNumericLocalesSetter::~CNumericLocalesSetter()
|
||||||
{
|
{
|
||||||
|
-- s_numeric_locale_depth;
|
||||||
|
if (m_nested)
|
||||||
|
return;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::setlocale(LC_NUMERIC, m_orig_numeric_locale.data());
|
std::setlocale(LC_NUMERIC, m_orig_numeric_locale.data());
|
||||||
#else
|
#else
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user