The config was always replaced by a rename, never written in place, so
the write helper's refusal of a read-only target, right for the presets
it mirrors, stopped a read-only OrcaSlicer.conf from ever being saved
again. The helper takes an explicit opt-in to replace such a file, and
the two config save variants share one writer that uses it.
The identity helper's stat headers were included only under the Linux
guard, which the Linux-only build never noticed; they are included on
every platform now. A temporary the longer name pushes past the path
limit is written in place like one refused for permissions, the rename
retry that waits for a Windows reader runs on Windows only, a failing
stat in the sweep skips that entry rather than ending the sweep, and the
rename fallback no longer stats the target it is about to remove.
Holding the lock across the whole preset scan meant a reload on a
background thread, which the login path runs, blocked a save on the GUI
thread for the scan's duration through the in-process mutex, which has
no timeout. Each file is locked on its own now, which keeps a file whole
under a reader without keeping the saver waiting.
A guard kept its handle to the lock file for good, so a lock file that
someone deleted or recreated left this instance locking a file no other
instance could see. The guard compares what the path names against what
it opened and reopens when they differ. Preset::save() serialises before
it takes the lock, so the exclusive window is the two file writes.
On Windows an unlocked reader, which the CLI and a timed-out instance
are by design, made the rename fail at once and the write go in place
under that reader; the rename is retried for half a second first, since
a reader is done in milliseconds, and the fallback when no temporary
can be created is logged like the other one. The sweep matches only the
exact <name>.<pid>.<n>.tmp shape and waits an hour, since hosts sharing a
data dir may disagree on the time. Real write access is checked with
access(), the read-only tests skip as root, and the dead permissions
block after the rename is gone.
The sweep's prefix form counted any <name>.<digits> file as a leftover of
the old config writer, so a user's OrcaSlicer.conf.1 backup went at the
next start. Only the <name>.<pid>.<n>.tmp form is a temporary now, and
the name is tested before the entry is stat'ed.
The read-only check went by mode bits, which misses a deny-write ACL on
Windows and refuses a root-owned file root can write; it asks the OS
with access() instead. The two-step rename fallback runs only for the
errors a refused replace produces, never for an I/O error that would
only lose the target, and says so if the second step fails after the
old file is gone.
The orphaned-.info scan on the sync thread reads each .info under the
lock, so a remove_files() in another instance is seen whole or not at
all, and queues the cloud delete after the lock is released, keeping the
queue mutex outside it. AppConfig::save() assembles its text before it
takes the lock, like Preset::save(). The two bundle loops share one
metadata loader, and the two-thread write test counts leftover
temporaries rather than every directory entry, since a scanner on
Windows may hold the old file under another name for a moment.
Sweeping the target's directory from inside write_file_atomically() made
every settings export into a user's folder delete their own numbered
files that matched the older config temporary form, and cost a directory
walk per save. The helper writes its target and nothing else; the user
preset scan, the bundle metadata reads and AppConfig::load() sweep the
directories the application owns, once, while they hold the lock.
Replacing a file needs only a writable directory, so a preset or config
the user made read-only was overwritten where the in-place write used to
fail; such a target is refused before anything is written. The CLI's
load_if_exists() takes no lock and creates no lock file, since the CLI
never saves. The lock guard holds the slot mutex through a unique_lock,
so an exception during construction cannot leave the slot locked for
good, and it counts its entry last so a throw leaves the slot as found;
the cool-down after a failed open is set where the failure is seen.
The cloud agent's sync state and secret fallback file and the 3DPrinterOS
session file wrote through a fixed ".tmp" name with a non-Unicode stream;
they call the helper. The vendor cache failure test makes the cache
read-only, which the helper refuses on every platform, and the utility
tests carry the PascalCase tag the test rules ask for.
Two threads writing one target without a lock shared the same temporary
name, so one could truncate it under the other; the name now carries a
per-call counter. The helper takes its content as chunks, which lets the
vendor cache hand over its header and body without copying the blob, and
AppConfig::save() goes through it too, including the Windows backup copy,
so the config's temporaries get the same handling as everyone else's.
Copying the target's permissions onto the temporary set a read-only bit
that stopped the rename itself on Windows; they are applied after the
rename there. The two-step rename fallback triggers on whatever error a
mount reports when the target is still there, since FUSE, gvfs and MTP
refuse a replacing rename with errors other than the three it handled.
Every successful write sweeps stale temporaries of its own target, so
leftovers beside the bundle metadata, physical printers, plugin config
and profile cache are covered, and the older OrcaSlicer.conf.<pid> form
with them. The bundle metadata guard is taken per file, never while the
bundle registry's writer lock is held, so the two are not taken in both
orders. The lock guard's open-and-lock steps are one block, and the
read-only choice lives in user_presets_lock_path() instead of at each
call site.
The vendor cache test that blocked the old fixed temporary name with a
directory provokes the failure through permissions instead.
Some mounts refuse to replace an existing file in one rename, and the
old remove-then-rename worked there where the atomic path now fails, so
rename_file() takes the two-step route when a one-step replace is
refused and write_file_atomically() writes in place whenever the rename
fails, not only for the Windows sharing case.
An instance that gave up waiting for the lock writes unlocked by design,
so a peer holding the lock could sweep its in-flight temporary and make
its rename fail; only temporaries older than ten minutes are removed now,
and the sweep uses the error-code overloads so an entry vanishing between
listing and stat cannot throw out of startup. The registry mutex is
leaked like the map it guards, so a save during static destruction does
not lock a destroyed mutex.
The physical printer loader is never called, so its guard is gone, while
the two delete paths that do run now hold the lock. The bundle metadata
loader is lock-free again, since the zip import reads it from a scratch
folder; the guard sits at the two scans that read the user's bundles.
Preset::save() builds what it writes before taking the lock, the cache
writer reserves its payload, and the retry test tolerates a slow runner.
A lock file that failed to open once stayed unopened for the rest of the
process, so a scanner holding the fresh file for a moment on Windows
silently disabled the lock for the session, and a lock call that throws,
as it does on a share without a lock service, was re-attempted and logged
by every guard. Both are now left alone for the cool-down and then retried.
Renaming a fresh file over the target turned a symlinked preset into a
plain file, reset its permissions to the umask default, and could not
work at all for a settings export to a device or pipe, since a temporary
cannot be created beside /dev/stdout. A target that is not a regular file
is now written in place, an existing target keeps its permissions, and a
directory that refuses the temporary but not the file falls back too.
The inline PhysicalPrinter::save() overload was the one physical printer
writer without the guard. load_info() took the lock redundantly under the
scan guard and, in read-only mode, created user.lock per file; the bundle
metadata reader now honours read_only too. The plugin config, the setup
guide's profile cache and the vendor preset cache wrote through a
temporary by hand; they use the helper, with a binary mode for the cache.
A crash between temporary and rename left a <name>.<pid>.tmp behind for
good; AppConfig::load() and the preset scan remove stale ones while they
hold the lock, and AppConfig::save() names its temporary the same way.
Windows refuses to replace a file that another process holds open without
FILE_SHARE_DELETE, which is how the C runtime opens files for reading, so
the atomic write could fail against a concurrent reader and drop the save
where the old in-place write had succeeded. Lock the readers that were
still outside the guard, Preset::reload() and the physical printer loader
and writer, and when the rename still fails that way, log it and write in
place as before; losing the save is worse than a torn read. Report the OS
error from a failed write instead of a generic I/O error.
Each leaf guard paid the full two-second wait on its own, so a bulk save
against an instance holding the lock for a long scan stalled once per
preset while holding the preset collection mutex. After a timed-out wait
the same lock file is not waited on again for ten seconds. Read-only scans
never rewrite or delete and many CLI jobs may share one data dir, so they
take no lock and no longer queue behind each other or log about writing.
Take the bundle metadata guard beside the write rather than while the JSON
is built, state the lock-order rule in the header, and give the tests a
temporary file rather than a directory, since the process keeps the lock
file open and a directory holding it cannot be removed on Windows.
Every running instance shares one OrcaSlicer.conf and one user preset
tree, and nothing kept their writers apart. Two instances saving at the
same moment, or the cloud preset sync thread writing while the GUI thread
saved, could interleave, and a reader in another instance could open a
preset JSON or .info file between truncate and close and get a partial
file, dropping that preset for the session with a parse error.
Add InstanceLock, a scoped guard that serialises the threads of one
process through a recursive mutex and other processes through an advisory
OS file lock, which the OS releases when its holder dies. It is best
effort: when the lock file cannot be created, or another instance still
holds it after two seconds, the guard logs a warning and lets the write
proceed rather than letting a hung instance block every other one.
AppConfig::save() and load() hold OrcaSlicer.conf.lock; load is included
because the Windows path restores from the .bak copy, and because Windows
cannot replace a file another process has open, so an unlocked reader
there made the other instance's save fail. Every user preset writer and
reader holds user.lock: Preset::save(), save_info(), load_info() and
remove_files(), the whole directory scan in load_presets(), the bundle
metadata file, the .info removal after a cloud-confirmed delete and the
bundle folder removal on unsubscribe. The guard sits at the leaf writers
on purpose: set_sync_info_and_save() calls save_info() under the preset
collection mutex, so a batch lock around save_user_presets(), which takes
that mutex through delete_preset(), would invert the order.
Write preset JSON, .info and bundle metadata files through a temporary
file beside the target that is renamed over it, so a reader that never
waits still sees a complete old or new file. On Linux and macOS
rename_file() deleted the target before renaming, leaving a window in
which the file did not exist at all, and returned a meaningless error
code on failure; rename() replaces atomically, so call it directly.
AppConfig::save() now logs a failed final rename instead of dropping the
save silently.
Add the one-all-printer-preset-per-product rule to the orca-profiles skill:
color is chosen at runtime, a material family is a new product and a color is
not, and CI does not catch per-color presets so it stays a review call. Note
that @System is the all-printer convention rather than an enforced check.
orca.host.ui.create_dock_panel(html, title, width, height, on_message,
on_close, dock) hosts plugin HTML in a pane of the Plater's dock manager,
next to the sidebar, and returns a UiDockPanel handle
(post/show/hide/close/is_open). The arguments follow create_window(). The
panel uses the window.orca bridge of plugin windows, restores its position
and size from the saved window layout, hides with the Plater off the Prepare
and Preview tabs when floating, and is closed with its plugin; plugin panes
are removed in MainFrame::shutdown().
The web view hosting moves out of PluginPage into a shared WebPanel base:
bootstrap page and swap to the plugin HTML, theme, element-default and
bridge scripts, window.orca message parsing, delivery to the page, and live
re-theming, also re-applied on every load after the swap. Pages tabs and
docked panels both derive from it. Pages tabs now re-theme in place on a
theme change instead of being reloaded, and a window.orca call a host does
not support is logged.
What the hosts share no longer lives in one of them: the bootstrap page, the
base URL and the plugin-window bridge move to Widgets/WebHosting, used by
WebDialog and WebPanel alike. The Plater restores plugin panes with a new
saved-layout parser, GUI/AuiPaneLayout, kept in its own small header so
slic3rutils can test it without pulling in the Plater.
The web hosting classes carry no plugin name, so other hosts can reuse them:
PluginWebDialog becomes WebDialog (its bootstrap page moves to
resources/web/dialog/WebDialog), and destroy_for_plugin(),
load_plugin_content() and plugin_defaults_user_script() become
destroy_silently(), load_page_html() and element_defaults_user_script().
Includes a sample plugin (sandboxes/orca_dock_panel_plugin_any.py) and
binding and layout-helper tests in slic3rutils.
* Add PlastAR and Printalot filament vendors
Two Argentine brands from Printalot: PlastAR (budget PLA) and Printalot
(ABS). Each has a tuned @base plus per-color presets covering the
manufacturer's color lineup.
PlastAR PLA: flow 0.98, 1.75 mm, nozzle 220 C (190-230), bed 60 C; 14 colors.
Printalot ABS: flow 0.94, density 1.05, retraction 0.2 mm, max volumetric
18 mm3/s, nozzle 250 C (240-270), bed 100 C; 14 colors.
Per-color presets inherit their @base (no per-color parameter changes).
Passes scripts/orca_extra_profile_check.py.
* Ship PlastAR and Printalot as a single Printalot filament vendor
Place both Argentine lines in one OrcaFilamentLibrary/Printalot bundle and follow the library's brand shape: a non-selectable @base plus one all-printer @System per product, which is where a library preset meant for every printer belongs. The former per-color presets are dropped, leaving PlastAR PLA and Printalot ABS with their PLA and 250 C ABS material values. setting_ids are minted by the tooling; filament_ids resolve through the @base roots.
---------
Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
* Add Polymaker PLA Pro filament profile
Polymaker PLA Pro is present in the tree only as printer-scoped variants
under Snapmaker U1 and Anycubic Kobra S1, so it is invisible to every other
printer. This adds it to the Orca Filament Library as OGFPM020 so it is
selectable generally.
Values are taken from the manufacturer's published print settings and
cross-checked against the two existing vendor profiles:
density 1.23 g/cm3 both existing profiles agree
softening 55 C both existing profiles agree
nozzle 220 C (210-230) manufacturer's stated range
max volumetric speed 15 Snapmaker 15, Anycubic 16
Flow ratio is set to 0.96, matching the Snapmaker profile. Worth noting for
review: the two existing profiles disagree here -- Snapmaker 0.96, Anycubic
0.85 -- because flow ratio depends on the extruder as much as the filament.
Any single value in a vendor-neutral preset is a starting point users should
calibrate; 0.96 is closer to the generic PLA baseline than 0.85 is.
setting_id assigned by scripts/assign_vendor_setting_ids.py.
OrcaFilamentLibrary version bumped 02.04.00.03 -> 02.04.00.04.
* fix errors
---------
Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
* Add Meltingplot vendor profiles (CHX 350 + MBL series)
Adds the Meltingplot vendor bundle with 5 printer models:
- CHX 350 (880x422x943, RepRapFirmware/Duet)
- MBL 133/136/308/480 (RepRapFirmware/Duet)
Each model ships 0.4/0.6/0.8/1.0/1.2 nozzle variants. Layer height
presets span 40-60% of the nozzle diameter and deliberately avoid
heights that divide the Z screw lead evenly (CHX: 1204 ball screw,
4 mm lead; MBL: TR4x2 trapezoidal screw, 8 mm lead) so periodic
screw error does not repeat as banding.
All printers use 2.85 mm filament, so the bundle carries its own
filament library (PLA, StoneFil, ABS, TitanX, ASA, PETG, PA6 CF HT,
STYX 12, PP 9-2, PET-CF15, Extrudr PLA NX2 Matt, Igus iglidur J260)
with the 2.85 mm diameter pinned once in the vendor-local
fdm_filament_common base.
Machine limits mirror the printers' firmware configuration; machine
limit emission is disabled so the values only feed the time estimator.
* Add per-nozzle volumetric flow limits and nozzle size in filename
Cap filament volumetric speed per nozzle (0.4: 14, 0.6: 20, 0.8: 26,
1.0: 30, 1.2: 40 mm3/s). Filaments whose limit exceeds a nozzle's
capability get a nozzle-scoped child profile that only lowers
filament_max_volumetric_speed; filament_id is inherited so all nozzle
variants remain the same material.
Also include layer height and nozzle diameter in the g-code filename.
* Set CHX 350 machine time cost to 5 EUR/h
* Inherit Meltingplot filaments from OrcaFilamentLibrary generics
Per the profile creation guide, vendor filament profiles now inherit
from Generic * @System instead of vendor-local fdm_filament_* copies.
Each profile carries only Meltingplot-specific deviations plus the
2.85 mm filament diameter; the seven local fdm_filament_* base files
are removed.
Deliberate pins where the library default would change tuned behavior:
- PLA/ABS/TitanX keep filament_max_volumetric_speed 20 (0.6 nozzle cap)
- ABS/PET-CF15 keep close_fan_the_first_x_layers 1
- STYX 12 sets required_nozzle_HRC 0 (unfilled PA12, density 1.02)
* Remove Meltingplot StoneFil filament profile
* Meltingplot ABS: use library fan settings
* Meltingplot TitanX/ABS: use library fan and nozzle temperature settings
* Remove STYX 12, PP 9-2 and Igus iglidur J260 filament profiles
* Meltingplot ASA: use library fan_max_speed
* Derive per-nozzle volumetric speed caps from physical limit formula
Caps now follow V = 34*d * m / S: the 34*d limit line calibrated on
Micro Swiss Volcano plated copper at 2.85 mm, material factor m from
the OrcaFilamentLibrary generic ratios (PLA/ABS/ASA 1.0, PETG 10/12,
PETG-CF 11.5/12, PA-CF 8/12, PLA Matte 11/12), safety factor S = 1.25
covering batch/moisture/wear/diameter tolerances.
Each material base now serves the 1.2 nozzle at its maximum cap;
children @0.4-@1.0 lower the cap per nozzle. Machine variant
default_filament_profile entries point at the matching preset.
* Scale slow_down_layer_time per nozzle from bead cross-section
Minimum layer time follows the derived cooling rule: heat per layer
scales with bead cross-section (layer height x line width), so the
0.8-nozzle-tuned values are scaled by q(d)/q(0.8) using each nozzle's
standard preset geometry. Bases carry the 1.2 value, children @0.4-@1.0
their nozzle-specific value.
* Meltingplot: lift Z above the print before the end macro
Add a G90 / G1 Z{min(max_layer_z + 5, printable_height)} F600 move at the
start of machine_end_gcode, before M98 print_end shuts the printer down and
parks it. Besides clearing the part, the explicit Z coordinate lets the Duet
file-info parser pick up the object height.
* Meltingplot: cap default layer height at 40% of outer wall width
A 45 deg slope shifts each bead outward by exactly one layer height. With
the Slic3r bead model (rectangle (w-h) x h plus half-circles of diameter h)
the flat contact band to the layer below is w - 2h, so the maximum
self-supporting angle is atan((w-h)/h). Support cannot compensate: the
stair tread at 45 deg is only h wide, far below one support line width, so
no support line ever fits underneath a single step.
All ten machine variants defaulted to h/w = 0.455..0.524, i.e. at or past
the h/w = 0.5 point where the flat contact vanishes. The 0.8 nozzle default
(0.44 mm at w = 0.84) reached atan(0.4/0.44) = 42.3 deg and failed on 45 deg
slopes even with support.
Default presets now satisfy h <= 0.40 * outer_wall_line_width, which leaves
one third of the bead's flat underside in contact at 45 deg and puts the
geometric limit at 56.3 deg. To keep the defaults on sensible ladder rungs,
outer wall width is widened where it was the binding constraint:
chx_small 110 -> 115%, chx_large 105 -> 110%, mbl_04 105 -> 115%.
Ladders are unchanged; the thicker rungs stay available for parts without
steep overhangs.
* Meltingplot PLA: raise slow_down_layer_time by calibration factor 1.5
Print feedback on CHX 350 with a 0.8 nozzle at 0.44 mm layer height showed
curling at the retraction points with the derived value of 25 s. There is no
cooling headroom left to trade: fdm_filament_pla pins fan_min_speed =
fan_max_speed = 100, and additional_cooling_fan_speed is inert because no
Meltingplot machine enables auxiliary_fan. Minimum layer time is the only
remaining lever; 35 s prints cleanly at that geometry.
The cross-section rule only fixes the ratios between nozzle sizes, so this
is a calibration of the PLA anchor itself: both PLA ladders are scaled by
1.5 (Extrudr 9/20/38/56/83 s, Meltingplot PLA 8/17/30/45/66 s for
0.4/0.6/0.8/1.0/1.2). The Extrudr base fan_cooling_layer_time goes 60 -> 100
so the 1.2-nozzle value stays below it.
Other materials are left unchanged - only the PLA anchor has a real
counter-example so far.
* Meltingplot: drop layer heights that cannot print 45 degree walls
A preset whose layer height exceeds ~45% of the outer wall line width has
less than ~6 degrees of reserve on a 45 degree wall (max self-supporting
angle atan((w-h)/h)), and support cannot compensate because the 45 degree
stair tread is only h wide - far below one support line. Those presets are
not usable in practice, so shipping them only invites failed prints.
Removes the 22 rungs above h/w = 0.45 and prunes them from the vendor
index. What remains per nozzle (default first):
CHX 350 0.4: 0.18 | 0.6: 0.24 0.28 | 0.8: 0.32 0.36
1.0: 0.44 0.48 | 1.2: 0.48 0.56
MBL 0.4: 0.18 | 0.6: 0.24 0.28 | 0.8: 0.36 0.34
1.0: 0.44 0.48 | 1.2: 0.48 0.56
The 0.4 nozzle keeps a single rung: 0.20 mm would qualify (h/w = 0.435) but
divides both screw leads evenly (4/0.20, 8/0.20) and stays excluded by the
Z-artifact rule, and 0.22 is already at 0.478.
Also corrects the MBL 0.8 default to 0.36 mm, which at w = 0.92 sits at
h/w = 0.391 and therefore still satisfies the stricter 40% default rule.
* Meltingplot: require 5 degrees of reserve on 45 degree walls
Replaces the two separate thresholds (h <= 0.40 * outer wall width for
defaults, 0.45 for ladder rungs) with a single requirement stated on the
design constraint itself: every shipped preset must reach
a_max = atan((w - h) / h) >= 50 deg
i.e. 5 degrees of reserve on a 45 degree wall, equivalent to
h <= 0.456 * outer_wall_line_width. The default is simply the thickest rung
that passes.
The 11 degrees the 40% rule produced were more margin than the failure mode
warrants, and cost throughput for no return. For calibration: across 940
machine defaults from 60 vendor bundles in this repo, the median reserve is
+1.8 deg, 71% ship less than 5 deg, and 8% cannot geometrically produce a
45 deg wall at all.
Adds the rungs the relaxed threshold makes available - 0.30 (0.6 nozzle,
both series) and 0.38 (0.8 nozzle, both series) - and restores the 0.30 mm
MBL preset removed in 5b4862b3 with its original setting_id. 0.20 mm on the
0.4 nozzle and 0.50 mm on the 1.0 nozzle would also qualify but stay
excluded because they divide both screw leads evenly.
Defaults are now (0.4/0.6/0.8/1.0/1.2) 0.18/0.30/0.38/0.48/0.56 for both
series, at 50.2 to 57.3 deg. The 1.2 nozzle deliberately keeps 0.56 rather
than the 0.60 the rule would allow: solidification time scales with h^2 and
bead weight with h*w, so the largest nozzle is the one that should not sit
on the minimum.
* Meltingplot: disable precise wall by default
Precise wall was inheriting OrcaSlicer's global default of true. Disable it
bundle-wide in the vendor process root so it applies to CHX 350 and all MBL
models. Note it was already ignored on the CHX small-nozzle branch, which
uses the inner-outer-inner wall sequence.
* Meltingplot CHX: raise max extruding acceleration to 6000
The 4000 limit silently clamped the profiles' 6000 values for default and
inner wall acceleration, since GCodeWriter caps print acceleration against
machine_max_acceleration_extruding regardless of emit_machine_limits_to_gcode.
Raising it to 6000 matches the X/Y limits so the configured values are emitted
as-is. The firmware's own M201 still governs what is actually driven.
* Meltingplot PA6 CF HT: raise part cooling floor to 40%
Sharp 90 degree corners were washing out layer by layer while straight walls
and overhangs printed cleanly. Overhangs are fine because overhang_fan_speed
forces 100% regardless of layer time; everything else fell back to
fan_min_speed, since at the layer times seen in practice neither branch of the
layer-time fan interpolation applies.
Raise fan_min_speed to 40% and set reduce_fan_stop_start_freq so that floor is
actually applied instead of dropping to zero. Also lower the auxiliary fan to
40% and raise the overhang cooling threshold to 95%, matching the values
validated on the print.
* Meltingplot: re-mint filament ids with orca_id_tool
Upstream now requires every filament_id to be a minted "OF" id derived
from the (filament_vendor, filament_type, name) triple and recorded in
scripts/filament_id_snapshot.json. The hand-made ids this bundle shipped
with (MPFPLA0, EXTNX2M, ...) were rejected by orca_extra_profile_check.
Regenerate them with "orca_id_tool.py --generate --vendor Meltingplot"
and record the result with --update-snapshot. No setting_id changed, and
the ids were never released, so no existing project file refers to them.
* Meltingplot: normalize bundle for updated profile checks
Drop obsolete keys (silent_mode, adaptive_layer_height, tree_support_with_infill) and rebuild the vendor index in canonical order, as orca_profile_tool.py normalize / update-index write them.
* Meltingplot: list per-nozzle filaments in default_materials
The unsuffixed filament presets only cover the 1.2 mm variants, so the 0.4-1.0 mm printer presets had no compatible entry in their model's default_materials. The validator's check_printer_default_materials rejects that, and load_installed_filaments would auto-install no filament for those variants on first run. Name the @0.4/0.6/0.8/1.0 nozzle presets alongside the base ones for PLA, PETG, ABS and ASA.
---------
Co-authored-by: yw4z <ywsyildiz@gmail.com>
* Add Flashforge Adventurer A5 printer profiles
Adds system profiles for the Flashforge Adventurer A5 to the existing
Flashforge vendor: the machine model with 0.25/0.4/0.6/0.8 mm nozzle variants,
14 process presets, and 43 filament presets, plus the printer cover image.
All presets inherit from existing Flashforge bases already in-tree
(Adventurer 5M Pro nozzle profiles, AD5M Pro process/filament presets,
Flashforge generics); no new base assets are introduced (the A5 reuses the
existing 5M-series bed/hotend models and buildplate texture). Every inherits
reference and sub_path was validated to resolve.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Assign setting_id to Adventurer A5 presets (fix profile check)
The new A5 filament and process presets were missing the deterministic
setting_id required by OrcaSlicer's profile validator. Generated via
scripts/assign_vendor_setting_ids.py (61 instantiated presets). Verified with
scripts/orca_extra_profile_check.py: 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix Flashforge Adventurer A5 profiles so the bundle loads and validates
The new A5 presets were not in canonical form, several filaments resolved
no or the wrong filament_id, and the model and machines pointed at
non-existent or AD5M Pro defaults. Run the standard profile tooling
(normalize, update-index, generate-id), give the branded filaments the ids
of their existing Flashforge products, and repoint the defaults at
A5-compatible filaments and processes. Bump the Flashforge bundle version.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: yw4z <ywsyildiz@gmail.com>
Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
- GMP: name the parameters in the configure probe from
0001-GMP_GCC15.patch. Unnamed parameters are a hard error on GCC 10
and older, so configure failed there.
- TBB: turn off the automatic hwloc search so a system libhwloc-dev is
not picked up.
- scripts/linux.d/debian: run apt update before checking which
webkit2gtk package exists, and prefer webkit2gtk-4.1 since the build
requires it. Add automake, which MPFR's autoreconf needs.
# Description
<!--
> Please provide a summary of the changes made in this PR. Include
details such as:
> * What issue does this PR address or fix?
> * What new features or enhancements does this PR introduce?
> * Are there any breaking changes or dependencies that need to be
considered?
-->
When a PR is merged using the bot with `/bot merge`, it doesn't invoke
`post_merge_profiles.yml` because post_merge_profiles.yml only starts on
a push or manual dispatch.
# Screenshots/Recordings/Graphs
<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->
## Tests
<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->
<!--
> A guide for users on how to download the artifacts from this PR.
-->
[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
Plugin dialog content is injected with SetPage, so on the WebKit backends a
reload (context menu, keyboard shortcut or location.reload()) re-fetches the
SetPage base URL instead of the injected document, and the plugin UI is gone
for good: load_plugin_content() returned early once m_content_loaded was set.
Re-inject the plugin HTML when a main-frame load after the initial swap is
neither that swap nor a page the plugin linked to. m_own_page_load marks the
load our own SetPage caused, and the URL test recognises the reload: the
injected document and the directory a reload re-fetches both report the base
URL, so a load of any other URL is left alone. The test ignores a fragment the
page navigated to, and undoes the escaping the web view applies to what the
resources path holds.
A load reaching the base URL is not enough on its own, because WebKitGTK reports
a navigation that never committed against the document that stayed and then
finishes that document again: a link to a missing file therefore arrives as a
load of the base URL and reads exactly like a reload. So the re-injection also
requires a navigation to the base URL to have committed, which a reload always
does and a failure never does.
A bootstrap page that cannot be loaded is still not recovered from: WebKitGTK
substitutes a stock error page for it, and that load supersedes the swap
whichever way the swap is ordered around it. The file ships, so this is a
broken-install path; nothing here makes it worse than it already was.
No separate MSW path is needed: wxWebViewEdge ignores the SetPage base URL, so
its documents report about:blank and the test never matches there, and WebView2
reloads NavigateToString content from its own history entry anyway.
* Add Ultimaker S5 Profile - WIP
* Add Ultimaker physical printer base
* Ultimaker API WIP for base update.
* Fix undefined reference error.
* Add UMS5 profile, add placeholders for testAuth stuff.
* Fix non-const func definitions, make func names align with style guide.
* Localization stuff? IDK if this does anything or is required.
* Add cover image
* Auth code cleanup, add UI button for auth cred generation, implement various auth checks and tests.
* Fix auth stuff
* Clean up code
* Get upload code sort-of working, fix typo
* Update printer settings and start/end gcodes
* Add makeGriffinCompatible preprocessor script to prevent machine crash, update machine profile.
* Fix buildplate size, fix time missing bug, add S5 buildplate model
* Correct capitalization to UltiMaker
* Fix display bug, fix capitalization bug
* Implement credential generation button and logic
* Fix generate auth creds button, add todos, fix capitalization.
* Actually fix generate auth credentials.
* Fix generate auth creds message.
* Update UM S5 machine limits
* Revert accidental commit.
* Fix postprocessor, clean up code.
* Update presets for multi-extruder printing.
* Add Single Extruder and Fast profiles.
* Code cleanup
* Register and validate the UltiMaker S5 presets
* Show the Generate API Key button only for UltiMaker print hosts
The PR added it to the Physical Printer dialog for every host type, where pressing it runs an ordinary connection test and reports "API Key created". Gate it on the selected host type instead.
* Drop unused lambda captures in the UltiMaker host code
clang promotes -Wunused-lambda-capture to an error under the project's -Werror, so the file failed to build on macOS; the five callbacks do not touch this.
* Fix the Windows build of the UltiMaker print host
---------
Co-authored-by: SoftFever <softfeverever@gmail.com>
The validator, fixture archives and unpacked fixture trees no longer live under <repo>/.test/check_profiles, so every worktree on a machine shares one copy instead of re-downloading. macOS, Linux and Windows each use their own user cache dir, named apart from OrcaSlicer's per-user dirs. The now-unused /.test/ ignore rule is dropped.
# Description
A plate using one filament no longer reserves or draws a prime tower in
the plater just because multiple filament slots are configured. The
shared footprint estimate gated "no tower" on the purge volume being
zero, but on non-Bambu printers with the shipped defaults that volume
comes from the SEMM flush matrix, which reads every configured slot and
stays nonzero even when only one filament is used — so the preview
showed a tower the print could never contain. The estimate now decides
from the filament count alone, with wrapping detection and smooth
timelapse staying the only reasons a single-filament plate keeps a
tower, matching `Print::has_wipe_tower()`. The gate also moved above the
flush-volume scan so the lone-filament path no longer pays for it.
No change to slicing output — toolpath generation already omitted the
tower for a single used filament; this removes the phantom preview,
placement reservation, and validation footprint.
# Screenshots/Recordings/Graphs
Before the fix:
https://github.com/user-attachments/assets/c5b0ea61-127d-408e-bafe-f1f76c58b996
After the fix:
https://github.com/user-attachments/assets/ac6632b3-5d44-4013-aca3-73f6cfd1139c
## Tests
<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->
Added a shipped-defaults single-filament case to
`tests/libslic3r/test_wipe_tower_estimate.cpp`: it estimates a 5.04
mm-deep tower before the fix and zero depth after. `[WipeTowerEstimate]`
and the fff_print `[WipeTower]` suites pass.
<!--
> A guide for users on how to download the artifacts from this PR.
-->
[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)