Commit Graph
304 Commits
Author SHA1 Message Date
Kris Austin 7888452666 build: clear 7 warning categories across 26 sites (#15615)
* 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.
2026-09-10 07:39:14 -03:00
Lam Wei Lun 9e4f8aac80 Merge and fix conflicts 2026-09-10 12:11:20 +08:00
Lam Wei Lun 0927a5d5e7 Merge main 2026-09-09 19:12:23 +08:00
Kris Austin fa3dbfcc6f fix: clear 1 warning - report the real error when a Windows G-code export fails (#15582)
fix: report the real error when a Windows G-code export fails

copy_file built its failure message as "Error: " + errCode. Adding a DWORD
to a string literal is pointer arithmetic, not concatenation, so the pointer
lands errCode bytes into an 8-byte literal and runs past its end for any code
above 7. std::string then calls strlen on it and throws length_error, and the
catch(...) in BackgroundSlicingProcess::finalize_gcode replaces the diagnosis
with "Unknown error occurred during exporting G-code."

Every code a user is likely to hit is past the end: write-protected media is
19, no media 21, a full disk 112, and a destination held open by another
program 32. Codes 1 to 7 stay inside the literal and produce a truncated
message instead. So the "Maybe the SD card is write locked?" text has not
been reachable on Windows since this path was added in #2923.

Now that it is reachable, that guess only fits removable media, so it is
conditional on m_export_path_on_removable_media. The existing string is
untouched and keeps its 23 translations; the fixed-drive case adds one string.
2026-09-09 07:55:19 -03:00
Hanif Koh 2f2a6bc3b5 Share the Estimated First-Layer Outline of the Wipe Tower
The preview brim, the placement margin and the pre-generation validation
warning each decided on their own whether the tower has a Type2 cone
base, reading the wall type and cone angle three different ways. The
preview's read cast the preset's enum to ConfigOptionEnum<T>, which a
preset-shaped config never holds, so the cone base was never previewed.

estimate_wipe_tower_first_layer_outline now answers that question once,
beside the footprint estimate, from the config and the resolved planner;
all three sites take the outline from it. The libslic3r case reads the
outline off a preset-shaped config, where the old cast came back empty.
2026-09-09 15:45:16 +08:00
Hanif Koh 81357695c5 Verify WipeTower Footprint at Point of Generation
The clamps and validation work from estimates. Once the tower is
generated, _make_wipe_tower re-tests the exact first-layer footprint,
brim and cone base included, against the printable area and the
exclusion zone, so an off-plate tower fails with a clear error instead
of exporting unprintable G-code. The rectangle-wall mesh footprint
learns the Type2 cone base so that check and the post-generation
validation see the real outline.

Pre-generation, validation hard-checks the body plus an explicit brim
and warns on the estimated auto brim and cone base with the existing
"may collide" strings, so the user hears about a marginal position on
the first slice rather than only at generation time.

Two fff_print fixtures that print a tower at the default position move
it onto the 200 mm test bed, as the multifilament fixtures already do:
the shipped default y of 220 is off that bed, and the backstop now says
so instead of exporting the tower.
2026-09-09 15:45:16 +08:00
Hanif Koh 2fdc16f9f2 Size a no-purge tower at the planners' idle depth
Smooth timelapse no longer charges a prime volume it does not purge. A
tower printed with no tool change is exactly the idle depth: the
stability minimum for Type2, the wrapping detection depth for Type1.
Charging a full prime_volume on top made the previewed and arranged
tower deeper than the one that is printed.

The Type2 half of "a tool change reserves a tower whatever the purge
volumes resolve to" arrives with the base commit; here it only has to
survive the planner split, since Type1 already reserves per filament.

The wipe tower filament only joins the tool ordering when there is a
tower to join, which is the has_wipe_tower() half of the guard
Print::extruders applies.
2026-09-09 15:45:16 +08:00
Hanif Koh 99627c8e93 Size the Footprint Estimate from the Planners
The shared estimate reserved every tower with one volume-per-purge rule
and the stability floor. Both planners do more: WipeTower (Type1) wipes
each filament's own prime volume in whole lines, one block per
adhesiveness category sized by its worst layer, rams the leaving
filament at every nozzle change, and squares a rib tower from the
planned depth; WipeTower2 (Type2) spaces its lines by
wipe_tower_extra_spacing, not the Type1-only infill gap, and its extra
flow cancels out of the depth. Both extend the ribs rather than the body
below the stability minimum, size every layer including a thinner first
one, and lay the brim in whole loops, WipeTower reporting half a spacing
of line width on top.

All of that now lives in estimate_wipe_tower_footprint, fed the planner
(resolve_wipe_tower_type mirrors Print::wipe_tower_type and the CLI's
Bambu Lab detection) and the filament ids rather than a count. Print
passes its own tool set; the PartPlate adapter derives the plate's ids
from the passed config and treats an explicit count as a floor, so the
CLI's count-only callers size per filament too. The placement clamp also
reserves a Type2 cone's base bulge, which the body box does not cover.

The planner-mirroring helpers sit beside the planners in WipeTower and
WipeTower2 so the two stay in sync; the libslic3r cases pin them to
footprints measured from generated G-code.
2026-09-09 15:45:16 +08:00
Hanif Koh e1efec7d6c Fix review findings in the shared wipe tower estimate
A raft is not a reason to reserve a tower. Print::apply runs
normalize_fdm_2, which clears enable_prime_tower for a plate that purges
one filament unless smooth timelapse or wrapping detection is on, so a
single-filament plate with a raft prints no tower at all and the estimate
was reserving bed area for one. Drop the input; need_wipe_tower is now
exactly the two exceptions normalize_fdm_2 honours, named there so the
next reason added has to be checked against it.

The GUI preview and the validation containment check each re-derived
"is a tower printed here" from the filament count instead of reading the
estimate, so both missed the towers printed with no tool change to purge
for. They now take the answer from the footprint, which is the drift this
shared estimate exists to remove. A tower that is not printed estimates to
zero, so its hull is degenerate and every check on it passes trivially -
the containment check needs no gate of its own.

WipeTowerData::width was written only by the pre-generation estimate and
left at zero for the whole post-generation life of the Print, while its
neighbour depth held the real value. Set it from the generator in both
branches.

The plate's height scan transformed every model part's full mesh per
instance on each scene reload, discarding all but the z extent. The
cached convex hull has the same z extent.

A plate loaded from a sliced .gcode.3mf holds no objects and its filaments
live in slice_filaments_info; the config-taking get_extruders overload
returned an empty list for it, which sized the tower for a placeholder two
filaments. It now answers the way the wx overload does, without reaching
the plater.

Also drop estimate_wipe_tower_size, which has no callers.
2026-09-09 15:45:16 +08:00
Hanif Koh 8df5e5e738 Extract and Unify Wipe Tower Estimation 2026-09-09 15:45:16 +08:00
HanifKoh 8a291f9d56 Confine config import to the preset directory (#15608)
import_presets reduced each zip entry to a basename by stripping only
'/', so on Windows an entry named with '\' separators kept its
directory components and was extracted wherever they pointed. Strip
both separators, and reject any entry whose name still escapes the
extraction folder.

The preset name from the JSON and the bundle id from
bundle_structure.json were joined onto the preset directory unchecked
as well, which let either of them write outside it on every platform.
Both are now validated before anything is written.

The check is the is_path_within_root helper the 3MF importer already
had, moved to Utils so both importers share it. It treats '/' and '\'
as separators on every platform, so a bundle that would escape on one
OS is rejected on all of them.
2026-09-09 15:35:21 +08:00
HanifKohandraistlin7447 4deadc9dce Make Tree-Support Deterministic (#15565)
* Make tree support deterministic without giving up its parallelism

* Break equal-distance ties in the tree support MST by coordinates

* test: cover the determinism this PR fixes

The MST unit tests here cover the tie-break, but the drop_nodes rework
has no test.

Adds two cases to the tree support suite. The thread-scheduling one
slices five configs twice each and compares the support point sequence,
which is what the node ordering moves. The MST tie one pins the branch
diameter and line width that carry Prim's equal-distance ties into the
toolpaths.

slice_with_tree_support takes an optional config list so the second case
can add the tree parameters it needs, and the double-slice comparison is
shared rather than written twice.

Both fail on main without this PR. The first passes from 60d1ceb580, the
second from e148865dd6.

---------

Co-authored-by: raistlin7447 <kris.austin@gmail.com>
2026-09-09 12:33:42 +08:00
Lam Wei Lun a4c399d250 Merge main and resolved conflicts 2026-09-09 11:05:52 +08:00
HanifKoh 58bf267fdd Scale Min Junction Width to Prevent Fuzzy Skin From Failing Slice (#15566)
* Fix fuzzy skin failing the slice: the minimum junction width was unscaled

* Unit Tests For Fuzzy Fix

* Cover ridged multifractal noise in the fuzzy skin width floor test

Its output is not bounded to [-1, 1], so it scales past the configured
thickness and drives the junction width negative. The floor has to hold
for any noise value, not just an in-range one.
2026-09-08 16:57:33 +08:00
Maximilian Ghazanfar bcb4f17d9a fix(cli): resolve inherited presets through vendor manifests (#15438)
* fix(cli): resolve inherited presets through vendor manifests

* fix(cli): resolve typeless inherited presets

Probe the configured preset collections when a preset JSON omits its type. Reject missing, cross-type, and duplicate identities instead of silently selecting a candidate.

* fix(cli): allow missing app config during preset resolution

* fix(cli): tolerate malformed app config during preset resolution
2026-09-08 12:12:55 +08:00
Kris Austin 5779274e5b test: cover support interface generation and tree support (#15575) 2026-09-07 18:02:14 -03:00
SoftFever 4b104bb574 Merge branch 'main' into feature/filament_id 2026-09-07 11:53:50 +08:00
SoftFever 3500a1e588 unify id generation scripts 2026-09-07 10:46:59 +08:00
Rodrigo FaselliandIan Bassi 85dc866425 Spiral Inset infill (spiral-concentric infill) (#15085)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-09-06 11:36:23 -03:00
SoftFever 06e665fca7 Merge branch 'main' into feature/filament_id 2026-09-06 22:34:06 +08:00
SoftFever 4aa0e1d60b Translate filament ids at the printer boundary
Orca content-addresses every system filament, Bambu's included, but a printer,
its AMS and its vendor's cloud know only that vendor's own catalog ids. The
printer agent now translates between the two: outbound MQTT and FTP traffic, the
AMS mapping sent with a print job, and the ids written into a 3mf bound for the
printer all leave in the printer's own ids, while status messages, loaded
projects and SD-card prints arrive in Orca's. An id with no mapping passes
through unchanged, and an agent whose printers already speak Orca's ids
translates nothing at all.

Bambu's map is generated from BambuStudio's own shipped bundle; a missing or
unreadable file leaves every lookup an identity rather than taking the app down.
The profile check validates the map's shape, and profile CI now runs on the paths
that can change it. docs/HLSD/filament_id.md records the places the map
deliberately does not reach.
2026-09-06 20:53:11 +08:00
HanifKoh 1170b048e8 [CLI]: Fix Plate Config Reading and BuildVolume Height Checks (#15479)
* Fix incorrect early exit for CLI mode no-support preventing parameters from being read

* Use PartPlate's m_height to allow CLI to perform proper BuildVolume check

* Add safeguard against extruder_pintable_heights and extruder_areas vector size mismatch

* Preserve printable_height precision in PartPlate/PartPlateList

* Fixed multiple BuildVolume warning issue, and keep check_outside diff minimal
2026-09-04 23:24:59 +08:00
HanifKoh df30e22427 [CLI]: CLI Crash Guards (#15477)
# 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?
-->

Part 1 of 3 of the CLI-mode bug sweep, split out of #15452 per review
feedback there. This PR contains the crash fixes.

## Fixes

- **`--outputdir`/`--datadir` with a missing parent directory aborted**
via unguarded `create_directory`. Directories are now created
recursively, with a graceful early exit and a specific error message if
creation fails.
- **`--slice` + `--export-3mf` segfaulted on a from-scratch slice**:
`ConfigOptionVector::get_at()` on an empty vector is `.front()` of an
empty vector (UB). Guards added for `filament_color`/`filament_id` at
the CLI call site, and inside `DynamicPrintConfig::get_filament_type`
for `filament_type`/`filament_is_support`/`filament_id`. Only *empty*
vectors are treated as missing — the existing clamp-to-front behavior
for merely out-of-range indices is preserved, so GUI callers are
unaffected.
- **OOB heap write from stale `filament_self_index` on
`--load-filaments`** (fixes #14181): a 3MF carrying more
`filament_self_index` entries than loaded filaments wrote past the end
of `old_variant_counts`. The guard validates both bounds — entries `>
filament_count` *and* non-positive entries (`< 1`), since a single `0`
in an otherwise-valid array indexes `old_variant_counts[-1]`.
- **Wrong printable-area check** for non-rectangular beds: use the
printable area's bounding box instead of a naive vertex calculation
(fixes #15363).
- **`nozzle_height` and `align_center` were not read into the arrange
config** in CLI mode.

# 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.
-->
- Repro'd each crash on CLI before the fix; all resolved after.
- `tests/libslic3r` suite passes; full binary builds clean on Linux.
- Added `get_filament_type` unit tests 

<!--
> 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)
2026-09-04 15:46:03 +08:00
Lam Wei Lun c6ab725584 Fixes issue with mixed filament being loaded into a real slot 2026-09-04 14:41:20 +08:00
Lam Wei Lun bbb4681b32 Merge branch 'main' into publish_3mf 2026-09-04 12:24:57 +08:00
HanifKoh 57ce18d70d [CLI]: CLI Argument Parsing Fixes (#15478)
* Reject invalid CLI argument values instead of silently accepting them

* Add read_cli accept/reject tests

* Update Option Type for LogFile argument

* Add read_cli vector option tests

* Accept common bool spellings on the CLI, cover --logfile in tests

* Add unit tests for truthy bool parsing
2026-09-04 11:31:42 +08:00
TheLegendTubaGuyandRodrigo Faselli 7acea3ed09 Honor symbolic default bed types for new printers (#15273)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-09-03 19:42:31 -03:00
SoftFever df101ead91 fix more issues 2026-09-04 00:29:52 +08:00
SoftFever 7c9b38ba04 remove retired_filament_ids.json 2026-09-03 21:03:42 +08:00
Lam Wei Lun 8c7160079e Revert clang-format changes then reapplied chagnes for Plater/PresetBundle. Fixed extruder masking incorrectness. Fix warning notifications stacking 2026-09-03 13:17:13 +08:00
SoftFever 7a0ca15df8 Merge branch 'main' into feature/filament_id 2026-09-02 15:34:20 +08:00
Lam Wei Lun f1719b5580 Fixes mixed filament growth bug. Fixes unit test 2026-09-02 14:29:15 +08:00
Lam Wei Lun f5984e7523 Merge main 2026-09-02 11:43:04 +08:00
CliffordandClaude Opus 5 b6ef6cf1be fix: out-of-bounds write migrating per-variant values when switching printers (#15456)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 19:29:11 -03:00
Kiss Lorand e8115658e0 Fix overhang fan control when overhang slowdown is enabled (#15158) 2026-09-01 18:07:02 -03:00
SoftFever e8b2a9fca0 Merge branch 'main' into feature/filament_id 2026-08-31 22:11:38 +08:00
Lam Wei Lun 6fef33cdb3 Merge main 2026-08-31 18:01:31 +08:00
SoftFever 5add7a5062 Show Orca Filament Library filaments in AMS and calibration dialogs
These dialogs treated a filament with no compatible_printers as compatible with
nothing, while the rest of the app treats it as compatible with everything, so
the entire Orca Filament Library was missing from the AMS material and
calibration filament lists. They now resolve compatibility the same way the
plater does, and a vendor profile still supersedes the library generic of the
same name.
2026-08-31 16:25:59 +08:00
Ian Chua 27e99ca713 feat: initial plugin auditing workflow (#14989)
# Description

This is an initial draft of the plugin audit workflow.

It focuses on the user experience and developer-facing permission
workflow. It does not yet include the complete implementation of every
operation that should be audited, such as the full filesystem,
networking, and process-spawning event coverage.

## User workflow

When a plugin is loaded:
1. The plugin’s register_capabilities() function is executed.
2. The plugin declares the permissions it requires.
3. OrcaSlicer displays a permission dialog listing the requested
resources.
4. If the user grants access:
  - The permission is persisted in the plugin’s .install_state.json.
  - Capability registration continues.
  - The plugin is materialized and loaded.
5. If the user denies access:
    - Plugin loading fails before capabilities are materialized.
    - on_load() is not called.
- The plugin’s install state is marked with "enabled": false to prevent
repeated automatic load attempts.

At runtime, if a plugin accesses a resource that was not approved during
loading, the audit hook displays another permission dialog. For
filesystem requests, the dialog identifies the requested filepath.
  - Granting access persists the permission and allows the operation.
  - Denying access raises a Python PermissionError.
- The error propagates to the host, which records the failure and
unloads the plugin.

Host-side traceback logging is performed outside the plugin audit
context so that logging does not generate additional permission dialogs.

## Developer-facing API

Plugins can declare filesystem read permissions through the new API:
```python

import orca
AUDIT_PATH = __file__


@orca.plugin
class ExamplePackage(orca.base):
   def register_capabilities(self):
        orca.request_permissions(
            fs_read=[AUDIT_PATH],
        )
        orca.register_capability(ExampleCapability)
```
orca.request_permissions() must be called from register_capabilities()
while the plugin is being loaded.

Currently supported permission:
orca.request_permissions(fs_read=[...])

The paths should be explicit filesystem paths that the plugin intends to
read. The host deduplicates repeated paths, presents the request after
registration completes, and persists granted paths in the plugin
install-state sidecar. This API is still experimental, and is by no
means the final implementation.

Support for additional permission categories, including filesystem write
access, networking, and process spawning, is reserved for subsequent
work.

# Screenshots/Recordings/Graphs

<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->

<img width="869" height="799" alt="image"
src="https://github.com/user-attachments/assets/8a5903cc-0cbb-45a8-b88a-706d6cba790f"
/>


## 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)
2026-08-31 14:29:36 +08:00
Lam Wei Lun fff0efdb27 Fixes filament import bug 2026-08-31 13:57:21 +08:00
Lam Wei Lun 6ffb20a7f5 Update translations. Change import filament message to warning instead. Change messages to be simpler 2026-08-31 12:08:08 +08:00
Lam Wei Lun 06517e623f Fixes issue where user imports a 3MF file where filament slots exceeds the maximum number of slots that user has on its printer 2026-08-31 10:46:23 +08:00
SoftFever ea0242feda Merge branch 'main' into feature/filament_id 2026-08-30 20:54:33 +08:00
SoftFever dfb102f68d Merge branch 'main' into dev/ffmpeg-player 2026-08-29 22:44:08 +08:00
Lam Wei Lun a62db72e02 Publish 3MF: import-side hardening and test coverage
Validate mixed-filament definitions during the published material pass: definitions whose components reference slots that do not exist or hold other mixed filaments, or that carry fewer than two components, are reported through the shared skipped_keys channel instead of shipping a mix the GUI integrity check would only flag later.

Fix the slot-limit exhaustion report being silently dropped: it wrote to published_config->skipped_keys, which the pass's final move-assignment from the local vector clobbers. All rejections now go through the local.

Remove the unreachable persist branch from add_detached_preset: no caller passes save_to_project=false, so the parameter is gone and the copy is always project-embedded.

Tests: cover the exhaustion path, the new definition validation, the identity-tier matching matrix (including substitute reporting), the structural-key denylist, whole-vector size-mismatch skips, relocation payload degradation, the "(Published 2)" uniquify chain, mixed blend colours staying out of shared preset configs, and duplicate-slot last-wins. Also fix the legacy-3mf scenario passing vacuously behind an if-guarded assertion. All existing published/3mf tests pass unchanged.
2026-08-28 15:24:03 +08:00
Lam Wei Lun 25b008ba3e Merge main 2026-08-28 10:38:36 +08:00
Lam Wei Lun 28b325805b Fixed issues with remapping mixed filaments when importing published 3MF 2026-08-28 10:37:54 +08:00
Kris Austin 6d1584844e fix: STEP part names with accented characters import as numbers (clears 6 warnings) (#15406) 2026-08-27 19:06:06 -03:00
Ian Chua f9c415fc41 Merge branch 'main' into feat/plugin-auditing 2026-08-27 14:52:20 +08:00
Lam Wei Lun 20e5a7e042 Merge main 2026-08-27 14:11:41 +08:00