# Description
Follow-up to #15950, where a `filename_format` using
`initial_no_support_extruder` shipped broken because the profile
validator's slice sweep never expands `filename_format`. The sweep now
expands every custom G-code and `filename_format` text shipped in any
system profile. Each printer's slice also fires the pause, template
custom G-code and clumping-detection hooks and names the output file,
and the first printer shipping a `printing_by_object_gcode` also slices
by object. Beyond each printer's default process and filament, every
compatible system process and filament carrying a template text no
earlier slice has expanded is sliced once, which takes the sweep from
1,110 to 1,248 slices (about 49 s locally, up from 43 s). While the
sweep runs, the placeholder parser also resolves variable names inside
`{if}` branches a slice does not take, so one expansion checks every
branch.
The stricter sweep found two profile bugs, fixed here: the Anycubic
Kobra X filament change G-code carried an unreachable block reading
variables only Anycubic's own slicer defines, and the Wanhao France D12
template custom G-code had an unterminated `{if}`, so adding a template
custom G-code on those printers failed the slice. It also fixes a parser
bug where a declaration such as `{local a = layer_height + 1}` failed to
parse inside a branch that is not taken.
No change to slicing output for templates that already worked: the
untaken-branch check is enabled only by the validator's slice mode, and
the parser fix only lets previously rejected templates parse.
# Screenshots/Recordings/Graphs
<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->
## Tests
New placeholder-parser cases cover the parse fix and the untaken-branch
check: off by default it changes nothing; on, it rejects undefined names
in branches not taken, accepts names declared there, and leaves boolean
expressions (compatibility conditions) alone. The full sweep passes on
all system profiles, and planting an undefined variable in an untaken
branch of a printer's start G-code, of a non-default filament's start
G-code or of a non-default process's `filename_format`, or reverting
#15950, each fails it and names the preset. `scripts/check_profile.sh`,
`libslic3r_tests` and `fff_print_tests` 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)
The 3MF importers read XML entries into a single expat buffer whose size is
an int, while the archive extraction used the entry's 64-bit declared size.
The two could disagree for entries declaring more than INT_MAX bytes.
Reject such entries before allocating, and use one size for the buffer, the
extraction and the parse. This applies to the BBS importer, the PrusaSlicer
importer and the PrusaSlicer fingerprint probe. The load now fails with an
error instead.
* Reject 3MF Plate IDs Below 1 Instead of Indexing Before the Plate List
The plate importer copied each plater_id from model_settings.config into the
1-based plate list after checking only the upper bound, so plater_id="0"
wrote to plate_data_list[-1] and crashed on load. Both copy sites now reject
ids below 1 with the same "invalid plate index" error already used for ids
past the end.
* Drop Malformed 3MF Paint Data Instead of Reading Past the Bitstream
Painted facets are decoded from a bitstream a nibble at a time with no bound
check, so a truncated or corrupt paint string in a 3MF (for example split
codes with no children behind them) read past the end and crashed on load and
slice. A one- or two-side split naming side 3 also indexed past the triangle's
vertices.
Every nibble read now goes through a bounds-checked reader. Loading validates
each triangle's tree and drops a malformed one with a warning, so the stored
data, used extruder states and later decoding all agree. deserialize() also
unwinds and clears any triangle whose tree is incomplete or malformed, and
has_facets() stops at a truncated triangle. Valid streams decode unchanged.
* Sanitize Server-Supplied Download File Names
The URL downloader used the file name from the Content-Disposition header
as given, without the cleaning and unused-name search applied to the
URL-derived name.
Reduce the header name to a sanitized base name with the new
sanitize_file_basename helper, which splits on both path separators and
rejects names made only of dots and spaces. Run the result through the
same unused-name search as the URL-derived name, now shared in
find_unused_filename, and fall back to the URL-derived name when nothing
usable remains.
* Sanitize Download Names Before Choosing an Unused One
The unused-name search probed the name as given and sanitized the
result afterwards, so a name whose special characters are replaced
could be mapped onto a file that already exists.
Move the search into libslic3r as find_unused_filename, sanitize first
and probe the name that is actually written. The download marker path
is shared through download_marker_path. Restore the last tried name in
the error reported when no free name is found, and cover the search
with unit tests.
* Keep Downloads on an Unused Name Until They Complete
When the server supplied the name, the download marker stayed under the
URL-derived name, so the adopted name was not reserved against other
downloads. The final rename also replaced any file that took the name
while the download ran.
Move the marker to the adopted name before any data is written, and
check the name again right before the final rename, picking the next
free name if it is taken by then.
* Sanitize the File Name of Model Import Links
The model import took the file name from the link as given and only
avoided an existing file with a substring match on the folder listing.
Reduce the name to a sanitized base name, falling back to untitled.3mf,
choose the name with the shared unused-name search, and check it again
before the final rename.
* Handle Filesystem Errors When Finishing a Model Import Download
Choosing the final name and moving the downloaded project into place
could throw from inside the download callback. Any such error now removes
the temporary file and reports the existing import failure message.
* Non-crossing infill optimization
* test triangles
* test grid
* cleaning
* Align and clip rectilinear infill paths
Generate infill coverage in the pattern's local frame, rotate triangular patterns by layer, and clip centerlines to the surface vicinity. Start closed outlines outside the surface so clipping splits them cleanly.
* Update test_fill.cpp
* Update multiline-infill.md
---------
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
# Description
Extruder variants (Standard, High Flow, extra high flow) now work on any
printer. Any vendor profile can declare them, and a multi-variant
filament picks up the right variant on every printer. In the sidebar,
users can switch the printer variant and set the nozzle volume type of
each extruder on multi-extruder printers. This also fixes a later
filament printing at the first filament's temperature on a P1S or X1C
with a High Flow nozzle. The profile checks now reject variant arrays of
the wrong size and outdated variant strings. Every shipped vendor
profile passes them, and the orca-profiles skill documents the rules.
Slicing output changes only where the wrong variant was used before.
# Screenshots/Recordings/Graphs
<img width="393" height="218" alt="Screenshot 2026-09-28 at 11 28 07 PM"
src="https://github.com/user-attachments/assets/8bee4b0e-c38c-4039-8c11-096ace6fbad0"
/>
<img width="448" height="267" alt="Screenshot 2026-09-28 at 11 28 37 PM"
src="https://github.com/user-attachments/assets/e767cd97-a5d0-4728-b010-c8ea2bc94ca7"
/>
<img width="746" height="603" alt="Screenshot 2026-09-28 at 11 28 54 PM"
src="https://github.com/user-attachments/assets/23c8af3b-c679-46e5-9fd0-2e43df0449b3"
/>
https://github.com/user-attachments/assets/10d75d72-86a3-42e8-8a95-b1627bd58e91
## 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)
* Add missing TopTools includes to GeometryEngine.cpp
* Add missing TDF_LabelSequence include in STEP.cpp
---------
Co-authored-by: yw4z <ywsyildiz@gmail.com>
The segments come in print order, bottom layer first, which seen from above is back to
front: every hidden fragment is shaded before the one that covers it, and on an integrated
GPU that overdraw is most of the frame. Drawing the instances last to first whenever the
camera looks down lets the depth test reject the hidden fragments instead. Side views and
views from below keep the print order, and the shadow-caster pass is unchanged.
Synchronize the plater filament controls after preset loading, even when the internal filament list already matches the nozzle count.
Co-authored-by: Codex <codex@openai.com>
Fix size_t/%d mismatch in MsgDialog button keys
`m_buttons.size()` is a `size_t`, which does not match the `%d` conversion in
printf-style variadics. Build the key with `std::to_string` instead; exact
for any size_t, no behavior change for realistic counts.
Co-authored-by: yw4z <ywsyildiz@gmail.com>
Guard the smooth-normals preference read when CLI thumbnail generation initializes geometry without a wx application. Use the existing flat-normal path in that case and preserve GUI preferences.
Use DPI-aware 20 DIP vertical scrolling for general-purpose GUI
scroll areas.
Keep list-based views aligned to their item height so one wheel increment follows the visible row rhythm.
This makes Preferences and other dialogs scroll consistently across
Windows DPI settings.
get_dpi_for_window's pre-8.1 fallback and get_font_list_by_enumeration
both called GetDC without a matching ReleaseDC, leaking a GDI handle
each call. get_dpi_for_window runs on every mouse-move over the 3D
viewport, so the leak exhausts the per-process GDI handle limit and
hangs the app within minutes on Windows 7/8.
Co-authored-by: Fernando Marino <f.marino@rheagroup.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
# Description
This brings back the Bambu Lab profile sync with BambuStudio, reverted
from main, along with its bed-model offset fix. The synced printers and
filaments share their start and end G-code and dual-nozzle settings
through template files that Orca did not read, so those printers had no
machine G-code. Orca now loads these templates the same way BambuStudio
does, so every synced preset comes in complete. `profile_include_dump`,
a new developer tool, compares the result with BambuStudio's.
Other vendors' profiles are unaffected. Bambu Lab profiles move to
version 02.08.00.10, so installs that took the earlier sync update too.
<!--
> 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?
-->
# Screenshots/Recordings/Graphs
<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->
## Tests
Unit tests cover how template settings combine with inherited and preset
settings, loaded from JSON and from the preset cache. The profile
validator passes on every shipped vendor, and every Bambu Lab preset
gets the same template values in Orca as in BambuStudio.
<!--
> 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)
A scarf joint split the loop at exactly the scarf length, so the remainder
of the segment the split landed in became the first flat segment, often a
fraction of a millimetre. The seam insertion also leaves segments of a few
micrometres at both ends of the loop, which a scarf extrudes through where a
plain loop would start or stop. With junction deviation the planner treats
such short moves as tight corners, limited by the Z axis acceleration at the
end of the ramp, and slows to a third of the wall speed or nearly halts at
the seam.
Extend the ramp to the next vertex when the remainder would be shorter than
half a scarf step, capped at a millimetre, beyond which planners treat a move
as ordinary; the scarf only grows, never shrinks. Drop the vertex next to the
seam point at either end when that segment is shorter than an eighth of a
common line width, so the loop still starts and ends at the seam; a trimmed
path loses its arc fitting and prints as line segments. Clamp the scarf
length to the trimmed loop so a scarf covering a whole loop still ends at
full flow. The descending pass reuses the same path, so both wedges stay
consistent, and a flat part that would collapse to a single point is dropped.
The global arrange branch, taken by --arrange with all plates selected, only
reserved the prime tower when filament ids had been given on the command
line for STL input. A project carries its filament use per plate and its own
tower positions, but that set was empty for it, so the tower was never an
obstacle: the arranged pile was centred over it and the slice then failed on
a G-code path conflict.
When no filament ids were given, count the filaments each plate uses and
reserve a tower on every plate that needs one, keeping the project's tower
position instead of resetting it to the default. Only a tower the slicer will
print is reserved: the prime tower must be enabled, and a by-object print
gets none unless a smooth timelapse needs it, as the per-plate arrange
decides. Overflow beds are sized for the busiest plate. The STL route is
unchanged.