The "Show raw G-code (belt only)" toggle, retired in #16236, returns as
an item of the Preview canvas view menu (with its B shortcut), and only
there: no legend checkbox. Unlit, the preview shows the designed,
upright view; lit, the raw machine-frame G-code, which is what to look
at when checking the machine frame transforms. The toggle is view
only; exported G-code is the same either way.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
# Description
The default Orca Cloud API URL omits its scheme, so libcurl interprets
it as HTTP and follows the server redirect to HTTPS. Recent libcurl
versions intentionally do not forward the `Authorization` header across
protocol/port-changing redirects, causing Orca Cloud profile sync to
receive HTTP 401 `missing_authorization` responses and eventually log
the user out.
Use the HTTPS API URL directly. Besides restoring sync with current
libcurl versions, this improves security by preventing the bearer access
token from being sent in the initial unencrypted HTTP request.
# Screenshots/Recordings/Graphs
N/A — no UI changes.
## Tests
- `git diff --check`
- Confirmed with current libcurl that the scheme-less URL redirects and
loses the authorization header, while the direct HTTPS URL retains it
A using-directive or using-declaration in the global namespace of a
header reaches every file that includes it, and a using-declaration also
makes the include checker treat that header as the one to include for
the name. google-global-names-in-headers reports both, on changed lines
like the existing check, so headers that still have one are not held to
it until the line is touched.
The check does not see a using inside a namespace.
clang_tidy_diff.py's closing message assumed every finding was a missing
include; it now says other findings need a manual fix.
- ClipperUtils.hpp imported jtMiter, jtRound and jtSquare into the
global namespace for every includer. No code names them there.
- BBLStatusBar.hpp, BBLStatusBarBind.hpp, BBLStatusBarPrint.hpp,
BBLStatusBarSend.hpp and ProgressStatusBar.hpp re-exported their class
into Slic3r::GUI. Nothing refers to the class through that namespace.
- Jobs/SendJob.hpp, Jobs/BindJob.hpp, Jobs/UpgradeNetworkJob.hpp and
AuxiliaryDataViewModel.hpp declared "namespace fs = boost::filesystem;"
at global scope without using it.
Each of these headers put a using or namespace alias at global or
namespace scope, which every includer inherited:
- BBLTopbar.hpp: "using namespace Slic3r::GUI;" at global scope, reached
through MainFrame.hpp. Seven source files used GUI names unqualified
outside the namespace because of it, one of them as "::RadioBox".
- IMSlider.hpp and TickCode.hpp: "using namespace CustomGCode;" inside
Slic3r.
- ProjectTask.hpp, Jobs/PrintJob.hpp and ConfigWizard_private.hpp:
"namespace fs = boost::filesystem;". PresetBundle.cpp and GUI_App.cpp
had no alias of their own.
- VoronoiUtils.hpp: "using VD = Slic3r::Geometry::VoronoiDiagram;" at
global scope.
The headers now spell the names out. Source files that used them get
the qualifier, or a using of their own where there are many uses.
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.
* Stop Leaking json Through Headers and Drop Includes Kept Only for the Name
AppConfig.hpp, DeviceManager.hpp and UserManager.hpp carried a global
"using namespace nlohmann;", json_diff.hpp a global "using json =
nlohmann::json;" and PrinterFileSystem.h a global "using nlohmann::json;".
Every file that included one of them, directly or not, could write a
bare json, and 63 did without declaring it.
The last two also made the include checker treat json_diff.hpp and
PrinterFileSystem.h as the headers that provide json, so they were
included from files that use nothing else from them: 57 of the 59
includers of json_diff.hpp never name json_diff.
The five statements are removed. Headers that use the type now spell
nlohmann::json, source files declare their own "using json =
nlohmann::json;", and the includes that only supplied the name are
dropped or replaced by <nlohmann/json.hpp>.
Eight files reached json_diff.hpp only through an include that is now
gone and with it lost that header's "using namespace std;". The std
names they used unqualified are qualified.
* Declare json in OrcaSlicer.cpp on Every Platform
OrcaSlicer.cpp had its "using namespace nlohmann;" and the json include
inside the Linux-only include block, so on Windows and macOS it took
json from AppConfig.hpp's global directive, which is gone. The include
and a "using json = nlohmann::json;" now sit outside the block.
The loader's ignore set in PrintConfigDef::handle_legacy() gained the
belt options retired in #16236, and the profile tool's unit test checks
that its OBSOLETE_KEYS matches that set, so the Check profiles job
failed on belt-printer. Add the twelve keys.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
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>
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>
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>
Fixes the `unable to load shaders: phong` error at startup on
`belt-printer` after #16195. That PR added `vec3 up_direction` to the
`SlopeDetection` uniform struct in `phong.vs` (110 and 140) but not in
`phong.fs`, so the vertex and fragment stages declared the `slope`
uniform with different struct types and the program failed to link.
`gouraud.fs` already carried the member; `phong.fs` now does too.
Shader-only change.
#16195 added slope.up_direction to the SlopeDetection uniform struct of
phong.vs (110 and 140) but not to phong.fs, so the two stages declared the
uniform with different types and the program failed to link: "unable to
load shaders: phong" at startup, and studio lighting / realistic phong
rendering fell back. gouraud.fs already carries the member.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Gives every option in the *Belt printer* and *Machine frame transforms*
groups, the build plate tilt, the belt purge tower enable and the belt
purge tower width a wiki link (the *Wiki* button next to the option),
pointing at the pages and anchors added in
OrcaSlicer/OrcaSlicer_WIKI#374. The two purge tower links that pointed
at a whole page now point at their section. String arguments and
`label_path` assignments only; the wiki's Tab-link validator passes
against this `Tab.cpp` with that branch.
# Description
Filament changes on the Prusa CORE One MMU3, MK4 MMU3 and CORE One INDX
now use the settings PrusaSlicer 3.0 ships for them. On the MMU3
printers these are Prusa's per-material ramming, load and unload speeds,
cooling moves and stamping. On the INDX they are Prusa's multi-tool
ramming and 10 mm³ minimal purge, plus a filament start G-code that
restores pressure advance after the purge station disables it and then
sends `M573 R`, as PrusaSlicer does.
This supersedes #16008. Thanks to @nuclearmistake for that work, which
identified what these printers need for reliable filament changes. This
PR reaches the same goal with the existing `include` mechanism rather
than new printer-level overrides. The values live in shared templates in
the Prusa bundle (PLA and PETG families with High Flow ramming variants,
and one for the INDX), and the filament presets include them, so each
material keeps its own values as in PrusaSlicer. For the MK4 MMU3, ten
small presets inherit the MK4 filament tunes and include the templates;
they cover the materials PrusaSlicer offers with the MMU3 and replace
the library generics as that printer's defaults. The CORE One MMU3 0.6
nozzle now uses the 0.6 Generic PLA and Prusament rPLA profiles, as in
PrusaSlicer. Unlike #16008, filaments from Orca's shared library keep
Orca's defaults on these printers.
No engine change, and printers without an MMU3 or INDX are unaffected.
MK4 MMU3 users also get the MK4's material tuning, such as temperatures
and cooling, from the new presets.
# 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 follows up on #16019 with fixes and workflow improvements to the
Design tab. Sketching now waits for you to pick a plane, the reference
planes stay out of the way until they are needed, and the camera follows
the mouse controls set in Preferences, as suggested by @Felix14-v2 in
https://github.com/OrcaSlicer/OrcaSlicer/pull/16019#issuecomment-5932747510.
It also fixes rendering, camera and Move bugs, which are listed below.
https://github.com/user-attachments/assets/6aac0a03-8405-403a-93b2-1fbf95da9fe7
**Improvements:**
- Pan and orbit follow Preferences > Control while sketching too. A
right-drag no longer ends the polyline chain or drops the point already
placed, and in the Touchpad camera style Alt+move and Shift+move orbit
and pan while a draw tool is selected.
- The XY, XZ and YZ planes are separate labelled squares around the
origin, in their axis colours, with dash-dot axes. They no longer cross
through the bed as one grey smear. Hovering over a plane greys it out,
and selecting one makes it solid.
- The reference planes stay hidden until a sketch needs them. A new
Origin row in the Feature tree keeps them on screen, and Ctrl+Shift+O
toggles it.
- A sketch opens only once its plane is chosen. If a flat face or a
reference plane is already picked, the sketch opens on it at once.
Otherwise the planes appear, and the next plane or face you click opens
the sketch. Esc or Cancel leaves without one.
- The Bed checkbox is now a row under Origin, and its state is
remembered across sessions. Both rows sit above the feature list as
fixed view switches.
- Zoom to selection is available on Feature tree and Bodies rows and in
the right-click menu.
- A Sketch button replaces the FEATURES label, the import icons now have
an arrow, and the document icons are sized consistently.
**Fixes:**
- Feature previews no longer z-fight with the bodies. The Hole preview
now hides the bodies and shows only the result, as Fillet/Chamfer and
Draft already do.
- Body edge lines stay in sync with the bodies after undo, hide and
delete.
- The bed, grid and reference planes stay aligned on every plate, not
only the first.
- The Fit camera button frames the selection and sketches, or everything
on show, instead of always framing the whole bed.
- Grabbing a move arrow no longer makes the body jump on the first drag.
- Move no longer gets stuck after Esc or a click off the gizmo. Esc and
Cancel put the body back, and undo waits until the Move is confirmed or
cancelled.
- The camera stays still when the first body appears.
- The view buttons no longer cover the status line at display scales
above 100%.
- The import buttons no longer stay highlighted after a click.
- The Bodies right-click menu no longer closes at once on Linux.
# Screenshots/Recordings/Graphs
- **Z fighting issue**
Before fix:
https://github.com/user-attachments/assets/0da30897-8d81-494a-a206-9b4dfd8fa9c0
After fix:
https://github.com/user-attachments/assets/04ccad39-dbbc-4bcf-8d5c-3ba4894cb755
- **Sketch plane rendering**
Before:
<img width="374" alt="{CCFCEB16-20FA-4202-A5F8-5F2219E44C0B}"
src="https://github.com/user-attachments/assets/2dfd19b2-9991-45c7-91e3-e139d111229c"
/>
After:
<img width="1706" height="1258" alt="image"
src="https://github.com/user-attachments/assets/3ec89038-4614-4c04-9f20-37bfc50ee5ef"
/>
- **Wrong body frame lines**
Before:
https://github.com/user-attachments/assets/81ccae26-2a9d-4ecb-9928-678dbe9fb94c
After
## 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: crash in LAN mode when the printer type is not known yet
InputIpAddressDialog::set_machine_obj() built the help image name from
the printer config with no fallback. If the printer type is empty or
unknown, for example before the first push_all arrives on a flaky LAN
link, the lookup returns "" and create_scaled_bitmap("_en") throws.
The dialog is opened by the "LAN Connection Failed" handlers in
MediaPlayCtrl and MediaFilePanel, where nothing catches the exception,
so the app crashes.
Use input_access_code_x1 when there is no image, and the _cn image for
zh_CN, the same as ConnectPrinterDialog::init_bitmap().
Ported from Bambu Studio 52ca2ec5d1.
* fix: return an empty bitmap for an empty icon name
create_scaled_bitmap() threw when a caller passed an empty name. That
happens when a printer config lookup has no entry, for example in
AMSSetting::update_ams_img() for a printer type with no AMS image.
Log an error and return wxNullBitmap instead.
Ported from Bambu Studio 52ca2ec5d1.
They now sit above the features' framed list as fixed view switches:
a click no longer selects them, they stay put while the features scroll,
their eyes line up with the features' eyes, and their labels dim when
hidden. Ctrl+Shift+O toggles the Origin from the keyboard, as
Ctrl+Shift+B does the Bed. The test script's position for the first
feature row is calculated, not measured, and needs re-measuring on the
test setup.
The bed's show/hide state is now remembered across sessions like the Origin
row's, shown by default. The GUI ladder's ribbon x-coordinates are shifted by
the removed checkbox's derived width and still need re-measuring on the rig.
Sketch on a picked flat face or reference plane opens the sketch on it at once. With nothing
picked it no longer enters sketch mode: the reference planes and axes come up, and the plane or
flat face clicked next opens the sketch and puts them away. Esc or Cancel leaves without one.
A picked plane is used up by the sketch on it and dropped by Esc or a click on nothing, the plane
prompt is no longer replaced by a stale tool hint, and clicking the face a sketch was just
cancelled on picks that face again rather than the whole body.
* 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