Commit Graph
627 Commits
Author SHA1 Message Date
Valerii Bokhan 1882861a98 Feature: Small perimeters speed for supports (#13459) 2026-07-03 17:27:57 -03:00
Clifford Garwood 17584e2ffb Merge remote-tracking branch 'upstream/main' 2026-06-30 01:55:14 -04:00
raistlin7447 03568b5200 fix: slicing fails when filament_end_gcode uses layer_z with a wipe tower (#14462)
WipeTowerIntegration::append_tcr processed filament_end_gcode with only
layer_num in its placeholder config, so a filament_end_gcode referencing
{layer_z} could not be evaluated and slicing aborted. This affects any
multi-filament print that routes tool changes through the prime/wipe tower
(for example a support filament on a Bambu printer); the same macro works
in machine_end_gcode and on the non-wipe-tower set_extruder path, which
both define layer_z.

Set layer_z to tcr.print_z, the value this function already provides to its
change_filament_gcode and tcr_rotated_gcode placeholders.

Fixes #10119
2026-06-30 09:12:12 +08:00
Clifford GarwoodandClaude Opus 4.8 4677c79e18 Merge upstream/main into iXex PR branch (#13086)
Catches the iXex/IDEX branch up to upstream main (44 commits). One
content conflict resolved:

- src/libslic3r/Print.hpp: kept upstream's default-initialized
  m_origin {0,0,0} alongside our m_imex_slice_offset member.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 12:02:29 -04:00
SoftFever 14e572db5f Add nozzle flow variant & make some options multi-variant (#13712)
# Description

Port BBS per-extruder config variants toggle, thanks Bambu!

Also fix invalid num error when resetting multi-variant filament
overrides.

TODOs:

- [x] Make more configs multi-variant (such as speeds)
- [x] Add flow variant (normal/high flow) combo box
- [x] Add botton to sync config to other variant


# Screenshots/Recordings/Graphs

<img width="846" height="1494" alt="image"
src="https://github.com/user-attachments/assets/47abf053-f5b8-4c86-ac0b-c0323ed8b242"
/>

<img width="1478" height="1189" alt="707420e5be01c30af3e6ede1f3dc9b67"
src="https://github.com/user-attachments/assets/11268712-da65-42ab-9cb8-3cede7790a5c"
/>

<img width="1478" height="1189" alt="81d5d3877f4d5bf9dccd44d7f0b30aa7"
src="https://github.com/user-attachments/assets/cda5ea51-07c3-48fc-bfbb-1428dca14e26"
/>


## 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 #10336
2026-06-28 22:30:40 +08:00
Ioannis Giannakas 0e4928f200 Introduce minimal chamber temperature field (gcode chamber_min_temperature (#14340)
Introduce minimal chamber temperature field (gcode chamber_min_temperature)
2026-06-27 13:27:01 +01:00
Clifford GarwoodandClaude Opus 4.8 c5d0cdbcff Merge upstream/main into iXex PR branch (#13086)
Catches the iXex/IDEX parallel-printing branch up to upstream main
(102 commits). Two content conflicts resolved:

- src/libslic3r/Preset.cpp: s_Preset_printer_options — kept upstream's
  new "use_3mf" key and our iMEX printer-capability/mode keys.
- tests/fff_print/test_gcodewriter.cpp: upstream revived the disabled
  suite (#14196), dropping the obsolete [.]-tagged lift() test and its
  config_lift_unlift.ini; kept their set_speed + z_hop tests and appended
  our 10 per-firmware set_pressure_advance/set_temperature scenarios.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 23:29:35 -04:00
Noisyfox 7d0fd272b5 Merge remote-tracking branch 'upstream/main' into dev/extruder-toggle-wip
# Conflicts:
#	src/libslic3r/GCode.cpp
2026-06-24 18:22:32 +08:00
Kiss LorandandSoftFever 045179150f Refactor skirt/brim + bugfixes related to them (#14333)
Refactor skirt and brim ownership and emission flow

Refactor skirt and brim generation around a common object/group
ownership model.

Skirts and brims are now emitted as a coordinated preamble
(skirt -> brim -> object) instead of being generated and emitted
through multiple independent code paths.

Changes:
- Fix repeated skirt emission caused by the previous skirt state
  tracking logic.
- Restore local skirt/brim ordering for per-object skirts in
  By Layer mode.
- Emit brims together with their owning object or object group.
- Handle combined brims independently from skirt grouping.
- Handle draft shields through the same ownership model as skirts.
- Fix draft shield generation when skirt height is zero.
- Generate draft shields after brim geometry is known, preventing
  draft shields from overlapping brims.
- Reject unsafe grouped per-object skirt configurations in
  By Object mode.
- Remove legacy skirt emission paths and state-management
  workarounds.

Support brim generation remains unchanged.

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-24 15:48:31 +08:00
Noisyfox d13958ac54 Emit max value of machine limit among used extruders 2026-06-24 14:16:13 +08:00
SoftFever ca388f2d9e Merge branch 'main' into pr/Noisyfox/13712 2026-06-22 10:56:11 +08:00
Kiss LorandandRodrigo Faselli 762e474433 Skirt overhaul (#14130)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-06-19 10:43:46 +08:00
Ian Bassi 514ab02525 Localizations refactor (#14254) 2026-06-18 09:13:51 -03:00
SoftFever 9eeb73b68b feat: Support 3MF as g-code (use_3mf option) (#14238)
* feat: add support for 3MF file format in printer configurations and export options

* fix file extension

* enable 3mf for X Max 4

* disable use_3mf for X Plus 4

* Fixed an issue where `label_object_enabled` was not properly propagated to 3mf

* enable exclude object for Max 4

* remove hardcoded use 3mf for flashforge, move them to the new printer profiles config
2026-06-17 15:39:40 +08:00
raistlin7447 5fafbb59fc Revive the disabled fff_print test suite (#14196)
* Fix null-deref and arranger bugs that gate headless slicing tests

export_gcode dereferenced a null result out-param, enum serialization
dereferenced a null keys_map, and get_arrange_polys left bed_idx unseeded so
the arranger dropped items. All only affect the headless test/CLI path.

* Fix the headless test harness and add G-code test helpers

Use the real arranger, fix temp-file handling with an RAII guard, and add
layers_with_role / max_z for inspecting sliced G-code.

* Re-enable the Model construction test

* Re-enable SupportMaterial tests and add an enforced-support test

* Re-enable and extend PrintObject layer-height and perimeter tests

* Re-enable Print skirt, brim, and solid-surface tests

* Re-enable and extend PrintGCode tests

Un-hide the basic scenario (dead-key fixes, reframes, trimmed trivia) and add
initial-layer-height, sequential-order, and null-result export tests.

* Re-enable and reframe the skirt/brim tests

Detect skirt/brim by G-code role comment instead of a sentinel speed, and
resolve the previously-unfinished skirt-enclosure test.

* Replace the stale lift()/unlift() test with a z_hop test

* Delete the stub and broken Flow tests
2026-06-14 17:42:53 +08:00
Rodrigo Faselli 6d9ab28e2d Revert "skirt before brims (combine brim bugfix)" (#14131) 2026-06-09 20:25:34 -03:00
Rodrigo Faselli 38ea91a6bb skirt before brims (combine brim bugfix) (#14126) 2026-06-09 17:14:30 -03:00
Clifford Garwood 62074b409d fix(gcode): skip ooze prevention for same-physical filament changes
Ooze prevention currently treats every toolchange as a transition between
independent hotends — the OLD filament's extruder cools to a standby
temperature (via standby_temperature_delta or the filament's
idle_temperature) before the change, and the NEW filament's extruder
ramps back up afterward. This is correct for IDEX/toolchanger setups
where the parked nozzle would drip otherwise.

For AFC/MMU lane swaps where the SAME physical extruder stays selected
(only the loaded filament changes), the cool-down → re-heat round trip
is pointless: same nozzle, same heater, just a different filament feeding
it. In-print this costs 30+ seconds per lane swap, and the AFC tip-form
sequence ends up running on a cooling extruder.

Gate the pre_toolchange call on physical_extruder_map: when both the old
and new filament index map to the same physical extruder, skip the
standby cool-down. post_toolchange is left untouched — its M109 to the
new filament's print temp is still emitted, so per-lane temperature
differences (e.g. PLA → PETG on the same AFC manifold) are still handled.

Note on pem sizing: the guard requires physical_extruder_map to be sized
to the filament count for the per-filament lookup to succeed. The option's
registered default is a single-entry [0], which is shorter than the filament
count on any multi-filament setup, so the bounds check fails and ooze runs
as before. The fix fires only on profiles that explicitly author pem to
match filament count (the AFC/MMU/toolchanger configs that actually encode
same-physical routing).

Behavior matrix:

| Config | pem | Ooze behavior |
|---|---|---|
| Single-extruder + SEMM | (any) | `init_ooze_prevention` already disables ooze. No change. |
| Single-extruder, no SEMM | (any) | Single filament, no toolchanges. N/A. |
| IDEX / Toolchanger | `[0,1,…]` per-filament | Cross-physical → ooze runs as before. |
| Vanilla AFC, SEMM=true | (any) | `init_ooze_prevention` disables ooze. No change. |
| Vanilla AFC, SEMM=false | `[0,0,…]` per-filament | Same physical → **ooze SKIPPED** (the fix). |
| Toolchanger + AFC | per-filament | AFC swaps skip, cross-physical swaps run. |
| Default pem `[0]` (1 entry) | shorter than filament count | Bounds check fails for filament index ≥ 1 → ooze runs as before. No-op for profiles that haven't authored a per-filament pem. |
| Empty pem | `[]` | Guard returns false → ooze runs as before. |

The guard depends only on physical_extruder_map; no machine-class check.
Any printer whose pem is sized to filament count and indicates multiple
logical slots routed to the same physical hotend benefits.
2026-06-08 03:13:44 -04:00
Clifford Garwood e502175030 Sync upstream main
124 upstream commits including CrealityPrint integration (added include
in Plater.cpp alongside the existing IMEXHelpers include), profile fixes
and version bumps (#14084, #14085, Polymaker), CI artifact publishing,
test refactors (arachne walls test added; test_3mf/test_config/
test_gcodewriter content moved/removed upstream — IMEX test file
preserved as it is feedback-only), translations.
2026-06-08 01:26:33 -04:00
Ian Bassiandigiannakas ea35b9ce68 Divided filament for features (#14042)
* Implement legacy key handling to address possible profile issues following semantic change of per feature filaments

* Reimport base

* Fix inner wall

* Profiles update

---------

Co-authored-by: igiannakas <ioannis@my-spot.co.uk>
2026-06-05 20:45:43 +08:00
Kiss Lorand 1b72dbf6fa Fix inconsistent ordering of support base outline and fill (#11761)
* Preserve support base outline/fill order

Honor no_sort when emitting support toolpaths to keep outline-first order.
Group tree support base paths (including lightning) into per-area no_sort collections to prevent interleaving across islands.
Keep lightning layer lookup side-effect free.

* Tag Orca specific changes

Tag Orca specific changes vs. Bambu using the comment //ORCA: . This helps when reviewing merge commits from upstream Bambu so we don't end up causing regressions when pulling in commits from upstream
2026-06-02 14:39:27 +08:00
Kiss Lorand 6a26284ba6 Fix air filtration gcode emitted even if not not supported by the printer (#13868)
* Fix air filtration gcode emitted even if not not supported

- do not emit air filtration gcode if not supported by the printer
- removed redundant  "add_eol" parameter from "set_exhaust_fan()" function
2026-05-31 12:11:40 +08:00
Clifford Garwood ed6c608dc2 Sync upstream main
Pulls latest upstream fixes (Default filament option #13887, SEMM
multi-extruder crash #13896, linux wxstring crash #13925, Polymaker
profiles, et al.).
2026-05-29 09:50:18 -04:00
Clifford Garwood 9b3c1b87f4 Sync upstream main
Includes nozzle-diameter guards for printers without nozzle info (#13255,
now landed upstream) and manual-calibration nozzle mismatch fix (#13882).

# Conflicts:
#	src/slic3r/GUI/GCodeViewer.cpp
#	src/slic3r/GUI/GLCanvas3D.hpp
#	src/slic3r/GUI/Tab.cpp
2026-05-29 01:49:42 -04:00
mrmeesandClaude Opus 4.7 67b9f07655 Fix built-in placeholders missing from custom G-code and output filenames (#13892)
* fix: restore version placeholder in custom G-code

PlaceholderParser sets "version" in its constructor, but Print::apply() calls clear_config() which wipes it. Unlike timestamp/user (restored during G-code export), version was never restored, so [version]/{version} threw "Variable does not exist" in custom G-code while working in output filenames.

Re-set version after both clear_config() calls so it resolves everywhere.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: resolve timestamp and user placeholders in File header G-code

file_start_gcode is processed via print.placeholder_parser() directly, before the G-code parser integration copy that restores timestamp/user. As a result {timestamp}, {year}..{second} and {user} threw "Variable does not exist" in the File header G-code field while working in Machine start/end G-code.

Inject fresh timestamp and user into the file_start_gcode config so they resolve, matching the other custom G-code fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: expose initial_extruder and extruded_*_total placeholders in output filenames

PrintStatistics exposed initial_tool (not its documented alias initial_extruder) and total_weight/extruded_volume (not the documented extruded_weight_total/extruded_volume_total). Filename formats using the missing names failed with "not a variable name".

Add the missing aliases to PrintStatistics::config() and placeholders().

Fixes #12436

Fixes #10708

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:29:16 +08:00
mrmeesandClaude Opus 4.7 4000445345 Fix total_toolchanges placeholder being 0 without a wipe tower (#13895)
* fix: populate total_toolchanges without a wipe tower

total_toolchanges is documented as available while change_filament_gcode (and the wipe-tower toolchange flow) is evaluated, but it was sourced only from WipeTowerData::number_of_toolchanges, which stays -1 (clamped to 0) when no wipe tower is generated. Manual filament swaps and toolchanger/IDEX setups without a wipe tower therefore always saw total_toolchanges = 0 in custom G-code and output filenames, despite real tool changes occurring -- breaking the placeholder's documented contract.

Add a tool-ordering fallback: when number_of_toolchanges < 0, count tool changes from the print's tool ordering (the transitions in the per-layer extruder sequence). Wipe-tower prints are untouched -- number_of_toolchanges >= 0 still wins -- so their reported count does not change.

Limitation: sequential (by-object) prints without a wipe tower leave Print::tool_ordering() empty, so total_toolchanges stays 0 there (unchanged from before).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:09:15 +08:00
Noisyfox bb9bc04996 Merge branch 'main' into dev/extruder-toggle 2026-05-21 15:42:38 +08:00
Ian BassiandSteve Scargall c5855db578 Line Type preview: Display distances and amount values (#13681)
* feat(viewer): Display travel distance and move count in G-code summary

This commit introduces a new feature that enhances the G-code viewer by displaying the total travel distance and the total number of travel moves in the 'Line Type' summary.

This provides users with more detailed statistics about their prints, helping them to better understand the printer's behavior and identify opportunities to optimize travel moves for faster print times.

This commit also fixes a critical bug in the G-code processor where the travel distance was being calculated incorrectly. The distance variable was not being updated for non-extruding travel moves, leading to inaccurate statistics. The calculation has been corrected to ensure it is performed for all relevant move types, resulting in accurate travel distance reporting.

* Subfix segments

kilo mega giga tera peta exa

* Add missing values

* Grams to Kilos and tons

* add distance

* Fix tool view

* Record and display seam distances

Track seam-related distances in print statistics and show them in the GCode viewer. Added total_seam_gap_distance and total_seam_scarf_distance to PrintEstimatedStatistics (with initialization). In GCode::extrude_loop the code now computes seam gap and scarf distances and accumulates them for external perimeters. GCodeViewer uses the summed seam distance when the Seams option is selected in the legend.

* Fix travel / wipe distances

* Update GCode.cpp

* Filament changes estimated time

---------

Co-authored-by: Steve Scargall <37674041+sscargal@users.noreply.github.com>
2026-05-21 13:49:43 +08:00
Noisyfox 15952edf4d Fix wipe_speed 2026-05-21 13:30:05 +08:00
Noisyfox 8a6573db19 Fix usage of most of the multi-variant parameters 2026-05-21 13:15:33 +08:00
1c8c7820c8 Initial attempt to make speed configs multi-variant
Co-authored-by: chunmao.guo <chunmao.guo@bambulab.com>
Co-authored-by: zhimin.zeng <zhimin.zeng@bambulab.com>
Co-authored-by: qing.zhang <qing.zhang@bambulab.com>
2026-05-21 09:04:27 +08:00
Noisyfox e87b0d57b4 Make inner_wall_speed multi-variant 2026-05-21 09:04:27 +08:00
Ioannis Giannakas d52d0a082d Option to always travel to wipe tower before Tx commands on multi-toolhead setups using type 2 tower (#13703)
* Option to always travel to wipe tower before Tx commands on multi-toolhead setups using type 2 tower
2026-05-17 20:46:08 +01:00
Clifford Garwood ab63789076 Merge remote-tracking branch 'upstream/main' into feedback
# Conflicts:
#	src/libslic3r/GCodeWriter.cpp
#	src/libslic3r/PrintApply.cpp
#	src/slic3r/GUI/Tab.cpp
#	tests/libslic3r/test_config.cpp
2026-05-13 00:57:36 -04:00
ec424fb674 Machine Input Shaping (#11202)
* Base IS Machine

* Toggle line

* Rebase

* Intento 1

* Wiki IS

* Flavorized

* Tooltips

* Calibration using the same list

* max

* Reorder JD validation

* Refactor set input shaping

* Calibrations IS

* Default values

* Axis

* Orca comments

* Rename input_shaping_enable to input_shaping_emit

Refactor all references of the input shaping configuration option from 'input_shaping_enable' to 'input_shaping_emit' across the codebase. This improves clarity by better reflecting the option's purpose of controlling whether input shaping commands are emitted in the generated G-code.

Restore DONT EMIT FOR KLIPPER

* Refactor input shaping option toggling logic

Simplifies and consolidates the logic for toggling input shaping related options in TabPrinter::toggle_options(). Uses a loop to handle enabling/disabling lines based on GCode flavor compatibility, and refines the conditions for toggling individual options.

* Improve input shaping option toggling logic in TabPrinter

* GrayOut Emit to gcode limits for klipper

* Typo

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Typo

* Skip Y input-shaper when type is Disable

If marlin2 and disabled it will be already disabled at X.

* IS expert

Co-Authored-By: SoftFever <softfeverever@gmail.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-05-11 19:38:40 +08:00
glowstab 9956ad5b48 X2D Support (#13388)
# Description

Adresses #13294 

- Adds the X2D printer definition, machine presets, process presets,
filament presets, BBL profile index entries, CLI config entries,
filament blacklist updates, and printer/load/calibration/cover assets.
- Updates dual-nozzle handling to use configured toolhead labels and
match Bambu X2D hotend placeholders.
- Adds X2D-specific wipe tower cooling placeholder support and 3MF
filament/nozzle change sequence metadata import/export plumbing.

# Note

I own a P2S and an X2D. That's all. I frankly have no idea if my changes
cause regression on other printers, and have no capability to test. I
know that for my X2D, which runs an AMS, .2mm nozzles, SuperTack, and in
LAN mode, this has been working without issue.

# Screenshots/Recordings/Graphs

<img width="606" height="380" alt="Dual nozzle control"
src="https://github.com/user-attachments/assets/0d1c1063-4621-4097-b97c-d739557bf18c"
/>

*Dual nozzle control*

<img width="726" height="260" alt="image"
src="https://github.com/user-attachments/assets/270355b7-ca67-4ca3-ad19-582b8f11411b"
/>

*Multi nozzle filament override*

<img width="416" height="202" alt="X2D Machine config and dual nozzle
support"
src="https://github.com/user-attachments/assets/6a5c07b2-0d20-4819-8f42-d60731313249"
/>

*X2D Machine config and dual nozzle support*

<img width="397" height="142" alt="Filament for Supports test prints"
src="https://github.com/user-attachments/assets/3c7546bd-0e27-4d56-89b7-d9ca18c976f9"
/>

*Filament for Supports has been used in over 20 hours of test prints*

<img width="210" height="263" alt="Left vs Right filament distinction"
src="https://github.com/user-attachments/assets/03322268-b669-4f14-8d77-c4d96843d219"
/>

*Left vs Right filament distinction*

<img width="557" height="327" alt="Custom filament mapping"
src="https://github.com/user-attachments/assets/c1c4396f-7359-474e-80bd-78fec22f9c82"
/>

*Custom filament mapping*

<img width="556" height="314" alt="Auto map"
src="https://github.com/user-attachments/assets/d83e3217-edce-4340-886e-043962003a30"
/>

*Auto map*

<img width="689" height="664" alt="LAN mode send print with X2D preview
and no errors"
src="https://github.com/user-attachments/assets/76009bbf-31d3-4a6c-979c-8643b487c824"
/>

*LAN mode send print with X2D preview and no errors, dual nozzle
selection*


## Tests

- 20 hours of dual-nozzle printing.
- 100% CTest tests passed
- Validated 208 changed JSON files.

<!--
> 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 #13294
2026-05-10 02:21:13 +08:00
Kiss Lorand a3f229f406 Fix extrusion of some support layers at wrong Z height (again) (#13460)
Fix extrusion of some support layers at wrong Z height

Fixes the issue that PR #12736 (github.com/OrcaSlicer/OrcaSlicer/pull/12736) reverted the changes of PR #13327 (github.com/OrcaSlicer/OrcaSlicer/pull/13327)
2026-05-03 23:36:02 +08:00
Kiss Lorand 0ee62a9662 Fix role-based fan speeds being lost on layer change (#13390) 2026-05-02 18:24:09 -03:00
Clifford Garwood 493a9e96d2 Merge remote-tracking branch 'upstream/main'
# Conflicts:
#	src/libslic3r/Preset.cpp
2026-05-02 01:17:02 -04:00
SoftFever 0f366ddff1 feat: Add Z Anti-Aliasing (ZAA) contouring support (updated) (#12736)
This PR supersedes #12225, which originally proposed this feature but
appears inactive.

The feature originated from work I developed earlier in
[BambuStudio-ZAA](https://github.com/adob/BambuStudio-ZAA), a private
fork of Bambu Studio

Compared to #12225, I updated the implementation for current upstream
and fixed the following issues:
 - fixed broken tests
 - removed references to nonplanar directory

Reviewers may want to compare against #12225 for earlier
discussion/context.

## Summary

Port of **Z Anti-Aliasing (ZAA)** from
[BambuStudio-ZAA](https://github.com/adob/BambuStudio-ZAA) to
OrcaSlicer.

ZAA eliminates visible stair-stepping on curved and sloped top surfaces
by raycasting each extrusion point against the original 3D mesh and
micro-adjusting its Z height to follow the actual surface geometry. The
result is visibly smoother domes, chamfers, and shallow slopes — without
post-processing.

## How It Works

1. The slicer runs normally, then a **posContouring** step processes
each layer
2. `ContourZ.cpp` raycasts every extrusion point vertically against the
source mesh
3. Each point's Z is adjusted to the mesh intersection, converting flat
`Polyline` paths into `Polyline3` paths with per-point Z coordinates
4. The G-code writer emits the adjusted Z values, so the printer follows
the true surface

## Configuration

Five new settings under **Print Settings > Quality**:

| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `zaa_enabled` | bool | off | Master enable/disable switch |
| `zaa_min_z` | float | 0.06 mm | Minimum Z layer height; controls
slicing plane offset |
| `zaa_minimize_perimeter_height` | float | 35° | Reduce perimeter
heights on slopes below this angle (0 = disabled) |
| `zaa_dont_alternate_fill_direction` | bool | off | Keep fill direction
consistent instead of alternating |
| `zaa_region_disable` | bool | off | Disable ZAA for a specific print
region/material |

## Key Changes

- **Core algorithm**: New `src/libslic3r/ContourZ.cpp` (~330 lines) —
raycasting engine
- **3D geometry**: `Point3`, `Line3`, `Polyline3`, `MultiPoint3` extend
existing 2D types
- **Arc fitting**: Templated to work with both 2D and 3D geometry
- **Pipeline**: `ExtrusionPath::polyline` changed from `Polyline` to
`Polyline3`; new `posContouring` step in `PrintObject.cpp`
- **G-code**: `GCode.cpp` writes per-point Z when `path.z_contoured` is
set
- **UI**: ZAA settings exposed in Print Settings > Quality panel
- **Documentation**: `docs/ZAA.md` with usage and implementation details

57 files changed, ~1800 insertions, ~200 deletions.

## Test Plan

- [ ] Load a model with curved top surfaces (sphere, dome, chamfered
box)
- [ ] Enable **Z contouring** in Print Settings > Quality
- [ ] Slice and verify G-code has varying Z values within contoured
layers
- [ ] Build on macOS (verified), test on Linux and Windows
2026-05-02 11:03:00 +08:00
yogihybo 699a11f75e Fix to raft checking logic for slow down layers (#13415) 2026-05-01 14:32:39 -03:00
Clifford Garwood b452a8a28f Merge remote-tracking branch 'upstream/main' into feedback 2026-05-01 01:30:40 -04:00
SoftFever 2957508b4a Fixed a bug where the scarf seam wouldn't work properly when ZAA was disabled. 2026-04-28 18:46:56 +08:00
SoftFever 9bc2eb7476 Merge branch 'main' into zaa 2026-04-28 16:57:02 +08:00
Clifford GarwoodandClaude Opus 4.7 0bb1cef78e feat(imex): polish UI per PR feedback + add parallel-mode safeguards
Felix14-v2 PR review feedback (https://github.com/OrcaSlicer/OrcaSlicer/pull/13086#issuecomment-4323696312)
plus the slice-time validation work that follows from his bug list.

UI polish:
- Capitalize "Primary" in display (right-click mode menu, plate tooltip).
  Sentinel stays lowercase for wire compatibility.
- Pre-slice-warnings checkbox now uses Orca's ::CheckBox so it matches the
  green toggle style of the rest of the IDEX/IQEX configuration page.
- DPI-scaled the IMEXModesCtrl (modes editor) sub-panels, button grid,
  text wraps, gcode textarea, and the ghost-tooltip swatch (imgui.scaled).
  Legend swatches sized to body-text height for visual balance.
- Primary mode tool buttons in the modes editor are now disabled (read-
  only): cycling roles on the IMEX-off mode is a no-op and confusing.
- Modes editor sub-panels now explicitly inherit the app's window-default
  dark colour so chromeless ScalableButtons don't render with a visible
  light box around their icons on GTK dark themes.
- Per-mode-line reset arrows in the modes editor: each row gets a small
  reset bitmap that snaps that row's name+tools+gcode triplet back to the
  saved preset's value. matches_config() guard on the page-level reload
  prevents the textbox-being-typed-into from being destroyed mid-keystroke.
- New View menu item "Show IDEX/IQEX Toolhead" — toggles the per-carriage
  footprint boxes during G-code preview playback. Gated to Preview tab +
  IMEX printer; backed by app_config so it persists.

Coordinated config migrations:
- imex_tool_layout and imex_viz_theme migrate from coString to coEnum
  (ImexToolLayout / ImexVizTheme). Existing wire format preserved so
  saved presets and 3MFs deserialize unchanged. Side-benefit: both now
  pick up standard Field rendering and so finally show reset arrows.

Slice-time safeguards (the validation half):
- imex_suppresses_bare_toolchange(parallel_mode, count): suppresses the
  slicer's bare T<n> at print-start in any IMEX parallel mode (the user's
  imex_mode_gcode + machine_start_gcode owns tool activation there). Mid-
  print T<n> emits normally — Print::validate blocks the configurations
  where mid-print T<n> wouldn't make sense. Applied to both code paths
  inside GCode::set_extruder (the long multi-extruder path AND the
  single-extruder path that fires when multiple_extruders=false).
- imex_multicolor_block_reason(): hard-stop validator returning a user-
  facing reason string when the active IMEX configuration can't physically
  support multi-color. Catches IDEX (1 tool/gantry), 2-tool-active IQEX
  (no within-gantry swap topology), and any MMU/AFC lane sharing among
  used filaments. Wired into Print::validate as a slice blocker, and into
  PartPlate::has_imex_multimaterial_conflict so the plater badge agrees
  with the slice block (no more false positives where the badge warns but
  the slice goes through).
- New imex_mode_types config option (parallel array to imex_mode_names)
  and imex_mode_type_for() helper. Mode-type tag drives behaviour: zones,
  ghosts, and validation interpret modes differently per type. Initial
  types: "primary", "copy", "mirror", "split". Split modes are explicitly
  designed for paired-gantry IQEX multi-color and bypass the gantry-pair
  check in imex_multicolor_block_reason (MMU sharing still blocks them).

Test coverage:
- New unit tests cover imex_suppresses_bare_toolchange (4 cases),
  imex_multicolor_block_reason (8 cases including IDEX, IQEX 2-/4-tool-
  active, MMU sharing, missing primary, Split type), and imex_mode_type_for
  (3 cases including legacy fallback). Total: 186 IMEX assertions across
  71 test cases, all passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-27 22:51:05 -04:00
Ian BassiandRodrigo Faselli a9cfcb9d5d Temp Tower Nozzle based adjustment (#12269)
* Nozzle based base

* Post adjustment adaptation

* Cut before resize

* Restore calibutils calib_temptue

* No direction

* Stepper

* Fix

* Layerheigth = 0.5 nozzle

over #12323

Co-Authored-By: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>

* Disable Precise Z height for calibs

---------

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
2026-04-26 17:20:40 +08:00
Clifford GarwoodandClaude Opus 4.7 41457635e9 test(imex): extract physical→logical helpers + cover them with unit tests
Three of the four IMEX physical-vs-logical fixes landed earlier on this
branch (fbc58d2a1d, fa048babeb, a38b95bf45, e11e7d46df) used inline
lambdas / direct loops to translate physical extruder indices to logical
filament slots.  No test coverage existed for the specific composition,
even though the underlying primitives (resolve_filament_for_head,
first_filament_for_physical_head) were tested.

Pull two patterns out of Plater.cpp and GCode.cpp into IMEXHelpers as
named helpers, then unit-test them:

  imex_primary_logical_from_objects(used_slots_1b, pem, primary_physical)
    Walks the plate's used filament slots (1-based) and returns the
    first one whose pem entry maps to the primary's physical extruder.
    This is what the warning's `logical_for_primary` now delegates to —
    moves the "look at object assignments, not pem first-routed default"
    behavior introduced in fa048babeb out of the lambda and into a
    separately-testable function.

  imex_secondary_logical_slots(active_physicals, primary_physical,
                               plate_head_filament_map, pem)
    Iterates IMEX active physicals, skips the one matching primary,
    resolves each remainder via resolve_filament_for_head (per-plate
    override + first-routed fallback), deduplicates, drops -1 entries.
    Replaces the inline loop in GCode::_do_export's is_extruder_used
    marking (a38b95bf45 + e11e7d46df).

10 new test cases in test_imex_helpers.cpp cover the cases that
correspond directly to bugs hit:

  imex_primary_logical_from_objects:
    - AFC primary picks the object's slot (the user's specific bug)
    - Multi-color AFC primary returns first input-order match
    - Direct extruder primary unambiguous (no MMU)
    - No object routed to primary returns -1
    - Empty inputs (no objects, empty pem)

  imex_secondary_logical_slots:
    - Copy mode skips primary, falls back to first-routed
    - IQEX 4-mode enumerates all three secondaries
    - Per-plate override wins over first-routed
    - Drops unrouted physicals + deduplicates
    - Only-primary-active returns empty

All [IMEX] + [Variant] + [3mf] regression: 166 assertions / 61 cases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 05:07:34 -04:00
Clifford GarwoodandClaude Opus 4.7 d41e0d09b4 fix(imex): skip primary in IMEX is_extruder_used marking
a38b95bf45 translated physical -> logical for IMEX active tools but used
resolve_filament_for_head for *all* active tools including the primary.
For the primary, that falls back to first_filament_for_physical_head —
which returns the FIRST logical slot routed to the primary's physical
extruder, not the slot the user actually assigned to the printing object.

On the user's Neo XP 0.6 (pem [0,0,0,0,1,2,3,3]) printing in copy mode
with the object on slot 2 (PLA dark grey):
  - tool_ordering correctly marks slot 2 (object's filament).
  - The IMEX-marking loop then *also* marked slot 0 (ABS) as the primary's
    "first-routed" slot — wrong: slot 0 isn't loaded, slot 2 is.
  - Start-gcode template emitted EXTRUDER=260 EXTRUDER2=235 EXTRUDER4=235;
    the ABS-temp emission for slot 0 was harmless noise in this macro
    design but conceptually bogus.

The primary's filament is already correctly covered by
tool_ordering.all_extruders() — that lists the slots the objects on the
plate are assigned to.  Skip the primary in the IMEX-marking loop using
the same pattern as the IMEX PA emission path at GCode.cpp:3265
(translate initial_extruder_id -> physical via pem, skip that physical).

Result on the user's setup post-fix:
  - is_extruder_used: slot 2 (object), slot 4 (T1's filament in copy).
  - Start-gcode emits EXTRUDER2=235 EXTRUDER4=235 — exactly two temps,
    one per active heater, with no spurious ABS bookkeeping.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 05:07:34 -04:00
Clifford GarwoodandClaude Opus 4.7 2b7f438887 fix(imex): translate physical→logical when marking is_extruder_used for IMEX active tools
is_extruder_used is a logical-filament-slot indexed bool array — start-gcode
templates use it as `is_extruder_used[N]` where N is a logical filament slot
(matches how the rest of the codebase consumes per-filament arrays like
filament_settings_id, nozzle_temperature_initial_layer, etc.).

`tool_ordering.all_extruders()` returns LOGICAL slots and was correctly
marking those. But the IMEX-secondary marking added in 5aa624b025 was
writing PHYSICAL extruder indices straight into the logical array, mixing
index spaces. On any printer with physical_extruder_map size > 1 (MMU/AFC),
this marks the wrong slots and misses the right ones.

Symptom on the user's Neo XP 0.6 (pem [0,0,0,0,1,2,3,3]) in copy mode
[0:P,1:C] with object on slot 2 (PLA):
  - tool_ordering marks slot 2 (correct: object's filament).
  - IMEX active = [0, 1] (physical T0, T1) → mistakenly marks logical
    slots 0 (ABS) and 1 (ASA), neither of which is used.
  - Slot 4 (PLA on physical T1, the actual filament that loads on the
    secondary in copy mode) is NOT marked.
  - Start-gcode template emits EXTRUDER=ABS_temp EXTRUDER1=ASA_temp
    EXTRUDER2=PLA_temp; no EXTRUDER4.
  - PRINT_START macro reads t4=0, skips heating extruder1 — T1 stays
    cold during the print.

Translate physical → logical via resolve_filament_for_head before marking
(per-plate imex_head_filament_map override consulted, with first-routed
fallback when no override is set). This matches what the firmware actually
loads on each carriage during the parallel-mode print, and what the rest
of the IMEX hot path (PA emission, layer-change temperature) already does.

Result on the user's setup post-fix:
  - is_extruder_used[2]=true (object), is_extruder_used[4]=true (T1 in copy).
  - Start-gcode emits 2 temps for the actually-used filaments.
  - extruder1 heats correctly to slot 4's temp before the print begins.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 05:07:34 -04:00
Clifford GarwoodandClaude Opus 4.7 d329fce6b0 Merge branch 'tests/imex-coverage' into feedback
Brings in the IMEX test coverage (PA per-firmware, Temperature per-firmware,
[Variant] expansion, 3MF round-trip, imex_pem_tool_for helper + tests, and
the cherry-picked variant-truncation regression test).

Resolution notes:
- Two GCode.cpp call sites for set_pressure_advance had divergent edits:
    * tests/imex-coverage rewrote them to use the new imex_pem_tool_for
      helper (commit c2492ccc47), eliminating the inline parallel-mode
      check entirely.
    * feedback replaced the literal "primary" with kImexPrimaryMode in the
      same lines (commit 085f5ccec8).
  Resolution: keep the helper-call form. The kImex change is moot on lines
  the helper replaces, and imex_pem_tool_for in IMEXHelpers.cpp is also
  updated to use kImexPrimaryMode for consistency with the rest of the
  codebase.

- Test test_3mf.cpp updated for upstream's load_bbs_3mf signature change
  (PR adds is_orca_3mf out-parameter between is_bbl_3mf and file_version).
  All three call sites in the new IMEX 3MF round-trip tests pass &is_orca
  in addition to &is_bbl.

Full regression post-merge:
  libslic3r:    143 cases / 48,553 assertions  (+10 cases from new tests)
  fff_print:     24 cases /    245 assertions  (+10 cases from new tests)
  sla_print:     21 cases / 14,100 assertions
  libnest2d:     14 cases /    488 assertions
  slic3rutils:    3 cases /      3 assertions

All tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 01:17:27 -04:00