Commit Graph
12693 Commits
Author SHA1 Message Date
Clifford Garwood 481cd7d8e7 Merge remote-tracking branch 'upstream/main' into feedback 2026-04-21 14:56:08 -04:00
Ian BassiandRodrigo Faselli f70d30bf79 W10 double window fix (#13074)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-04-20 19:27:38 -03:00
Ian Bassi bfb70c598c CalibUtils: Center mesh models (#13252) 2026-04-20 19:18:14 -03:00
Valerii Bokhan 31c1c29325 Fix: Globally fixing the "milimeters" typo in the code (#13295) 2026-04-19 20:28:13 -03:00
Eyal Levin 43da0f7d9a Fix crash when selecting or moving wipe tower (#13243) 2026-04-18 07:42:54 +01:00
Ian Bassi 51589035e0 Update JD calib limits (#13253) 2026-04-17 10:42:39 -03:00
80ef058aaa Bambu H2D: Filament group wiki fix (#12880)
Co-authored-by: yw4z <yw4z@outlook.com>
Co-authored-by: yw4z <ywsyildiz@gmail.com>
2026-04-16 14:38:26 -03:00
Clifford GarwoodandClaude Sonnet 4.6 2cfdddf8b0 fix: crash on Multimaterial tab for all printers (Windows-only)
The "Pre-slice warnings" line in the IDEX/IQEX Configuration section
was a widget-only line (no options) with full_width left at the default
of 0. activate_line() only skips the option_set.front() call when
full_width=1; without it, the code falls through to:

    bool is_legend_line = option_set.front().opt.gui_type == ...

Calling front() on an empty std::vector is undefined behavior. On
Windows/MSVC release builds this dereferences a null pointer and reads
at offset 0x30 (where ConfigOptionDef::gui_type lands), producing an
ACCESS_VIOLATION at 0x30. On Linux/GCC the same UB happens to be
harmless, so the crash is Windows-only and cannot be reproduced on
Linux.

Fix: set line.full_width = 1, matching the pattern used by the "Modes"
(IMEXModesCtrl) line. This takes the early-return widget path in both
append_line and activate_line, bypassing option_set.front() entirely.

Reported by tester: crash on clicking Multimaterial tab with any
printer (K3D VOSTOK confirmed), build af59501f.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:45:25 -04:00
Noisyfox a162e3f031 Fix macos crash on close (#13215)
# Description

<!--
> 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

<!--
> Please describe the tests that you have conducted to verify the changes made in this PR.
-->
2026-04-15 23:03:59 +08:00
Ian Bassi 16727644bb Reduce size by Json Fromatting (#13163)
Reduce the size of current and new JSONs by standardising them with 1 tab indentation instead of 4 spaces.
This effectively reduces the size by almost 20 MB.

| Current | New |
|---|---|
| 85.2 Mib | 67 Mib |

Used [JQ](https://jqlang.org/) `--tab` to automatically format every current JSON.

> [!NOTE]
> Some profiles had the arrays on the same line, but those created by Orca were in the standard format (each object below the previous one). In some cases, this increases the number of tabs due to the new lines, but the increase is negligible, and this way both the base profiles and those created by Orca maintain the same style.
2026-04-15 22:58:12 +08:00
f7ef8a14bd Add Feature to disable snapping to buildplate (#11801)
* identified code for snapping to buidlplate

* rename internal name to ensure_on_bed to be consistent, saves option in 2mf, finish Move UI, use in both ensure_on_bed() functions

* makes auto_drop a per-object setting, removes global setting

* remove adUndef, add auto_drop to constructor/serialize

* fixes drop() button

* add "auto_drop" checkmark to "load as single object" dialog,
nothing changes if auto_drop == yes || "load as single object",
if auto_drop == false and "load as single object" == false the objects now retain their relative position to each other

* retains auto_drop (and printable) state when assembling or splitting objects,
adds ObjectList::printable_state_changed()  overload to be able to only provide ModelObject* vector

* adds dialog when splitting to ask if auto_drop should be disabled,
only shows when auto_drop enabled and atleast one volume  floating

* adds arrow indicator on bounding box if auto_drop == false

* removes unneeded code, keeps "auto_drop" naming consistent

* makes for loop simpler in set_printable, set_auto_drop and get_auto_drop,
makes get_auto_drop const,
fixes wording in Snapshot text

---------

Co-authored-by: Hanno Witzleb <hannowitzleb@gmail.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-04-15 22:36:25 +08:00
yw4z f02aa7200e Fix over scaled controls on windows (#13117)
init
2026-04-14 22:48:38 +08:00
Clifford GarwoodandClaude Sonnet 4.6 84fc851846 feat: add "Don't show again" to IMEX pre-slice warnings
Replaces MessageDialog with RichMessageDialog to show a suppress
checkbox on both slice-plate and slice-all warning paths. Persists
the choice to app_config as imex_pre_slice_warnings=false. Adds a
re-enable toggle in Printer Settings → Multimaterial → IDEX/IQEX
Configuration so the warnings can be restored if suppressed accidentally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 09:17:29 -04:00
Clifford GarwoodandClaude Sonnet 4.6 857bfbfb82 fix: guard against empty option_set in OG_CustomCtrl widget-only lines
update_visibility() and render() both called front() on an empty vector
when a CtrlLine had no options (pure widget lines). Added an early-return
path in update_visibility() and a null-guard in render().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 09:17:23 -04:00
Clifford GarwoodandClaude Sonnet 4.6 ad0b42fd37 feat: iMEX temperature handling and pre-slice warnings
Temperature emission (GCode.cpp, PrintConfig.cpp, ConfigManipulation.cpp):
- Set temperatures for all active tools in layer_change_gcode for iMEX
  parallel modes (primary + secondary carriages)
- Fix filament temperature commands so Layer 1 temperatures only emit on
  the first layer; subsequent layers use normal layer-change temperatures
- Remove stray temperature commands that fired outside the intended context
- Consolidate iMEX temperature handling into the second-layer transition;
  clean up emission logic and naming throughout

Pre-slice warning dialogs (PartPlate.cpp/hpp, Plater.cpp):
- Collect per-plate IMEX warnings before slicing: multi-material conflict,
  bed temperature mismatch between carriages (>5 °C delta), and filament
  type incompatibility
- Show a dismissible Yes/No dialog from both "Slice Plate" and "Slice All"
  actions; No returns to 3D view, Yes proceeds to slice
- Refresh plate thumbnails after the panel switch so previously-generated
  thumbnails are not left black

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:45:11 -04:00
SoftFever 3e4af2c723 WIP: Add native Wayland support for Linux (#13197)
* Add runtime display backend detection for Wayland support

Add LinuxDisplayBackend utility to detect X11 vs Wayland at runtime
using GDK_IS_X11_DISPLAY / GDK_IS_WAYLAND_DISPLAY macros. This is
the foundation for removing the forced GDK_BACKEND=x11 and enabling
native Wayland support.

- New files: LinuxDisplayBackend.hpp/.cpp with get_linux_display_backend(),
  is_running_on_wayland(), and is_running_on_x11()
- Propagate wxHAVE_GDK_X11 / wxHAVE_GDK_WAYLAND from FindGTK3.cmake
  as compile definitions to libslic3r_gui
- No-op on non-Linux platforms (returns Unknown / false)

* Fix Phase 1 code quality: pragma once, source ordering, static cache

* Make X11 initialization conditional for Wayland support

Remove the unconditional GDK_BACKEND=x11 force that blocked native
Wayland. Replace with conditional logic:

- EGL safety fallback: re-force X11 only when wxUSE_GLCANVAS_EGL is
  off and WAYLAND_DISPLAY is set, with a warning log
- XInitThreads() only called when DISPLAY is set (X11 in use)
- __GLX_VENDOR_LIBRARY_NAME only set when DISPLAY is present (GLX-specific)
- WEBKIT_DISABLE_COMPOSITING_MODE only set under XWayland (both
  DISPLAY and WAYLAND_DISPLAY present)
- Guard X11/Xlib.h include with __has_include for robustness
- Restore display validation to accept either DISPLAY or WAYLAND_DISPLAY

This is Phase 2 of the Wayland support plan.

* Fix Phase 2: safer EGL macro check, add clarifying comments

* Add GLAD2 library and replace GLEW linkage in build system

Set up GLAD2 as a static library to replace GLEW for OpenGL loading.
GLAD2 supports both GLX and EGL, which is required for Wayland support.

- Create src/glad/ with pre-generated GLAD2 sources (GL 4.6 compat)
- Add src/glad/CMakeLists.txt building glad as a static library
- Wire glad into src/CMakeLists.txt before libvgcode
- Modify libvgcode to use shared glad for GL path (keeps local copy
  only for GLES2/Emscripten) to avoid duplicate symbol conflicts
- Replace GLEW::GLEW with glad in libslic3r_gui link libraries

Note: GLEW is kept in deps for OpenCSG. Code migration from GL/glew.h
to glad/gl.h headers will follow in Phase 3B+3C.

* Fix Phase 3A+3D: libvgcode GLAD include, dead files, dlopen dep, OpenGL link var

* Migrate from GLEW to GLAD: replace headers and API calls across codebase

Replace all #include <GL/glew.h> with <glad/gl.h> across 49 source files.
Migrate GLEW API calls to GLAD equivalents:
- glewInit/glewExperimental -> gladLoaderLoadGL()
- GLEW_EXT_* / GLEW_ARB_* extension checks -> GLAD_GL_EXT_* / GLAD_GL_ARB_*
- Remove GLEW-specific EGL/GLX mismatch #error guards (not needed with GLAD)
- Replace unavailable EXT symbols with core GL equivalents in
  GLCanvas3D.cpp (GL_MAX_SAMPLES, glRenderbufferStorageMultisample,
  glBlitFramebuffer, GL_READ/DRAW_FRAMEBUFFER)
- Update log messages from glewInit to gladLoadGL

* Fix Phase 3B+3C: remove GLEW find, clean EXT symbols, update attribution

- Remove find_package(GLEW) block from root CMakeLists.txt since GLEW
  is no longer linked by any main application code
- Remove "glew" from SLIC3R_STATIC option description
- Replace all remaining EXT framebuffer symbols with core equivalents
  in render_thumbnail_framebuffer_ext and _rectangular_selection_picking_pass
- Update AboutDialog credits from GLEW to GLAD

* Enable EGL in wxWidgets and add runtime GLX/EGL selection for Wayland

- Set wxUSE_GLCANVAS_EGL=ON in wxWidgets build and Flatpak manifest
- Add PreferGLX() call on X11 sessions for driver compatibility
- Remove Phase 2 safety fallback (EGL is now always compiled in)
- Guard SwapBuffers against hidden canvases to prevent Wayland stalls

* Fix Phase 4: move PreferGLX to app startup, fix FPS counter guard

Move wxGLCanvas::PreferGLX() from OpenGLManager::create_wxglcanvas()
(static initializer) to GUI_App::on_init_inner() before any wxGLCanvas
is constructed. This prevents a race where SkipPartCanvas could trigger
wxGLBackend::Init() before the GLX preference is set. The new location
also adds explicit is_running_on_wayland() detection with a warning for
unknown backends.

Move increment_fps_counter() inside the IsShownOnScreen() guard so FPS
is only counted when a frame is actually swapped.

* Update GLFW from 3.3.7 to 3.4 for runtime Wayland/X11 backend selection

Replace the compile-time GLFW_USE_WAYLAND flag (which locked to a single
backend) with GLFW 3.4's GLFW_BUILD_WAYLAND + GLFW_BUILD_X11 flags that
build both backends and auto-select at runtime based on the available
display server. This enables the CLI thumbnail renderer to work on both
Wayland and X11 sessions without separate builds.

* wayland: Fix UI call sites that rely on global screen coordinates

On Wayland, wxGetMousePosition() returns (0,0) and SetPosition() is a
no-op for top-level windows. Fix the highest-impact call sites:

- GLCanvas3D: Use cached m_mouse.position from event handlers instead
  of wxGetMousePosition() + ScreenToClient() in get_local_mouse_position()
- Plater: Use event-relative coords via ClientToScreen(e.GetPosition())
  instead of wxGetMousePosition() in 3 leave-window handlers
- BBLTopbar: Use event.GetPosition() and FindToolByPosition() directly
  in mouse handlers instead of wxGetMousePosition()/FindToolByCurrentPosition()
- Search: Use focus-based dismiss logic on Wayland instead of
  wxGetMousePosition()-based rect checks in SearchDialog and
  SearchObjectDialog
- GUI_App: Skip SetPosition() in window_pos_restore() on Wayland where
  it is a no-op; still restore size and maximize state
- Button: Position tooltip relative to button widget via ClientToScreen
  instead of wxGetMousePosition()

* Fix SearchDialog Wayland dismiss: guard against search_line focus

* flatpak: Add Wayland socket permission for native Wayland support

* spec

* Fix crash on Wayland when wxWidgets lacks EGL support

Restore the safety fallback that forces GDK_BACKEND=x11 when wxWidgets
was not built with wxUSE_GLCANVAS_EGL=ON. Without this, the GLX backend
tries to access a non-existent X11 display on native Wayland, crashing
in wxGLCanvas::IsDisplaySupported() with SIGSEGV at offset 0xe4.

Also add a defense-in-depth guard in detect_multisample() that skips
the IsDisplaySupported call entirely on Wayland without EGL.

Root cause: deps/wxWidgets must be rebuilt after enabling EGL. The
compile-time check in OrcaSlicer.cpp detects the mismatch and falls
back safely.

* Fix EGL detection: use wxHAS_EGL instead of wxUSE_GLCANVAS_EGL

wxUSE_GLCANVAS_EGL is a CMake build option, NOT a C++ preprocessor
macro. The actual macro defined in wxWidgets setup.h is wxHAS_EGL.
All compile-time EGL checks were using the wrong macro, causing
the safety fallback to always trigger even with a properly built
EGL-enabled wxWidgets.

* Fix GL function pointers invalidated on Wayland/EGL

gladLoaderLoadGL() dlopen's libGL.so.1 to resolve GL function pointers
via dlsym, then immediately dlclose's the handle. On X11/GLX this is
fine because the GLX context keeps libGL.so mapped. On Wayland/EGL,
nothing else holds libGL.so open, so dlclose unmaps it and all function
pointers become dangling — causing SIGSEGV on the first GL call.

Fix: on Wayland, use gladLoadGL(eglGetProcAddress) which resolves
function pointers through the EGL loader without opening/closing
libGL.so.

* fix crash on start and various rendering issues

* fix crash on close

* small refactor

* move GPU selection to desktop file

* clean up a bit

* clean up more

* fix appimage error
2026-04-13 19:45:39 +08:00
SoftFever 2553d37236 cherry pick Linux specific changes from 2.3 (#13205)
- add a new mode to build in docker
- Improve AppImage
 1. fix  libbz2 soname differeence issue on appimage
 2. Downgrade to 22.04 for better compatibility
 3. improve appimage overall
2026-04-13 17:21:05 +08:00
Ocraftyone 3c1cba1849 Add persistent cookie storage for PrinterWebView on WebKitGTK (#13135) 2026-04-13 14:07:40 +08:00
Clifford GarwoodandClaude Sonnet 4.6 73b5b750c6 feat: iMEX multi-material warning badge, conflict dialog, and mode row UI
- Add warning badge (obj_warning.svg overlay) to the iMEX plate icon when
  a parallel mode is active alongside multi-material objects on the same plate
- Add has_imex_multimaterial_conflict() using get_extruders(true) so only
  filaments actually used on the plate are checked
- Move multi-material caution dialog from reslice() into on_action_slice_plate /
  on_action_slice_all so it fires exactly once per user action and does not
  disrupt GL thumbnail generation during Slice All
- Fix is_imex missing from p->config init key list so on_config_change()
  diff detection correctly triggers refresh_imex_icons()
- Defer imex_changed handling until after set_bed_shape() so m_shape is current
- Replace plain remove button with ScalableButton (imex_remove.svg) in mode rows
- Add EditGCodeDialog launch button per mode row for placeholder browsing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 00:10:03 -04:00
Clifford GarwoodandClaude Sonnet 4.6 9a87363044 feat: 4-tool support, primary row, zone sizing, and stability fixes
IMEXModesCtrl:
- Primary mode is now a non-deletable first row stored as sentinel
  "primary" in imex_mode_names; older configs load cleanly
- New rows default T0 → Primary when no tool assignment is stored
- Filter "primary" from plater popup/cycle list to prevent double entry
- imex_tools_per_gantry cap raised 2 → 4

Zone sizing:
- Zone width/height now based on active tool count only; inactive tools
  donate their bed share to active neighbors (fixes 4-tool layout)
- Active col/row maps (col_to_zone/row_to_zone) applied consistently
  across zone fills, collision strips, and primary zone box

GCodeViewer animation:
- Mirror position formula fixed: left-of-copy reflects across copy
  zone's left edge; right-of-copy reflects across right edge
  (T3 was rendering on top of T1)
- strip_width/row_strip_height use active counts, matching PartPlate

Stability:
- Early return in calc_imex_zones() when tool_states is empty; prevents
  OOB crash on new printer with stale process-preset mode name
- is_imex toggle in on_config_change calls refresh_imex_icons() so the
  plate mode icon appears without requiring a new project

GCode:
- Remove "primary" guard so Primary mode gcode field is emitted at
  start of print

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 19:08:57 -04:00
Clifford GarwoodandClaude Sonnet 4.6 0d73cd13ba refactor: move IDEX/IQEX settings from standalone tab into Multimaterial section
- Remove standalone IDEX/IQEX printer tab
- Add IDEX/IQEX Configuration and Parallel Modes sections to the
  Multimaterial page, gated behind is_imex
- Carriage config options hidden via toggle_options() when is_imex is off
- Custom widgets (layout combo, theme combo, modes ctrl) show/hide accordingly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 19:08:57 -04:00
Clifford GarwoodandClaude Sonnet 4.6 461c69c83e refactor: rename iXex → IMEX throughout; use IDEX/IQEX as user-facing label
- All config keys: ixex_* → imex_* (is_imex, imex_gantry_count, etc.)
- All C++ identifiers: IXexModesCtrl → IMEXModesCtrl, m_ixex_* → m_imex_*, etc.
- 3MF serialization key: ixex_parallel_mode → imex_parallel_mode
- UI strings: iXex → IDEX/IQEX
- SVG icons: plate_ixex_mode*.svg → plate_imex_mode*.svg
- Remove unused ixex_mode.svg

Breaking change for existing printer configs — acceptable pre-merge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 19:08:57 -04:00
2033e60052 Auto hide/show the ironing angle settings if the selected ironing pattern does not use the user specified angles (#11451)
Co-authored-by: yw4z <ywsyildiz@gmail.com>
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-04-09 19:23:09 -03:00
Clifford Garwood 2934b18d2a Merge remote-tracking branch 'upstream/main' 2026-04-09 00:22:06 -04:00
Clifford GarwoodandClaude Sonnet 4.6 f540cf87a8 fix: preserve iXex tool assignments across gantry count changes
- Add all_tool_states map to IXexModesCtrl Row, storing all tool
  assignments including those not currently visible due to grid size
- active_tools_string() now serializes from all_tool_states so
  off-screen assignments survive the round trip through a smaller grid
- Button clicks keep all_tool_states in sync with visible btn_states
- Display anchors to the gantry row containing the Primary assignment
  so reducing gantry count keeps the meaningful row visible rather
  than always defaulting to row 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 23:35:32 -04:00
Eldenroot 984178ac29 Add fallback when color was not specified (crash fix) (#13002) 2026-04-08 17:21:22 -03:00
yw4z a9741b5274 Improve readability of "Only one wall on.." parameters (#13121) 2026-04-08 17:18:46 -03:00
Miki 71a84def1a Fix single-instance IPC by preserving "OrcaSlicer" suffix in Win32 title (#13017) 2026-04-08 17:15:43 -03:00
Ian Bassi d715dfc966 Wiki link fix and update (#13152) 2026-04-08 15:06:28 -03:00
goofoo afc3756843 fix+feat: Snapmaker U1 — 5 bug fixes and 0.6mm / mixed-nozzle profiles (#12244 #12390 #12652 #12073 #12797 #11424) (#12824) 2026-04-08 12:08:35 +08:00
Danielle WheelerandSoftFever 1b2ff12868 Add Flashforge Artemis Printer Profile (#11902)
* add Artemis configuration files

* updated config files

* undo testing on a different nozzle

* matched settings to FlashPrint5

* lowered nozzle temperature

* renamed filed to match Flashforge.json file

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-04-08 11:32:21 +08:00
Clifford GarwoodandClaude Sonnet 4.6 5fa6480f61 feat: per-plate iXex mode selection with undo, dark mode icons, and menu fixes
- Add per-plate iXex mode icon to the plate toolbar (normal, hover, dark, dark-hover SVG variants)
- Left-click cycles through available modes; right-click shows a popup menu with all modes as radio items
- Mode changes are recorded in the undo/redo snapshot system
- Fix double context menu: suppress EVT_GLCANVAS_PLATE_RIGHT_CLICK and EVT_GLCANVAS_RIGHT_CLICK when the iXex icon popup was already shown
- Remove ixex_parallel_mode combo from Print Settings > Other > Special mode (superseded by per-plate icon)
- Remove dead code: refresh_ixex_mode_combo(), m_ixex_mode_combo member, related Tab reload hook
- iXex mode persisted in 3MF project files via existing plate metadata serialization

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 23:25:38 -04:00
Clifford f25a433ec7 Merge branch 'OrcaSlicer:main' into main 2026-04-07 22:50:22 -04:00
Ian Bassi f685891b6e Fix: Wiki + Wall loop direction desc (#13143)
* Combine brims wiki fix

* Typo fix
2026-04-07 16:06:20 -03:00
Vovodroid e1d6cb1764 Remove "auto" wall direction option (#6193)
Remove "auto" wall direction
2026-04-07 22:33:32 +08:00
Rodrigo Faselli 208ebfc703 Combine brims option (Prusa style brims) (#12343)
* Union ex brims

Revert "Union ex brims"

This reverts commit bbc9a39faf318dc2df093eb2bdcebf19a4162fe9.

Update Brim.cpp

* dont repeat paths

* Update Brim.cpp

* multimaterial brim independiente

* Normal brim if is by object

* fix print order

* cleaning 1

* cleaning 2

* Normal brim if multimaterial on first layer

* fix artifact

* combine_brim optional

refactoring

* refactoring gcode.cpp

* refactoring brim.cpp

Update Brim.cpp

* Remove multimaterial first-layer check for brims

Stop detecting extruders used on the first layer and remove the is_multimaterial_first_layer guard. Simplify can_combine_brims to only consider combine_brims and whether printing is ByObject, allowing brims to be combined across extruders unless printing by object or combine_brims is disabled. Cleans up unused code and simplifies brim-generation conditions.

* Remove material specification from unified brim comment

* Update PrintConfig.cpp
2026-04-07 22:24:46 +08:00
Clifford GarwoodandClaude Sonnet 4.6 167211c85c refactor: rename ixex_carriage_width → ixex_nozzle_clearance; fix strip math and carriage box visualization
Config key rename (breaking for saved profiles — call out in PR):
  ixex_carriage_width_x/y → ixex_nozzle_clearance_x/y
  Labels updated to "Nozzle Clearance X/Y" with consistent tooltips
  describing the measurement as nozzle-to-collision-side-edge distance.

Strip math fix:
  Previously halved the clearance value (× 0.5) under the assumption
  the nozzle was centered in the carriage. The measurement is now the
  literal nozzle-to-edge distance, so the × 0.5 factor is removed.
  The collision strip width now equals the configured value directly.

Carriage box visualization (GCodeViewer):
  - Add per-carriage box_offset_x/y so the nozzle marker sits at the
    physically correct edge of the footprint box rather than centered.
  - X: zone-based by default (nozzle at inner edge facing bed center).
    Copy secondaries inherit the primary's X orientation (same movement
    direction). Mirror secondaries use the collision-side edge.
  - Y: always row-based regardless of copy/mirror mode. Gantry is always
    behind the nozzle (high-Y); front-row primaries with a back-row
    secondary override to place nozzle at the low-Y edge.
  - Fix stale mesh bug: GLModel::init_from() is a no-op when already
    initialized. Call reset() before init_from() so mesh rebuilds
    correctly when nozzle clearance values change in config.
  - Remove m_ixex_toolhead_box_dims (was the now-unnecessary cache key).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:57 -04:00
Clifford GarwoodandClaude Sonnet 4.6 a9ad17cea2 fix: route iXex collision zones through m_unselected for effective exclusion
params.excluded_regions flows into libnest2d PlacementConfig.m_excluded_regions
which is declared but never consumed by the NFP placer — the field is dead code.
m_unselected is the working path: it becomes fixeditems that are preloaded as
physical fixed obstacles in the NFP computation, same as the wipe tower.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:57 -04:00
Clifford GarwoodandClaude Sonnet 4.6 1cacc6d02d fix: exclude iXex collision strips from auto-arrange placement
Auto-arrange now injects the carriage collision zones as hard excluded
regions (is_virt_object) when an iXex parallel mode is active, using the
same BoundingBoxf3 data already stored for rendering and violation checks.
Objects will no longer be placed in the mirror-edge danger strips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:57 -04:00
Clifford GarwoodandClaude Sonnet 4.6 b9f7148080 fix: constrain auto-arrange to iXex primary zone when parallel mode is active
Adds std::optional<BoundingBoxf> m_ixex_primary_zone_box to PartPlate,
populated by calc_ixex_zones() alongside the existing secondary/collision
zone geometry. The new ixex_primary_zone() getter calls ensure_ixex_zones()
so callers always get fresh data. ArrangeJob::process() replaces the
full-bed bedpts with the primary zone corners when the getter returns a
value, so auto-arrange no longer drops objects into the bed center.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:56 -04:00
Clifford GarwoodandClaude Sonnet 4.6 a3cac6c139 fix: remove iXex zone outline borders to eliminate aliasing flicker
The thin rectangular outlines around copy/mirror zones caused visible
aliasing and appeared to flash during interaction. Removed the border
GLModel, its build code in calc_ixex_zones(), the render block, and
the unused border field from IXexTheme.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:40 -04:00
Clifford GarwoodandClaude Sonnet 4.6 185b7084d2 fix: null m_ixex_mode_combo in TabPrint::clear_pages() to prevent dangling pointer crash
Same class of bug as the TabPrinter fix: clear_pages() destroys all
page widgets but didn't null m_ixex_mode_combo, causing a SIGSEGV in
refresh_ixex_mode_combo() when load_current_preset() ran after a
page rebuild (e.g. triggered by Plater::reset()).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:39 -04:00
Clifford GarwoodandClaude Sonnet 4.6 f4808ae7ba fix: avoid capturing C array in lambda for ixex_tool_layout combo
Arrays cannot be captured by value in C++ lambdas; replaced with a
static local declared inside the event handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:39 -04:00
Clifford GarwoodandClaude Sonnet 4.6 5297417518 fix: remove phantom phys_row variable reference from iXex button layout comment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:39 -04:00
Clifford GarwoodandClaude Sonnet 4.6 a03d2cd566 fix: restore info log level in two commented-out PartPlate log lines
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:39 -04:00
Clifford GarwoodandClaude Sonnet 4.6 e786fabb6a fix: restore info log levels in PartPlate accidentally raised to warning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:57:39 -04:00
Clifford Garwood 1e56b65146 feat: Add iXex parallel printing support for IDEX and IQEX printers
Introduces first-class parallel printing (copy/mirror modes) for printers
with multiple independent X-axis carriages. Branded iXex (independent X
extruder), targeting Klipper firmware with a firmware-agnostic design.

- PrintConfig: new printer options declaring iXex capability and geometry
  (is_ixex, ixex_gantry_count, ixex_tools_per_gantry, carriage dims,
  tool layout, and per-mode name/role/gcode arrays)
- Preset: iXex keys registered in printer and process preset option lists
- Tab: IXexModesCtrl visual grid editor in Printer preset tab; mode
  dropdown in Process → Others tab; clear_pages() nulls iXex pointers to
  prevent dangling-pointer crash on preset save
- PartPlate: 2D zone visualization (active/dimmed/dividers) and
  placement-violation detection (has_ixex_placement_violations) that
  blocks slicing when objects fall outside the primary zone
- Plater: violation detection wired into update_background_process so
  the Slice button is disabled with an error notification on violation
- GCode: mode-activation G-code injected before machine_start_gcode
- GCodeViewer: multi-carriage toolhead markers in sequential preview,
  filament legend annotated with active carriage count and mode name
2026-04-06 14:57:39 -04:00
Sabriel-Koh b79d3e1701 Fix: generic filaments not showing on list (#13037) 2026-04-06 14:27:49 +08:00
Rodrigo Faselli 7d21cf78c7 💥Fix crash when return from assembly mode linux (#13091)
* Fix return from assembly linux

* Tie deferred callback to canvas lifetime and add shutdown guards

Use m_canvas->CallAfter instead of wxGetApp().CallAfter to ensure the callback is only executed if the canvas is still alive.
Add early returns if wxGetApp().is_closing() is true before accessing plater or the 3D canvas, reducing the risk of use-after-free during application shutdown.
Addresses feedback regarding potential UI teardown race conditions.

* copilot suggestion

* Use local reference to wxGetApp() in Return button callback

Replace multiple calls to wxGetApp() with a single local reference
to improve readability and avoid redundant function calls.
2026-04-06 14:06:48 +08:00
Kevin LynaghandSoftFever 5ba71e1198 Allow printing even if nozzle info isn't reported by firmware. (#12814)
* Don't assume 0.4mm nozzle; format as "unknown" if not defined.

* Skip nozzle diameter and hardness checks if nozzle info unknown.

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-04-06 12:40:36 +08:00