Commit Graph
684 Commits
Author SHA1 Message Date
Joseph Robertson 64cff12b9d Merge branch 'main' into belt-printer 2026-10-08 16:15:51 -05:00
Kris Austin 8790b07773 fix: missing chamfers on STEP import since the OCCT 8.0.1 update (#16290) 2026-10-08 18:10:37 -03:00
Rodrigo Faselli ee2c40ea85 Fix Mesh Boolean negative (cut) text object (#16275)
* Fix Mesh Boolean negative (cut) text object

* Update test_meshboolean.cpp

* missing headers

* Update test_meshboolean.cpp

* Refactor mcut difference test for source splits

* Apply suggestion from @raistlin7447
2026-10-08 16:00:28 -03:00
harrierpigeonandClaude Opus 5.5 c59eb1bcf9 Belt brim: cut the leading-edge brim at the first layer on the belt
The leading-edge-only brim is the outer brim cut down to the part's first
contact with the belt.  The cut was taken at the first layer with
geometry, but with an overhang on the leading side that layer is the
overhang's tip, which is sliced before the part reaches the belt and
does not touch it.  The cut then lay ahead of the part: a 30 mm fin
left a sliver of brim well ahead of a 20 mm cube, and a 40 mm fin, or a
leading brim length of 0, left none at all.

The footprint loop already finds the layers that touch the belt (their
contact band is not empty); record the first of them and cut there.

The new test slices a cube with and without a 30 or 40 mm fin over its
leading end and checks that the leading-edge brim is the same.  It fails
without the fix.

Reported by raistlin7447 in the review of #14394.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:40:52 -05:00
SoftFever 6edc858f8b Merge branch 'main' into belt-printer 2026-10-09 00:55:12 +08:00
Ian Chua 67a16dabca fix: prompt for permission when plugin tries to create a thread (#16248)
* fix: prompt for permission when plugin tries to create a thread

* fix: request permission on main thread
2026-10-08 23:49:33 +08:00
SoftFever 5072f6b614 Merge branch 'main' into belt-printer 2026-10-08 23:03:56 +08:00
Ian Bassi 59fc97fb28 Extend Separated Infills (#16274) 2026-10-08 09:43:46 -03:00
SoftFeverandxxxsam ee26e94170 Fix H2D prints rejected for a missing Filament Track Switch
Fixes #15927

Co-authored-by: xxxsam <31843242+xxxsam92123@users.noreply.github.com>
2026-10-08 17:49:04 +08:00
HanifKoh 30902561c0 Stop Exporting Names Through Usings in the Remaining Headers (#16250)
The last headers with a using or namespace alias at namespace scope:

- TCPConsole.hpp imported boost::asio::ip::tcp into Slic3r::Utils for
  two member declarations. The alias is now a private member of the
  class.
- WebSocketClient.hpp declared four namespace aliases and a tcp alias
  at global scope, each used only by the header. The names are spelled
  out.
- Repair.hpp aliased CGAL::Polygon_mesh_processing as PMP in
  Slic3r::tex2color. The three functions that use it declare the alias
  themselves.
- PreciseSeam.hpp, Thumbnails.hpp and MarchingSquares.hpp used a
  using-declaration or directive for one or two spots each; those spots
  are qualified. Thumbnails.hpp's "PNG"sv default argument becomes
  "PNG", which converts to the std::string_view parameter the same way.
- tests/sla_print/sla_test_utils.hpp had "using namespace Slic3r;" and
  tests/filament_group/fg_test_serialization.hpp "using json =
  nlohmann::json;" at global scope. The headers qualify their own names;
  the two SLA test sources get the directive themselves.

Also removed: twelve type aliases in headers that nothing references
(ConflictObjName, CircleSqf, CircleSqd, TRawBuffer, DistanceFunction,
SamePair, ExtruderNozzleInfos, Vec2dEvent, Vec2dsEvent, Vec3dEvent,
t_option, t_optgroups, Plater::fs_path) and a duplicate
fn_ft_job_msg_destroy alias in FileTransferUtils.hpp.
2026-10-08 13:59:12 +08:00
HanifKoh 6cd5feed79 Remove Duplicate Includes and the Dead GCodeSender Sources (#16249)
46 files include the same header twice at file scope, outside any #if,
66 times in all:
Model.cpp included Model.hpp twice, Utils.hpp <algorithm> and
<string_view> twice, seven GUI headers <wx/dataview.h> and
<wx/artprov.h> twice. The second include of each is removed.

GCodeSender.cpp and GCodeSender.hpp have been commented out of
libslic3r/CMakeLists.txt since 2022 and their only two includes are
commented out as well. Both files go, with the commented lines, and
the CMake entry for SLA/SupportTreeIGL.cpp, a file that no longer
exists.
2026-10-08 13:51:50 +08:00
HanifKoh 09530ef7c4 Size a Project's Mixed-Colour Metadata to the Filaments in the CLI (#16247)
The mixed-colour metadata options are parallel per-slot arrays in the project
config. A project saved before they were sized per slot stores a single value
for the gradient ones, and one saved before they existed stores none. The GUI
sizes all seven to the filament count when it opens a project; the CLI kept
the stored arrays and exported one-element defaults for absent ones, so a
project it exported carried one-element arrays where the GUI writes one entry
per filament. Slicing is unaffected, every reader treats a missing entry as
not mixed / no gradient, but the GUI-vs-CLI comparison reported the four
gradient keys on every mixed-filament project.

The resize helper moves from PresetBundle.cpp, where it was file-local, to
PrintConfig.cpp next to set_filament_dev_options(). It creates an option the
config lacks before sizing it, a no-op for the bundle's project config where
all seven always exist. The CLI calls it with its filament count once the
project and loaded filaments are merged, after the check that every mixed
slot has a filament of its own.
2026-10-08 13:40:36 +08:00
harrierpigeonandClaude Fable 5.1 ed8c1f92d7 Belt brim: cut the leading-edge brim at the first contact layer
The leading-edge-only brim is the outer brim cut down to the part's
first contact with the belt, and the cut was taken at layers().front().
Since the slicing frame starts at the belt below the footprint (#16236)
that is an empty lead-in layer whose contact lies ahead of the part, so
the cut removed the whole region and the brim type produced no brim at
all.  Take the cut at the first layer with geometry.

The all-brim-types test now includes leading_edge_only, and a new test
checks that the brim starts no later than the part and covers fewer
layers than the outer brim.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 19:08:59 -05:00
harrierpigeonandClaude Fable 5.1 cfad587c2d Belt: follow-ups from a second review pass
Guard the layer count and the per-object layer collection against an
object that is left without a layer to print on a belt (the counting
loop stepped before begin() and front() was taken of an empty vector).
Check the belt temperature tower's embossed model before the current
project is replaced, not after.  Only invalidate the support step of
objects that own a belt brim when an object is added or removed.  The
empty-layers test now counts an extrusion only where material is laid
down along a move.  The BeltBrim.cpp SEQUENCING note says exactly which
layers are read, and the machine-frame scale is 1/|sin|.

Remove more code that nothing calls: the kinematics inverse
(to_logical, apply_axis_remap_inverse, to_build_volume and the state
kept for them), the world_coordinates(), is_active() and
belt_brim_areas_by_layer() accessors, the PrintConfig overload of
physical_tilt() and the DynamicPrintConfig overload of
compute_belt_height_and_floor().  Comments in GCode.hpp,
BeltSliceStrategy.hpp/.cpp and PrintObjectSlice.cpp that described the
retired pre-slice remap and plane-evaluator still did; the purge-tower
width tooltip named the wrong switch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 19:08:59 -05:00
harrierpigeonandClaude Fable 5.1 febd82f6df Belt G-code: count only the layers that are written
collect_layers_to_print() drops the belt layers that print nothing (an
object's empty lead-in), but m_layer_count still counted every object
and support layer, so "total layers count", the total_layer_count
placeholder and the M73 progress disagreed with the layer changes in the
file.  Count with the same predicate, shared through
belt_object_layer_prints_something().  The by-object overload of
collect_layers_to_print() now drops those layers as well, so both print
sequences write the same layer changes.

Dropping the empty entries per object has one more effect on multi-
filament belt prints: a layer no longer selects a filament that it then
prints nothing with.  On belt_project.3mf (two filaments, belt purge
tower) the T commands go from 472 to 106 while the extruded length per
filament is unchanged; each of the removed tool changes was followed by
no extrusion.

The empty-layers test now runs for both print sequences and also checks
"total layers count" against the layer changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 19:08:58 -05:00
harrierpigeonandClaude Fable 5.1 54e079ae25 Organic supports: restore the per-slice collision, bed and belt trim
dda58b07cd stripped debug instrumentation from TreeSupport3D.cpp with a
script, and that script also deleted the loop in organic_draw_branches()
that trims every branch slice against the collision volume, the bed and,
on a belt, the belt plane.  This is the generator every printer uses, not
a belt code path, and it is the one place where raistlin7447's export
fixtures differed from main with belt printing off.  Restore the loop as
it was on main, with the belt-floor clip.

The new test prints a cube carrying a 60 mm plate with organic supports
on a flat-bed printer and checks on every support layer that no support
extrusion comes within 0.2 mm of the part's slice.  It guards that
invariant; on this fixture the loop's own effect is a sub-millimetre
reshaping of one branch (verified by slicing the fixture with and
without the loop), below the asserted gap, so the test does not by
itself fail without the loop.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 18:24:27 -05:00
Kris AustinandRodrigo Faselli c33515914d fix: Create Printer finds no system vendors in release builds (#16175)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-10-07 17:30:36 -03:00
Joseph Robertson e39d6cc089 Merge branch 'main' into belt-printer 2026-10-07 14:14:20 -05:00
harrierpigeonandClaude Fable 5.1 ef6d4a71de Tests: qualify Polyline in the belt overhang test for Windows
Windows headers declare a global Polyline, so the unqualified name in
test_print.cpp is ambiguous there (both Windows builds of belt-printer
fail at tests/fff_print/test_print.cpp:1336), as Polygon was in #16196.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 14:11:15 -05:00
SoftFever b805f2ffd6 Fill a new extruder's machine limits the same way as its other settings 2026-10-07 18:42:09 +08:00
SoftFever cc3769453f Merge branch 'main' into pr/yw4z/16162 2026-10-07 17:25:29 +08:00
harrierpigeonandClaude Fable 5.1 f64b49ab52 Belt printer: no layer changes that print nothing, and a preview that survives them
Since the slicing frame of a belt object starts at the belt below its
leading end, its first layers are empty.  On a single part they carry
the brim bands; with several parts along the belt the later parts'
empty layers fall between the earlier parts' printing layers and were
written to the G-code as layer changes with no moves at all.  The
preview numbers its layers (libvgcode::Layers) from the vertices it is
given and expects consecutive ids, so at the first such gap it stopped
creating layers and folded everything after it into the last one: the
top slider layer held nearly the whole print, the slider jumped every
other layer through the single-colour stretch before a second part on
another filament, and with the belt purge tower the whole print greyed
out while dragging.

Drop the belt layers that print nothing (no object, support or brim
content) in GCode::collect_layers_to_print, and renumber the layers
consecutively over the moves that exist when converting a result for
libvgcode, so a file with empty layers from any source still previews
correctly.  The layer slider labels a belt layer with its print Z (the
slicer's layer Z, which increases along the belt) instead of libvgcode's
toolpath height, which on a tilted layer is wherever its last extrusion
ended; the slider assumes that list increases and showed "0 / max" on
alternate layers.  The processor reads that print Z from the ";Z:" tag
non-BBL printers write (it only knew "; Z_HEIGHT:"), on belt printers
only, so nothing changes elsewhere.  Regression test: two cubes 60 mm apart along the
belt produce no layer without an extrusion and the header's layer count
matches.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 03:50:51 -05:00
HanifKoh f9ddb23804 Keep Each Filament's Device Drying Values When the CLI Merges Filaments (#16157)
The device drying options hold several values per filament, as many as
the filament preset gives, and a project stores them as the filaments'
values one after another. The CLI filament merge wrote them like an
option with one value per filament, putting each preset's first value at
the filament's own index, so a project with three filaments whose preset
gives "1", "0" was exported with 1;1;1;0;1;0 where the GUI writes
1;0;1;0;1;0.

The merge now leaves these options out of the per-filament pass and
rebuilds them afterwards from every filament's values in slot order.
Without a fixed number of values per filament one slot cannot be
replaced in place, so the stored values are kept when any slot has no
config to rebuild from.
2026-10-07 15:54:53 +08:00
HanifKoh a56d1bf33e Keep a Project's Changed Values on Extruder Variants It Doesn't List (#16107)
A project's listed settings are carried onto its base preset by update_non_diff_values_to_base_config, which matched variants by exact name and id. A variant the base gained after the project was saved got the base's value, while the same value in a user preset now falls back to the preset's first variant of that extruder. So an old project opened with its printer preset already modified, and saving it wrote the base's values into the 3MF.

The function now maps variants with map_variant_indices, as update_diff_values_to_child_config does: a base variant the project does not list takes the project's first variant of the same extruder. The variant lists themselves stay the base's, so a fallback never writes one variant's name over another's.
2026-10-07 15:51:49 +08:00
HanifKoh 662a8e340d Support the 02.08.04 Bambu Network Plug-in Series (#16202)
The 02.08.02 series appended queue_plate_id to PrintParams and nothing
after it changed the ABI OrcaSlicer calls, so adding the field brings
the current layout up to 02.08.04. Make 02.08.04 the latest series and
drop 02.08.01 from the whitelist: its PrintParams no longer matches, and
its malformed bind table is refused by dyld on macOS 27, so it cannot
load there. A stored 02.08.01 falls back to the latest series through
the existing unsupported-version path.
2026-10-07 15:51:21 +08:00
SoftFever b0da039eae Merge branch 'main' into pr/yw4z/16162 2026-10-07 14:44:59 +08:00
harrierpigeonandClaude Fable 5.1 cd155f07ae Tests: include <cmath> for std::sqrt in the belt overhang test
clang-tidy (misc-include-cleaner) flagged it on belt-printer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 01:29:53 -05:00
HanifKoh 23546e71ce Remove Unused Usings and the Includes Kept Only for Them (#16220)
151 using-directives, using-declarations, type aliases and namespace
aliases in source and test files that nothing refers to: the name is
never used, it duplicates a using already in scope, or the code sits
inside the namespace it names. Each one was removed on its own and the
file still compiled, both as it is and with every header-level using
taken away, so none of them was only redundant because a header leaks
the same name.

With the using gone, 28 #include lines and one forward declaration had
no other reference left in their file (boost/optional.hpp without any
optional, property_tree headers without any ptree) and go with it.

No header is touched.
2026-10-07 14:22:32 +08:00
Joseph Robertson ef3c47135f Belt printer: retire the redundant and unused options (#16236)
Follow-up to #16195 and the review discussion on #14394 (yw4z's note
about the third column on the *Belt tilt* row). Removes the belt options
that are redundant or unused before the branch ships, so they never need
compatibility handling after a release, and fixes supports under a
leading overhang. Every removed key is on `handle_legacy()`'s ignore
list, so existing profiles and 3MFs load silently.

## Removed

- **`belt_slice_rotation_global`**, **`preslice_remap_global`**,
**`belt_preslice_global`** (*Global mesh transforms*) and
**`gcode_back_transform`** — the global mode and the back-transform are
what belt printing is; they are presumed on wherever the flags were
consulted (`PrintObjectSlice`, `BeltBackTransform`, `BeltGCode`,
`Print::process`, `PrintApply`, `GCodeViewer`). The *Belt tilt* row is
axis + angle only; the three `fdm_belt_common.json` drop the keys.
- **`preslice_remap_x/y/z`** — no profile used the pre-slice axis remap;
the belt tilt axis plus the G-code axis remap cover the machines that
exist, and its implementation only agreed with itself for a plain swap.
The forward transform is the rotation.
- **`belt_support_z_offset_mode`** and **`belt_support_floor_mode`** —
the first was never read by a generator; the second's only shipped value
(*Generator only*) is now the behaviour.
- **`first_layer_plane`**, **`first_layer_plane_offset`**,
**`first_layer_plane_thickness`** and `FirstLayerPlane.{cpp,hpp}` — the
first-layer band is measured from the belt surface and is one first
layer height thick.
- `belt_brim_instances_compatible()` and its validation warning:
instances along the belt get their brim.

## Supports under a leading overhang (the clipping at the object's local
Z = 0)

The slicing frame of a belt object started at its lowest vertex, but the
belt under the leading end of an overhang lies below that, so no
generator could reach it: normal supports stopped at the object's lowest
layer, and both tree generators carried extension hacks sized from the
pre-rotation bbox and capped at global Z = 0 (right only for the
trailing half of the belt). The frame now starts at the lowest
belt-floor point under the footprint, less a 10 mm margin along the belt
for the base of a support column, and the extensions are gone:

- **Normal supports** run in the object frame and get the global belt Z
offset shifted onto the result (as organic already did). With the offset
on the object layers, a top contact at negative Z turned the
intermediate-layer count negative and the generator allocated layers
until the kernel killed it — any overhang in the leading half of the
belt did this. The first-layer flange expansion is skipped on a belt
(the first support layer is the leading tip, not a flange).
- **Classic tree** nodes keep dropping until their whole circle is in
the belt, so a branch tapers to a tip on the belt instead of stopping a
radius above it.
- **Organic**: the belt is no longer a support blocker. A blocker is a
collision, and a branch descending onto one slides off it, down the belt
and ahead of the part; the belt is where branches end, which the
per-layer floor clipping already does.

Regression test *Belt supports reach the belt under a leading overhang*:
a cube with a fin whose underside is parallel to the layers, 20 mm ahead
of the cube and up to 41 mm of slicing Z above the belt, for normal,
organic and classic tree supports; the lowest support layer must sit on
the belt beneath its own lines.

The belt object height (the layer range) is now estimated from the box
of the mesh as placed on the bed. `raw_bounding_box()` has the
instance's Z offset removed, which was harmless for the old
rotated-extent estimate but not for one anchored at the belt floor (a
point's rotated z and the floor under it move in opposite directions
under a Z shift): with the first version of this change every part came
out as a wedge, sliced only up to its diagonal, in the GUI and CLI
alike. Caught by a GUI test pass; the leading-overhang test now also
checks that the whole part is sliced.

## Belt brim after the parallel support step

`belt_brim_obstacles()` reads every object's layers and support layers,
which another object's support step rebuilds (and now shifts) at the
same time. The brim is generated sequentially once the parallel step is
over (`PrintObject::generate_belt_brim()`). This is the race behind the
Windows arm64 segfault in *Belt brim of each object precedes its
perimeters on its own filament*.

## UI

- *Belt tilt* is two rows: the angle (Advanced) and the axis (Developer;
a profile-level kinematics choice). A shared line is shown by its first
option's mode, so they cannot share one.
- *Machine frame transforms* is five single-option rows (G-code remap X
/ Y / Z, Decouple machine-frame tilt, Machine-frame tilt angle — the
angle row only appears when decoupled) instead of two multi-column
lines; the remap fields got full labels since they stand alone now.
- The gravity indicator on the bed is a plain line along the up
direction (no cone, 60 % of the axes' length), per yw4z.
- The *Show raw G-code (belt only)* legend/canvas toggle and its `B`
shortcut are gone; the preview is the designed view.

Also carries the two-line `phong.fs` fix from #16226 (merges as a
no-op).

## Verification

- `libslic3r_tests` 1116 passed (92 648 assertions); `fff_print_tests`
351 passed (561 696 assertions).
- `scripts/clang_tidy_diff.py --base upstream/belt-printer`: no
findings.
- `scripts/orca_profile_tool.py check`: no profile references a removed
key.
- GUI target builds; a scripted GUI pass (xdotool) checked the settings
groups in every mode, slicing, export, instances, the purge tower,
calibration dialogs, the wizard, printer switching and 3MF round-trip.

The wiki pages (OrcaSlicer/OrcaSlicer_WIKI#374) get a follow-up dropping
the removed sections once this is in.
2026-10-07 00:44:41 -05:00
SoftFever 82349e1ba4 Give each extruder its own machine limits 2026-10-07 13:41:42 +08:00
harrierpigeonandClaude Fable 5.1 a2f5a8ce2b Belt printer: size the layer range from the on-bed box
The belt object height is estimated from a bounding box swept through
the tilt rotation.  raw_bounding_box() has the instance's Z offset
removed, which did not matter while the estimate was the box's rotated
Z extent (a Z shift moves every corner alike), but the frame now starts
at the lowest belt-floor point under the footprint, and a point's
rotated z and the floor under it move in opposite directions under a Z
shift: the offset box under-estimated the height by twice the object's
height above the bed, so the layers stopped at the part's diagonal and
every part came out as a wedge (GUI and CLI alike; the unit tests never
checked the top).  Use the box of the mesh in the frame it is sliced in
(trafo_centered(), Z as placed on the bed), and have the leading
overhang test check that the whole part is sliced.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 00:10:29 -05:00
harrierpigeonandClaude Fable 5.1 dda58b07cd Belt printer: supports reach the belt under a leading overhang
The slicing frame of a belt object started at its lowest vertex, but the
belt under the leading end of an overhang lies below that, by the
overhang's length times the tilt's shear.  Every support generator works
in layers at z >= 0, so none of them could reach it: normal supports
stopped at the object's own lowest layer, and the two tree generators
each carried a stack of hacks to extend themselves below it (a post-hoc
copy of the lowest base area in TreeSupport, "virtual belt raft layers"
in TreeSupport3D/TreeModelVolumes), sized from the pre-rotation bbox
and capped at global z = 0, which is only right for the trailing half
of the belt.

Start the frame at the lowest belt-floor point under the footprint
instead, less a 10 mm margin along the belt for the base of a support
column (BeltSliceStrategy::apply_preslice_transforms and
BeltTransformPipeline::compute_belt_height_and_floor agree on it).  The
layers between it and the first vertex come out empty, which belt
slicing already tolerates, and the generators need no extension at all:

- normal supports: the generator anchors its layer grid at the frame
  origin, so run it in the object frame and shift the global belt Z
  offset onto the result afterwards, as organic supports already did.
  With the offset on the object layers a top contact at negative z
  turned the intermediate-layer count negative and the generator
  allocated layers until the kernel killed it (any overhang in the
  leading half of the belt).  Drop the first-layer flange expansion on a
  belt: the first support layer is the leading tip of the support, not
  a flange, and inflating it put lines in the air ahead of the belt.
- classic tree: a node now keeps dropping until its whole circle is in
  the belt, so the branch tapers to a tip on the belt instead of
  stopping, a radius above it, when its centre crosses.
- organic: the belt is no longer a support blocker.  A blocker is a
  collision, and a branch descending onto one slides off it, down the
  tilted belt and ahead of the part; the belt is where branches end,
  which the per-layer m_belt_floor clipping already does.

The belt brim is generated after the parallel support step instead of
inside it: belt_brim_obstacles() reads every object's layers and support
layers, which another object's support step rebuilds (and, now, shifts)
at the same time.  This is the race behind the Windows arm64 segfault
in "Belt brim of each object precedes its perimeters on its own
filament".

Also: the belt tilt axis moves to Developer mode as its own row (a
shared line is shown by its first option's mode), first_layer_plane
band thickness, belt_support_floor_mode, belt_preslice_global and
gcode_back_transform are retired and presumed on, the gravity arrow is
a plain line along the up direction, and the "Show raw G-code (belt
only)" preview toggle is gone.

Regression test: "Belt supports reach the belt under a leading
overhang" slices a cube with a fin whose underside is parallel to the
layers, 20 mm ahead of the cube and up to 41 mm of slicing Z above the
belt, for normal, organic and classic tree supports, and checks that
the lowest support layer sits on the belt beneath its own lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 22:14:25 -05:00
Joseph Robertson 7f749ee02b Merge branch 'main' into belt-printer 2026-10-06 18:27:21 -05:00
harrierpigeonandClaude Fable 5.1 8039d4d2ac Belt printer: retire the redundant and unused options
Removed, with the keys added to handle_legacy()'s ignore list so saved
profiles and 3MFs keep loading:

- belt_slice_rotation_global and preslice_remap_global. Both were only
  consulted when belt_preslice_global ("Global mesh transforms") was off,
  which no profile does; belt_preslice_global is now the single global
  mode and is presumed on everywhere the old flags were ORed in
  (PrintObjectSlice, BeltBackTransform, BeltGCode, Print::process,
  PrintApply). The Belt tilt row is axis + angle only.
- preslice_remap_x/y/z. No profile used the pre-slice axis remap; the belt
  tilt axis plus the G-code axis remap cover the machines that exist, and
  its implementation only agreed with itself for a plain swap (matrix
  columns vs remap_bbox rows). BeltTransformPipeline::build_preslice_remap,
  remap_bbox and has_preslice_remap are gone, the forward transform is the
  rotation, and the G-code header no longer carries the remap.
- belt_support_z_offset_mode. Saved and invalidated steps, but no support
  generator read it.
- first_layer_plane and first_layer_plane_offset, with FirstLayerPlane.cpp.
  On every shipped configuration the band is measured from the belt
  surface (GCode::belt_height_above_floor) and the evaluator was only
  reached for an explicit XY/YZ/XZ choice or a non-zero offset, which
  nobody set. first_layer_plane_thickness stays as the band unit,
  relabelled "First layer band thickness".

UI: the Machine frame transforms group is five single-option rows (G-code
remap X / Y / Z, Decouple machine-frame tilt, Machine-frame tilt angle;
the angle row is shown only when decoupled) instead of two multi-column
lines, and the remap fields carry full labels.

Also carries the phong.fs struct fix from #16226 so the worktree build
links its shaders.

libslic3r_tests and fff_print_tests pass; clang-tidy diff check clean;
orca_profile_tool.py check clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 18:14:34 -05:00
Rodrigo Faselli 78f74a6276 add missing headers of test_design_sketch_tool.cpp (#16233) 2026-10-06 18:25:28 -03:00
SoftFever 95a168a376 Merge branch 'main' into feature/CAD-improvements 2026-10-07 01:32:42 +08:00
Ian BassiandIoannis Giannakas c1baacf8a0 fix: thin-walled holes classic walls flip the direction (#16051)
Co-authored-by: Ioannis Giannakas <59056762+igiannakas@users.noreply.github.com>
2026-10-06 14:09:36 -03:00
SoftFever e4b0828644 Add Zoom to selection to the Design tab's rows and right-click menu 2026-10-07 00:01:07 +08:00
Ioannis Giannakas 5a8eb3f14e Fix one wall on top dropping inner walls of narrow Arachne walls (#16174)
* Fix one wall on top dropping inner walls of narrow Arachne walls

* Fix clang tidy errors on the test suite
2026-10-06 14:07:01 +01:00
Kris Austin e098c933f0 perf: write post-processed G-code without per-line copies to speed up export by up to 6% (#16167)
* perf: write post-processed G-code without a per-line copy

* perf: size the post-process line map from the first pass

* test: line ends of the exported G-code

* test: include the headers the line-ends test and gcode() helper use
2026-10-06 07:50:08 -03:00
SoftFever 250fed8808 Show the Design tab's reference planes as separate labelled squares around the origin
The XY, XZ and YZ planes no longer cross through the bed. Each is a small square in its axis
colour, set off from the axes into the corner that faces the default front view, with its name
written in the plane. Dash-dot axes run between the squares and replace the bed's axis triad
while they show. Hovering a plane greys it and selecting one makes it solid, and picking a
solid face now clears a previously picked plane.
2026-10-06 16:32:36 +08:00
SoftFever 0c2e26fa3d Stop the Design tab's move arrows from jumping the body on the first drag
Grabbing an arrow anywhere along its length snapped the body's centre to that point as soon
as the mouse moved. The body now moves by how far the cursor travels from where the arrow
was grabbed, including when it is grabbed while looking straight down the axis.
2026-10-06 14:48:48 +08:00
SoftFever e328b60992 Make the Design tab's reference planes readable where they cross
The XY/XZ/YZ planes are cut along each other and drawn back to front, with
lines along every crossing, and their fills are strong enough for the order
to show. Before, they blended into one grey smear and were too pale to work with.
2026-10-06 14:19:46 +08:00
harrierpigeonandClaude Fable 5.1 f97aa6a5af Qualify Slic3r::Polygon in the blocker-index test
tests/fff_print/test_print.cpp includes <Windows.h>, so an unqualified Polygon
in the new TreeModelVolumes test is ambiguous with GDI's Polygon() and fails
the Windows x64 and arm64 builds on belt-printer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 00:12:59 -05:00
SoftFever afa9252b59 Make the Fit camera button frame the Design tab's selection and sketches
In the Design tab the button always swung the camera to the plate view and framed the whole
bed, whatever was selected: the tab's picks and sketches are neither the canvas's selection
nor its volumes. It now frames the selected faces, body, edges, vertex, sketch region or
sketch entities, and with nothing selected everything on show — the visible bodies, the
feature preview and the sketches — keeping the current view direction. An empty tab still
frames the bed as before.
2026-10-06 12:28:52 +08:00
Joseph Robertson d2aa937ad7 Merge branch 'main' into belt-printer 2026-10-05 23:20:23 -05:00
harrierpigeonandClaude Fable 5.1 61a0db4a87 Belt printer: address the review on #14394
Code review items (raistlin7447):

1. PrintObject::slice() zeroes m_belt_min_z, m_belt_global_z_offset and
   m_belt_global_xy_correction before slicing. They were only written in belt
   mode, so a project switched to a normal printer, or whose tilt axis was set
   to None, kept the old offsets and shifted the adaptive infill octree and the
   organic support layers by them.
2. TreeModelVolumes shifts the support blockers into the raft-offset index
   space; a test now pins the index the blocker lands on.
3. The final-alignment clamp in libnest2d is opt-in (NfpPConfig::clamp_to_bin)
   and arrange sets it for belt printers only. Printers with an off-centre
   best_object_pos keep their alignment; a flat-bed test pins that.
4. The preview's belt view follows the loaded G-code, not the selected printer:
   GCodeProcessor carries the file's belt keys (and, for a belt file, its bed)
   into export_config_for_render(), and GCodeViewer enables the belt view from
   the header tilt.
5. belt_shift_layer_grid() also shifts the cached belt floor and the global Z
   offset, so a support-only or brim-only change after the purge-prism snap
   matches a fresh slice.
6. update_print_fff_config() resets raft_layers and draft_shield on a belt
   printer instead of only greying out the fields Print::validate() rejects.
7. GCodeWriter takes a first-layer point test instead of the FirstLayerPlane;
   GCode installs one that measures from the belt surface, like its
   extrusions, so the first-layer travel speed and the second-layer
   temperature change no longer depend on the gcode_remap_* convention.
8. belt_brim_clip_leading_edge() is exported and called by both the generator
   and the test.
9. Both phong.vs shaders use slope.up_direction for the overhang highlight.

The pre-slice and G-code axis remaps are gated on belt_printer through
BeltTransformPipeline::axis_remap_enabled(), so belt keys left in a profile
cannot change a non-belt print.

Tests requested in the review: belt-only keys at non-default values leave
non-belt G-code unchanged; switching a sliced project from belt to non-belt
(and tilt axis None) matches a fresh slice; a support-only change on a belt
purge print matches a fresh slice; non-belt start G-code moves keep the
first-layer Z in the processor; the belt brim's segment count catches a band
emitted twice.

The belt-to-non-belt test exposed an unrelated gap: invalidate_step(posSlice)
re-invalidated posSupportMaterial but not posSimplifySupportPath, so after
any re-slice the regenerated support paths were exported unsimplified.
posSimplifySupportPath is now in that list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 23:06:01 -05:00
harrierpigeonandClaude Fable 5.1 9dbd0307f8 Add the includes clang-tidy's include cleaner asks for on the belt files
The clang-tidy job on #14394 fails on 129 misc-include-cleaner findings:
the belt sources and tests use std::, Eigen, Point/PrintConfig and
BeltBrim symbols without including the header that provides them, which
only compiled because the precompiled header supplied it. Every include
the job names is added, in each file's existing include style ("../" in
the GCode/ and Support/ subdirectories, quoted libslic3r/ paths in the
GUI and tests). No code changes.

Verified with scripts/clang_tidy_diff.py -p build-tidy --base eb5b9a77b9
(SLIC3R_PCH=OFF compile database, clang-tidy 22.1.8): no findings left.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6Kg5igmmMU2YLoK6HrsWV
2026-10-05 20:43:18 -05:00
Kris Austin 1d577ea4e2 build: add the missing includes only a Windows build reports (#16110) 2026-10-05 21:49:32 -03:00
Kris Austin 9e5bfc272c fix: Compare Presets crash on filaments with different variant counts (#16176) 2026-10-05 21:20:12 -03:00