* Add Missing Includes Across src/slic3r/GUI
Every GUI source and header now directly includes the headers declaring what it uses, rather than relying on the precompiled header or transitive includes. Generated with clang-tidy misc-include-cleaner, plus one hand edit making CalibrationPanel.hpp self-contained.
* Drop the OS-Specific Includes Added Outside Their Platform Guards
GLib, GTK, D-Bus and POSIX headers are only used inside platform #if blocks, which already include them. Added unconditionally at the top of the file they broke the Windows build.
* Add the clang-tidy Configuration That Generated These Includes
Only misc-include-cleaner's missing-include check, with the headers it must never suggest: per-platform, internal and OS-specific ones that would break other platforms or are not meant to be included directly.
* Match Windows Paths in the clang-tidy Ignore List
Header paths use backslashes on Windows, so every / in a pattern is now [/\\]. The Windows SDK headers are ignored alongside the other OS-specific ones, and the list is one pattern per line. Suggested by @raistlin7447 from a Windows clang-cl run.
Since the CLI can open an OpenGL context (#15745) it renders plate
thumbnails on export, and the viewport restore at the end of
render_thumbnail_internal (#15674) then reads the plater through the wx
application. The CLI has neither, so every --export-3mf on a machine
with a display died with a segmentation fault after the first
thumbnail. Skip the restore when there is no application or no plater;
the GUI path is unchanged.
# Description
This PR introduces lifecycle events to the plugin API.
For all plugin capabilities, you can define a `on_lifecycle_event`
function in the plugin that takes in a event enum and a small payload
for some generic information on the lifecycle event.
The idea is to keep the payload generic and small, and if you want to
get more information, you should invoke other more targeted APIs to get
more information.
For example, lets say you are keeping track of the the `ObjectAdded*`
event hook for model transformation, addition or deletion. The payload
would tell you the name of the model, and you should use a targeted API
such as `orca.host.plater().model()` to get more information on the
model. This is the overall design principle of the API.
Currently the lifecycle events are the following:
```cpp
enum class LifecycleEvent {
// Project (3mf)
NewProject,
ProjectOpened,
ProjectBeforeSave,
ProjectAfterSave,
ProjectClosed,
ProjectDirtyChanged,
// Slicing pipeline
SliceStarted,
SliceGeometryFinished,
GCodeExportStarted,
GCodeExportFinished,
SlicingJobComplete,
// Plate/model editing
ObjectAdded,
ObjectDeleted,
ObjectTransformed,
ObjectChanged,
ObjectRenamed,
PlateCreated,
PlateDeleted,
PlateSelected,
PlateRenamed,
// Preset
PresetSelected,
PresetSaved,
// Printer/device
PrintStateChanged,
DeviceOnlineChanged,
DeviceDiscovered,
DeviceSelected,
DeviceConnected,
DeviceDisconnected,
UploadStarted,
UploadFinished,
// Print/send jobs
PrintJobStarted,
PrintJobFinished,
SendJobStarted,
SendJobFinished,
};
```
This is an initial draft and lifecycle events can be included later on.
[orca_telegram_notifier_plugin_any.py](https://github.com/user-attachments/files/31220973/orca_telegram_notifier_plugin_any.py)
If you're familiar with telegram bots, after you install the telegram
bot, in the config of this plugin, you can enter the Bot ID and the Chat
ID with said bot.
# 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.
-->
For this plugin, I am testing it with a telegram bot that sends me a
message on lifecycle event.
<!--
> 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)
An instance added with "+" was never registered with the plate it landed on,
and moving an instance only re-registered instance 0 of its object, so a copy
dragged onto another plate stayed unknown to that plate's registry. The
plate's filament list, its wipe tower preview and the position clamp all read
that registry, so a multi-filament copy moved onto a single-filament plate
drew no tower there and its tower position was never clamped.
Register new copies at creation, notify exactly the instances a move changed
(every instance of the object when one of its parts moved), and drop the
registry entry when a copy is removed again.
Every edit makes the precedence the compiler already applies explicit. None
of them regroups an expression, so behavior is unchanged at all eight sites.
Strip parentheses and whitespace from the diff and the token stream matches.
GCodeProcessor.cpp:1472 tests == where the symmetric clause below tests !=,
which reads like a typo and is not one. A comment now explains why.
OrcaSlicer.cpp:4760 was the only judgment call. Its leading !is_seq_print is
bare while both operands are parenthesized, so the written form matches what
the compiler does. Kept rather than guessed at.
ImGui::Text and ImGui::TextColored take a printf format, so these six sites
passed data where a literal belonged. A % in that data reads a vararg that
was never supplied.
Three sites in GLCanvas3D's paint toolbar passed filament text, which comes
from the filament preset config and is user-editable. Two more passed
translated strings, where a % in any of the 23 catalogs does the same.
GLGizmoSimplify passed its progress label.
That label had been built with an escaped %% because it was being used as a
format string. Passing it as an argument instead needs a single %, so it
still renders as "42%".
ToUTF8() returns a buffer class, which converts to const char* for a named
parameter but not through varargs, so those two sites need .data().
GLGizmoSimplify.cpp:335 is unchanged, because _u8L("%d triangles") is passed
with a real argument and has to stay a format string.
Validation grows the estimated body by the brim before the tower is
generated, so a tower whose brim leaves the bed is rejected up front
instead of at export. The scene reload re-clamps the stored position,
since set_default_wipe_tower_pos_for_plate does not rerun when painting
changes the filament count. The rectangle-wall footprint polygon gets its
two missing brim corners (it was a skewed quad), so the post-generation
check covers the whole brim.
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.
On macOS wxWidgets reports Ctrl+left as a synthetic right button, which is
what made Ctrl+drag pan the canvas. #14999 added an unconditional correction
of the event's button state from wxGetMouseState(), which reports the
physical buttons and knows nothing about that synthesis, so the synthetic
right button was overwritten with a plain left button on every event.
Ctrl+drag then matched the left button mapping and rotated instead of
panning.
Apply the correction only when the event carries no button state at all.
On macOS wx populates button state only for the mouse-down and mouse-dragged
event types, which are also the only ones the Ctrl+left translation touches,
so the ImGui capture fix keeps every event it was added for.
Fixes#15214
Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
* build: enable /Zc:lambda for MSVC
MSVC keeps its legacy lambda processor under /std:c++17, which rejects
reading a constexpr constant inside a lambda that does not capture it
(C3493). No other compiler requires that capture, and clang reports it as
an unused one, so the two cannot both be satisfied without the flag.
/Zc:lambda selects the conforming lambda parser that clang and GCC
already use. It is implied by /std:c++20 and /permissive-, so it is only
needed while we are on C++17. clang-cl is conforming already and does not
take the flag.
It requires VS2019 16.8, so build_release_vs.bat now says 16.8+.
* build: clear 237 unused lambda capture warnings
236 captures across 81 files, 142 of them `this`. Removing an unused
capture changes no behavior; clang does not report a capture whose type
has a non-trivial destructor, so nothing held only to extend an object's
lifetime is in this set.
Nine of them are the second half of the warning, "is not required to be
captured for this use", where the capture is a const or constexpr value
the body does read. Those depend on the /Zc:lambda change in the previous
commit. One of them, in FillRectilinear.cpp, had been worked around with
an #ifndef __APPLE__ guard around the capture list, which is now gone.
GUI_ObjectTableSettings.cpp captured its reset button only to read it
inside #ifdef __WXOSX_MAC__. That branch now takes the button from the
event it is already handling.
* build: fail configure on MSVC older than 19.28 instead of dropping /Zc:lambda
cl.exe answers an unrecognized /Zc: sub-option with warning D9002 and keeps
going, so on VS2019 before 16.8 the flag is silently ignored and the build
instead dies with C3493 in FillRectilinear.cpp, nowhere near the cause.
* fix: delete three locals that are now unused
Their only remaining use was the lambda capture this branch removed. The
Clang builds set -Wno-unused-variable, so the build never flagged them.
---------
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
In CAD the centre IS the sketch origin -- GLCanvas3D already moves the axis
triad there for exactly that reason. The grid under it did not agree: it comes
from PartPlate::calc_gridlines, generated from m_origin, the plate's front-left
corner, with an adaptive step meant for a print bed.
Measured on a screenshot from the user's machine: the nearest grid line was 10 px
from the origin in a 23 px pitch. The origin floated mid-cell, in both axes.
Corner-origin is CORRECT for Prepare -- a print bed starts at a corner -- and the
plate list is SHARED with the plater, so re-centring it there would change the
bed for every user of the app to fix one tab. The seam used instead already
existed: _render_platelist takes show_grid, and m_axes_at_bed_center is already
the "this is the Design canvas" flag. The Design canvas suppresses the plate's
grid and draws its own.
Minor every 10 mm, major every 50 mm, both generated from bed_center() so a line
passes exactly THROUGH the origin in each axis. Two GLModels, rebuilt only when
the bed shape changes, not per frame.
White majors, grey minors, the SAME in both themes. There is no white bed to
vanish against: the plate is dark grey either way (DEFAULT_MODEL_COLOR
{0.326,0.337,0.337} light, DEFAULT_MODEL_COLOR_DARK {0.255,0.255,0.283} dark),
a difference of 0.07. An earlier draft inverted the palette on the light theme;
that was a branch buying nothing. For contrast with what this replaces: the
plate's grid draws BOTH its thin and bold families in one 0.43 grey, which is
most of why the stock grid reads as a flat mesh with no scale to it.
z = -0.26, the same value as PartPlate::GROUND_Z_GRIDLINE -- below the bed fill
at -0.03, above the bed model at -0.41, so no z-fighting. Matched by
construction, since that constant is file-static in another TU.
Known limit, commented: the grid is clipped to the bed's BOUNDING BOX, not its
polygon. Identical on a rectangular bed; on a circular one it would spill past
the round edge. The target printers are rectangular.
Verified on the rig, not just compiled: white majors over a fine grey mesh, and
a white line through the origin in both axes.
snaporca-kha0
The sidebar Mixed Filament list, the extruder icons, the color painting
gizmo and the canvas filament bar now show the same bottom-to-top fade the
Edit Mixed Filament preview shows, custom gradient curves included, instead
of a horizontal fade between the two component colours. Ordinary and vendor
multi-colour filaments are drawn exactly as before.