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>
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.
_update_select_plate_toolbar_stats_item(true) runs from
on_action_slice_all before the select-plate toolbar has necessarily been
initialized. m_all_plates_stats_item is only assigned in
_init_select_plate_toolbar, so slicing a multi-plate project shortly
after startup (before the Preview tab has rendered) leaves the pointer
null while show_stats_item is true, and the branch dereferences it,
crashing with SIGSEGV.
Every other dereference of this pointer already null-checks it. Add the
same check here so the all-plates stats item is left unselected until the
toolbar is initialized instead of crashing.
Fixes#15116
Prime towers reserved depth from the prime volume alone, ignoring the flush
matrix: rib-wall towers in both the engine and the preview, and rectangle and
cone towers in the preview, which never carried the flush-aware estimate the
engine already used. The preview also read the print preset, which does not
carry the printer- and filament-scope keys the estimate needs and so silently
fell back to defaults. On multi-nozzle printers the flush matrix, which holds
one block per nozzle, was additionally read as a single block. The tower could
come out too small for the purge it has to hold.
The flush-based estimate also skipped the height-based minimum depth that the
prime-volume one applies, so low-flush prints could estimate a tower shallower
than the one that actually gets built.
The placement clamps and the tower-approach router both stood in the bed's
bounding box for the bed itself, so on a delta or hexagonal bed the prime tower
could be parked in a corner that does not exist and the nozzle could be routed
across it. Both now test the real printable outline, slicing reports a tower
that does not fit instead of printing it off the bed, and a tower parked near an
edge is routed along the clamped side rather than falling back to a straight
line across the tower.
Also fixes the placement validation rotating the tower hull by degrees read as
radians about the plate origin, and never rotating the generated tower footprint
at all.
* Fix gizmo being closed after releasing mouse outside the gizmo floating window
The left up event of a drag started on the gizmo floating window (e.g.
selecting text in an input field) and released over the bed was treated
as a click on the plate, which deselected the objects and closed the
active gizmo. Add the ignore_left_up guard to the plate select branch,
matching the deselect branch above.
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Emboss gizmo being closed after releasing mouse outside its floating window
The Emboss gizmo has its own close-on-click-away handler
(on_mouse_change_selection) that was not protected against left up events
originating from ImGui windows, so the gizmo was still closed when a drag
started on its floating window (e.g. selecting text in the input field)
ended over the 3D scene. Expose the canvas's ignore_left_up state to
gizmos and skip the close check for such releases.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Call proper EXT variant of the function if framebuffer type is EXT
* Update glad with `GL_EXT_framebuffer_blit` and `GL_EXT_framebuffer_multisample` extensions support
Resolve five conflicts, all of which needed both sides rather than a pick:
- BackgroundSlicingProcess: ours was a pure tabs->spaces reformat of base, so
keep main's per-filament volume/nozzle map read-back (its only change here).
- GUI_App: main's #12506 else-if attached to an `if` this branch deleted;
re-expressed onto the same-agent early-return path (the agent factory caches
per id, so pointer equality is the same predicate).
- MainFrame: both sides relocated Sync Presets independently; keep main's
push_notification plus the branch's Plugins menu items.
- Tab: the "TODO: Orca: Support hybrid" blocks were unchanged base, not a branch
decision; take main's enabled Hybrid to match the already auto-merged siblings.
- test_config: union of both sides' cases (6 plugin + 9 multi-nozzle).
Plater's pImpl (unique_ptr<priv> p) is destroyed before the wxWindow base
destructor runs DestroyChildren(), so child GLCanvas3D windows are torn down
after p is gone. GLCanvas3D::~GLCanvas3D() -> reset_volumes() then dereferences
the freed p through two paths:
- Selection::clear() -> plater()->canvas3D() -> p->get_current_canvas3D()
- _set_warning_notification() -> plater()->get_notification_manager()
Guard both with the existing wxGetApp().is_closing() flag; both are UI-only
side effects that are no-ops during shutdown, so normal-use behavior is
unchanged.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Multi-nozzle sync widget, AMS rack-nozzle mapping popup, calibration rework, send-dialog nozzle mapping and extruder-count UI. Includes the fix to persist the AMS sync badge on filament cards (H2C/A2L and direct-sync printers).