A build without SLIC3R_PCH had never been tried on macOS. Three files
used what pchheader.hpp happened to include: LocalesUtils.cpp needs
<sstream> and <iomanip>, and the two dialogs need <wx/tooltip.h>. The
GTK port's headers and libstdc++ pull these in transitively, the Cocoa
port's headers and libc++ do not.
Tiles previously rendered a colored monogram (title/source initials plus an ordinal) with a per-id hue. Show the matching native SVG icon instead:
- AppAction/NativeCommand gain an `icon` field; commands get a curated key->icon table and settings inherit their group header's icon.
- Notebook tracks each page's resource icon name and reports it in tab_options(), so the tab picker can show it too.
- Searcher records the group icon so settings keep it through search.
- Web tile rendering swaps monogramFor/hue for an <img>; drop the now-unused hue/text CSS vars. Add a test asserting every non-empty icon resolves to a shipped SVG.
# Description
Each plate keeps a registry of the instances it holds
(`PartPlate::obj_to_instance_set`). The plate's filament list
(`get_extruders`), its wipe tower preview and position clamp, the object
list grouping and the saved project's per-plate instance list all read
it. Two paths left it stale:
* `Plater::increase_instances` (the `+` key / toolbar) adds the copy to
the model but never registers it with any plate.
* `GLCanvas3D::do_move` (drag release and arrow keys) ended with
`notify_instance_update(-1, 0)`, so only instance 0 of each selected
object was re-registered. Rotate, scale and mirror already notify every
instance.
So a copy created with `+` and dragged onto another plate stayed unknown
to that plate: the project saved afterwards listed it on no plate, and a
multi-filament copy moved onto a single-filament plate drew no wipe
tower there and never got its tower position clamped. The Print side
selects instances by geometry, so the plate still sliced, which is why
this went unnoticed.
This PR
* registers new copies with their plate at creation;
* has `do_move` notify exactly the instances it moved (every instance of
the object when a part was moved in Volume mode), rather than instance 0
or all instances - notifying an instance that stayed put invalidates its
plate's slice result, so `(-1, -1)` as used by rotate would have
un-sliced every plate holding a sibling copy;
* drops the registry entry again when `decrease_instances` removes a
copy.
A second commit finishes the switch #15532 started with
`contain_any_instance_totally()`: `get_extruders_without_support()`,
`check_single_extruder_mixed_filament_risk()` and
`check_compatible_of_nozzle_and_filament()` still tested instance 0
only, so an object whose copy - not its original - sits on the plate was
skipped by all three.
No new options, no format change. The `is_new` flag is deliberately not
passed for the copies: a copy landing on a spiral-vase plate gets the
same "apply spiral mode settings?" prompt a dragged instance gets,
instead of a silent rewrite of the object's settings.
# Screenshots/Recordings/Graphs
Before:
<img width="1920" height="1080" alt="05-moved"
src="https://github.com/user-attachments/assets/3cf9f5a9-1a4e-41e8-8c57-578f849d8c29"
/>
After:
<img width="1920" height="1080" alt="05-moved"
src="https://github.com/user-attachments/assets/1b801a7e-b7cd-4ffb-bd1d-b701f90dade6"
/>
## Tests
Re-run after the rebase, both binaries driven through the same headless
harness (Xvfb 1920x1080, llvmpipe) on the same fixture: `cubeA`
(filament 1) alone on plate 1, `cubeB` (a two-part object, filaments 2
and 1) alone on plate 2, so plate 1 shows no wipe tower at load. Select
the plate-2 object, press `+`, walk the copy onto plate 1 with 36 x Left
(10 mm per press, one `do_move` each), save, slice plate 1.
Before is main `8af92214d0` - i.e. with #15532's
`contain_any_instance_totally()` already in place, so the only
difference is this PR.
* **Before:** the saved `model_settings.config` lists plate 1 with
`cubeA` only and plate 2 with `cubeB` instance 0. The copy (instance 1)
is listed **on no plate at all**, and plate 1 draws no wipe tower even
though a two-filament object is sitting on it.
* **After:** plate 1 lists `cubeA` **and** `cubeB` instance 1; plate 2
still lists instance 0. The plate-1 tower preview appears, and slicing
plate 1 succeeds with the tower actually generated - the filament panel
reports 1.10 m / 0.48 m in its Tower column over 51 filament changes,
and the G-code carries `EXCLUDE_OBJECT_END NAME=cubeB.stl_id_1_copy_0`.
Same camera and fixture on both runs, so the screenshots above are
directly comparable.
# 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?
-->
#15416 introduced a bug that caused system profiles to be copied over to
the system folder in the roaming folder on every startup.
# 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)
* Fix internal bridges over Hilbert Curve/Octagram Spiral sparse infill
For patterns with curved/turning anchor lines (Hilbert Curve, Octagram
Spiral), the bridge_over_infill algorithm produced incorrect results:
1. determine_bridging_angle: sampling curved anchor orientations
produced noise across all turning directions (0/90/180/270°)
instead of a single dominant one, yielding unstable bridge angles
with 180° spread. Fix: use the configured infill_direction + 90°
directly, bypassing the noisy sampling. The old blind +0.25*PI
(Hilbert) and +1/16*PI (Octagram) offsets are removed.
2. construct_anchored_polygon: curved Hilbert/Octagram anchors
intersected each vertical scan line many times at wildly different
Y positions, producing chaotic polygon sections — holes in random
places, bridges over air, rotated bridges. Fix: replace the curved
infill polylines with synthetic straight lines parallel to
infill_direction, spaced at the real infill line spacing
(flow_spacing / density). Lines are centered on the limiting_area
bbox center so that after rotation they span the full bridged_area.
Anchors are left at full bbox length (not clipped) to guarantee
every scan line finds an anchor.
Rectilinear and other straight-line patterns are unaffected.
Known limitation: some bridge edges may still terminate over air in
edge cases where the nearest synthetic anchor line is more than one
infill spacing away from the bridge boundary. This will be addressed
in a follow-up.
* fix: anchor internal bridges to actual sparse infill
Preserve real anchors across regions and align plane-path anchor origins with printed infill. Respect lower-layer rotation templates and model alignment, and sample curved bridge boundaries more finely.
Add regression coverage for anchor alignment, bridge angles and region isolation, with Orca comments explaining the geometry constraints. Verified 175 FFF tests before the comment-only follow-up; preserve CRLF in modified files.
* Fix internal bridge support contacts and separated infill origins
Restore anchor contact after bridge smoothing and share per-body pattern origins between anchors and printed infill. Recompute origins when preparation settings change.
Cover multiline counts 1, 2 and 3 and add regressions for printed bridge support, separated infill alignment and reslicing.
* Add explicit standard headers to PrintObject tests
* test: cover surface centering when infill settings change
Verify top and bottom Archimedean Chords and Octagram Spiral paths after switching centering modes or toggling separated infills. Compare reslicing against fresh slicing and document dependent infill invalidation.
* test: preserve directional surface infill when settings change
* perf: index layer islands for connected-body detection
* test: use public print pipeline for body centering checks
* build: clear 2 warnings - cast the NSTextField the class check already proved
mainframe_text_field is NSTextField* and was assigned a bare NSView*, which
Clang reports as -Wincompatible-pointer-types. Both assignments sit inside
if ([viewObject class] == [NSTextField self]), so the runtime type is already
guaranteed, and the line above the second one casts the same variable the same
way to call setTextColor. macOS only, since nothing else compiles this file.
* build: clear 6 warning categories from the clang-cl inventory
-Wmissing-braces (9). Aggregates whose first member is itself an aggregate.
GUID's fourth member is BYTE[8], so the trailing eight bytes take their own
braces. The others were reaching for zero-initialization with {0} and say {}
now. bbs_3mf's backup Task ends in an anonymous union, which needs braces of
its own; those braces initialize the union's first member rather than the one
named at the call site, so the RemoveBackup site says so in a comment.
-Wmacro-redefined (11). SendMultiMachinePage.hpp defines five names that
Preferences.hpp, PresetBundleDialog.hpp, ExportPresetBundleDialog.hpp and
TroubleshootDialog.hpp also define with different values, so the value in
force depended on include order. All nine of this file's DESIGN_ macros take
the SEND_ prefix it already uses for its own macros, values unchanged, so a
DESIGN_ name added elsewhere later cannot collide with it again. They read as
one page-local palette, a 900 to 400 gray ramp plus sizes, so the four with
no current readers stay: dropping them would leave gaps in a named scale. test_marchingsquares.cpp defines NOMINMAX,
which libslic3r already passes as a PUBLIC compile definition, so it takes
the #ifndef guard the other suites use.
-Wbraced-scalar-init (3). Two PushStyleVar calls resolve to the float
overload, so the braces were initializing a scalar. ConfigOptionFloatsNullable
already takes an initializer_list, so the inner braces did the same thing.
-Wmicrosoft-goto (2). Both gotos in copy_file_gui jump forward over the
initialization of size, dwRead and dwWrite, which only MSVC accepts. Those
declarations move up to join the others at the top of the function.
-Wunused-private-field (3). Every use of ColourPicker's m_clrData and
m_picker_widget is behind !defined(__linux__), so on Linux they are written
and never read; the members now carry the same guard. ParamsPanel's
m_size_move is read nowhere. Tab has its own, which is the one Tab.cpp uses.
-Wnonportable-include-path (2). BaseException.h asked for "stackwalker.h"
and the file on disk is StackWalker.h.
# 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?
-->
Addition to #14217 to support OTA updates when the zip content is an OPC
file.
# 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)
# Description
This PR introduces a publish workflow for sharing selected slicer
settings in .3mf projects without exposing or overriding the recipient's
complete printer, filament, or process profiles. A published file
specifies "requirements" for a model — printer, process, and per-slot
filament requirements — while importing it preserves the rest of the
recipient's workflow.
Publish dialog (File → Publish, Ctrl+Shift+E)
- Tabbed dialog (Printer / Filament / Process) with search, Select All /
Select Visible, and DPI rescaling.
- Per-material pages expose three kinds of content: individually
selected filament keys, a Full Publish toggle that embeds the slot's
entire filament preset, and required type and color rows for the slot.
- Publishing is allowed with no settings selected (the file then carries
only identity/requirement data).
- Reuses configuration value formatting extracted into a shared
ConfigValueFormatter.
Export
- Published 3MFs carry published, published_keys, and
published_material_keys metadata.
- A minimal export mode serializes only the selected values, material
identity, and plate geometry, omits embedded preset files, and masks
full-publish vector options to the author's slot so unrelated slot data
never leaks into the file.
Loading
- Only author-selected settings are applied; the recipient's presets are
otherwise preserved and structural/non-publishable keys are protected
(skipped keys are reported).
- Material settings match by filament ID, type, vendor, and slot.
Per-slot type requirements keep a matching receiver material, replace a
mismatched slot with the first same-type library filament (with a
notification), and fall back to a temporary embedded preset or skipped
keys when no match exists. Required colors are applied regardless of the
type match.
- A published 3MF loads as a new project: its path is not adopted as the
project filename (Save prompts instead of overwriting the shared file),
the title reverts to "Untitled", and the published metadata is stripped
so a later save produces a normal 3MF.
- Customized-preset and modified-G-code warnings are suppressed, since
the author's presets and G-code are not applied.
- Previously published 3MF files continue to load through the existing
matching path.
# Screenshots/Recordings/Graphs
<img width="1405" height="734" alt="publish_dialog"
src="https://github.com/user-attachments/assets/96b833c1-2b86-4c09-92b4-a4471a567e62"
/>
[publish_dialog_settings.webm](https://github.com/user-attachments/assets/acf22dd9-ae9b-4a58-b77d-8c2d9ffbc7a5)
## Tests
Added tests covering:
- Coverage for export slot masking, metadata round-trip,
type-match/replace/fallback semantics, slot growth, and skipped-key
reporting.
get_extruders() and estimate_wipe_tower_size() already ask whether any
instance of an object sits on the plate; the support-less extruder scan, the
mixed-filament risk check and the nozzle/filament compatibility check still
tested instance 0 only, so an object whose copy - not its original - was
placed on the plate was skipped by all three.
An instance added with "+" was never registered with the plate it landed on,
and moving an instance only re-registered instance 0 of its object, so a copy
dragged onto another plate stayed unknown to that plate's registry. The
plate's filament list, its wipe tower preview and the position clamp all read
that registry, so a multi-filament copy moved onto a single-filament plate
drew no tower there and its tower position was never clamped.
Register new copies at creation, notify exactly the instances a move changed
(every instance of the object when one of its parts moved), and drop the
registry entry when a copy is removed again.
Added shortcut (Ctrl/Cmd+B) to pin/unpin actions.
Clear unresolved pinned actions when switching between modes.
Fixed scroll-back issue when scrolling to pin action