Files
OrcaSlicer/localization/i18n
SoftFever f92f75e0fa Feat: Add multiple and 3D bed exclusion volumes (#13777)
# Description

This PR adds opt-in, height-aware exclusion volumes to OrcaSlicer,
including multi-nozzle handling, object and generated-geometry
validation, final G-code collision checking, and travel rerouting.

It grew from the original object-placement prototype into a
collision-aware slicing pipeline with documented limitations. The
central compatibility decision is that Orca's existing
`bed_exclude_area` keeps its historical meaning, while the new
`bed_exclude_volumes` setting explicitly enables the stronger
collision-aware behavior.

<img width="935" height="707" alt="Travel paths routed around exclusion
volumes"
src="https://github.com/user-attachments/assets/22925e5c-a3b1-4c26-be1a-8a89d9970cb5"
/>

Related issues: #5922, #10579, #10638 and #12774.

## Why this is useful

The existing 2D exclusion area prevents object placement in areas such
as the filament-cutter corner on Bambu printers. It cannot describe low
bed clips, raised tool docks, camera arms, flying-gantry hardware, or
other obstacles that occupy only part of the printer's Z range.

Treating every existing area as a physical motion obstacle would also be
unsafe for compatibility: some printers deliberately move into their
excluded material area. This PR therefore separates the two concepts
rather than changing the meaning of existing profiles.

| Setting | Purpose | Existing motion affected? |
| --- | --- | --- |
| `bed_exclude_area` | Existing bed-fixed material/placement keep-out |
No G-code checking or travel rerouting |
| `bed_exclude_volumes` | Shared 3D collision volumes |
Object/generated-material checks, G-code validation and travel rerouting
|
| `extruder_bed_exclude_volumes` | Per-extruder 3D collision volumes |
Same collision behavior, resolved for the active physical nozzle |

Bed areas and collision volumes are additive. A printer can retain an
existing cutter/material keep-out while adding separate physical
collision volumes. Belt printers retain the existing projection of bed
areas onto the tilted belt surface; collision volumes remain in model
coordinates.

## Configuration and syntax

`bed_exclude_volumes` accepts one or more polygonal prisms:

```text
XxY,XxY,...
```

defines a full-height collision volume.

```text
REGION|REGION|REGION
```

defines multiple independent volumes.

```text
ZMIN..ZMAX;XxY,XxY,...
```

defines a volume active only across that Z range. Either Z bound may be
omitted:

```text
..10;20x20,40x20,40x40,20x40
30..;20x20,40x20,40x40,20x40
```

For example:

```text
20x0,45x0,45x18,20x18|8..22;115x20,145x20,145x48,115x48
```

defines one full-height volume and one volume active from Z=8 mm to Z=22
mm. Z ranges are validated and clamped against the configured printable
height, and decimal parsing is locale-independent.

The CLI exposes the same distinction:

```text
--bed-exclude-area
--bed-exclude-volumes
```

Existing scripts using `--bed-exclude-area` retain the original polygon
format and behavior.

## Backward compatibility and migration

- Existing profiles and projects using only `bed_exclude_area` keep its
material/placement keep-out meaning; they do not implicitly enable
collision-volume checking or travel rerouting.
- Stock printer motion is not checked or rerouted against bed areas.
This is important for machines that deliberately enter an excluded
material area during cutting or loading.
- The new syntax is stored under separate config keys, so an older Orca
build does not try to deserialize a volumetric string as the existing
point-list option.
- In **Printer settings → Basic information → Printable space**,
**Excluded bed area** remains a normal editable field with Orca's
standard reset controls. **Toolhead collision volumes** is a separate
field directly below it. There is no Convert/Copy button and neither
setting clears the other.
- A bed-area polygon can be manually copied into the collision-volume
field to describe a full-height physical obstacle. Pasting volume syntax
into the bed-area field instead prompts for confirmation before adding
it to the appropriate volume definitions. The saved bed area, existing
volumes and selected nozzle mode are preserved; cancelling leaves them
unchanged.
- If a user does not configure the new volume keys, the new G-code
checker, rerouter, support trimming and nozzle-specific brim behavior
remain inactive.

This gives existing profiles a stable compatibility boundary while
allowing users and maintainers to migrate deliberately to full collision
checking over time.

## Multi-nozzle behavior

For multi-nozzle printers, the collision-volume mode selects one of
three behaviours. In individual mode, each extruder's definition is
edited on its own Extruder settings page. These modes apply only to
collision volumes; the excluded bed area stays shared and bed-fixed.

Collision volumes support three modes:

<img width="549" height="441" alt="Exclusion volume behavior selector"
src="https://github.com/user-attachments/assets/6ca8c2e2-d00e-4b32-9b12-bfbff0928966"
/>

### Shared

Every physical nozzle uses the same collision-volume definition.

<img width="2353" height="1633" alt="Shared exclusion volumes"
src="https://github.com/user-attachments/assets/96fe938b-07b4-4cd9-b587-e31f2ebba5f8"
/>

### Toolhead-relative (nozzle offsets)

The shared definition is treated as relative to the toolhead. Orca
derives the other nozzles' collision regions using their configured XY
offset from the reference nozzle. This is useful where the same physical
carriage must avoid an obstacle but its position changes when a
different offset nozzle prints at the same model coordinate.

<img width="1084" height="803" alt="Toolhead-relative exclusion volumes"
src="https://github.com/user-attachments/assets/e0790ee4-68b5-444f-90ac-22a5eba05eec"
/>

### Individual per extruder

Each physical extruder/nozzle has its own independent volume definition.
This supports machines whose valid region differs by tool and cannot be
derived from a simple nozzle offset.

<img width="1123" height="761" alt="Independent exclusion volumes for
three extruders"
src="https://github.com/user-attachments/assets/c6404ceb-9958-4df8-93ed-5ff2ac7dc658"
/>

Object validation resolves logical filament assignments to the physical
nozzle or nozzles that may print the object, including automatic Bambu
mapping. If an object may use several nozzles through painting,
feature-level assignments, modifiers, support or interface material, the
complete object is conservatively checked against every relevant
nozzle's volumes.

## Object validation and 3D preview

Object collision detection uses a cheap XY/Z broad phase followed by an
exact mesh-versus-prism test. The exact test:

- Avoids rejecting an object whose XY shadow overlaps a raised volume
while its real mesh remains clear.
- Detects normal surface crossings.
- Detects a volume completely enclosed inside a solid model.
- Respects object-instance and model-volume transforms.
- Separates the collision decision from optional preview-mesh
generation.

When a collision is found, Orca reports the relevant extruder where
possible and renders the intersecting model surface in red. The bed
preview shows a neutral grey footprint, a thin nozzle-colored ownership
border where appropriate, and a translucent 3D prism when a nearby
object makes the volume relevant. Raised volumes keep their ownership
outline on the bed rather than floating at their starting Z.

<img width="578" height="534" alt="Red model and exclusion-volume
intersection preview"
src="https://github.com/user-attachments/assets/d409f574-1790-48e5-b4a3-703273439954"
/>

Single-nozzle/shared geometry remains visually neutral; nozzle colors
are used when they convey distinct tool ownership.

The default automatic preview limits the translucent 3D geometry to
nearby object height to avoid obscuring the workspace. **View → Show all
collision volumes** displays the complete configured Z ranges, including
on an empty bed. Its default shortcut is **Ctrl+Shift+V**
(**Command+Shift+V** on macOS), and it can be changed in the shortcut
settings. Orca remembers this application-level display preference
independently of printer presets; it does not change collision checks or
slicing.

## Arrange and Fill Bed

Arrange and Fill Bed receive Z-aware, nozzle-aware obstacles, so an
object may occupy a footprint belonging only to another nozzle or pass
below a raised volume when its height permits it.

- Existing objects remain obstacles when Fill Bed creates new copies.
- Convex volume footprints are passed through accurately.
- Orca's current libnest2d path supports convex NFP obstacles only, so
non-convex volumes use a documented conservative bounding box until
convex decomposition is implemented.
- Orca's existing final alignment and normal unplaced-item behavior are
retained.

<img width="1097" height="846" alt="Fill Bed with multiple tools and
exclusion volumes"
src="https://github.com/user-attachments/assets/8c0ee5cf-624b-42a6-b57a-13c73400ac5c"
/>

## Brim and support generation

When collision volumes are enabled, object and support brims are clipped
against the relevant first-layer volume footprints before their final
extrusion paths are generated. Brim ownership is retained so touching
object and support brims cannot be merged and silently reassigned to a
nozzle whose volume they intersect. Established bed-edge and bed-area
brim clipping remains unchanged when collision volumes are not
configured.

<img width="1139" height="770" alt="Object and support brims clipped
around nozzle-specific volumes"
src="https://github.com/user-attachments/assets/2913ff31-53e4-4e43-8b27-1afba7e3bafb"
/>

Normal support and raft polygon categories are trimmed against the
relevant volumes over each support layer's actual vertical slab.
Support-material resolution accounts for explicit support/interface
tools, “current filament” behavior, alternating material layers,
automatic physical-nozzle mapping, support brims, and shared support
geometry.

TreeSupport3D receives active exclusion geometry during branch planning
so its existing avoidance machinery can steer branches around obstacles
rather than merely cutting finished paths.

## Final G-code collision validation

The final emitted G-code is checked as a safety backstop after slicing.
The checker tracks:

- The active physical nozzle and its XY offset.
- Absolute and relative XY/Z motion.
- Travel, extrusion and other parsed motion types.
- Tool selection and physical/nozzle mapping.
- Explicit motion in start, filament-change and tool-change G-code.
- Coordinate resets and common `G28` forms, including bare, spaced,
compact and parameterized axis selections.

Material keep-outs from `bed_exclude_area` are deliberately ignored by
the motion checker. Only explicit collision volumes constrain motion.

If Z is genuinely unknown, the check is conservative across all relevant
heights and the warning identifies that fact and includes the relevant
G-code line. The artificial first segment that the preview draws from
`(0,0)` is not treated as a real machine move.

## Travel rerouting

Generated travel moves are rerouted around active collision volumes when
a valid route exists.

Routing is:

- Aware of the travel's actual Z slab and planned lift/Z-hop.
- Resolved for the active physical nozzle.
- Constrained so any detour vertices added by Orca remain inside the
printable bed.
- Able to accept firmware-established start/end points on or beyond the
nominal bed edge.
- Revalidated before the replacement path is emitted.

The implementation covers ordinary generated travels, the first
generated move after start G-code, and moves following physical or
same-nozzle filament changes. Explicit movement commands in custom
start/tool-change G-code update the tracked position so the next
generated travel begins from the correct point without defeating Orca's
post-toolchange Z restoration.

Obstacle geometry is cached by extruder and active Z-region set, with
bounding-box rejection before expensive polygon work. Clear travels
therefore avoid repeatedly unioning and offsetting the same obstacles.

If no safe route can be found, Orca leaves the original move for the
final checker to report rather than emitting an assumed-safe detour.
Extrusion paths are validated but never rerouted.

<img width="1286" height="706" alt="Travel rerouting from start G-code
across multiple Z-aware volumes"
src="https://github.com/user-attachments/assets/a68cd98f-5576-4f78-af43-697e9f687a9b"
/>

And here is an example of independent nozzle travel rerouting:
<img width="2532" height="876" alt="image"
src="https://github.com/user-attachments/assets/28b0c26e-59d6-42b9-a64f-4c2205c4ea3f"
/>


## Testing and review status

Targeted Catch2 coverage now includes:

- Bed-area/volume parsing, validation, confirmed paste handling,
additive behavior and CLI options.
- Belt-surface projection of bed areas through both static and dynamic
region resolution, including the reported cube positions, with collision
volumes left unprojected.
- Shared, toolhead-relative and individual per-extruder resolution.
- Physical-nozzle and filament mapping.
- Exact object intersection, including fully enclosed prisms and
transformed instances.
- 3MF persistence.
- Arrange behavior for convex and non-convex obstacles.
- Brim bed-boundary and volume clipping regressions.
- Support and interface-material masks across support polygon
categories.
- G-code motion classification, coordinate tracking, homing forms and
tool selection.
- Safe travel rerouting, Z-aware activation, nozzle selection, off-bed
firmware endpoints and failure cases.

The reviewed `929beaee15` revision passed the CI checks, and review
testing confirmed that the unit tests and earlier arrange, tool-change Z
restoration, support, brim and brim-ownership regressions still pass.
Stock-output comparisons covered 12 printers × 3 jobs plus 17 project
files and produced G-code identical to `main` when the new feature was
not configured.

The belt projection correction and its regression coverage are included
in the latest update. Please use the checks below for the current head's
build and test status; earlier successful runs do not substitute for
validation of a new revision.

Review also compared CLI output against `main` across stock printers and
multi-filament projects. The compatibility regressions found during that
review—including stock Bambu cutter motion, preset dirty state,
unintended bed-area brim/support changes, tool-change Z restoration,
stale post-change origins, arrange rejection, router cost, locale
parsing and bed-edge brim clipping—have been addressed.

## Known limitations and follow-up work

The implementation deliberately favors conservative safety. A false
positive or some unused build volume is preferable to emitting a
movement that may collide with the machine. Collision warnings are not
an automatic repair or a guarantee of safe output.

- Skirts and draft shields are not regenerated or detoured around
collision volumes. The final checker can report an intersection, but
producing a valid closed loop around internal obstacles while remaining
inside the bed needs a dedicated solution.
- Extrusion paths are checked but not rerouted.
- Spiral Z-hop's circular XY sweep is generated after the primary travel
route has been planned. That sweep is not currently rerouted; the final
G-code checker can report a collision, but does not repair it.
- Orca cannot infer movement hidden inside an opaque firmware macro. A
deterministic macro endpoint should be exposed with explicit `G90`/`G91`
and `G0`/`G1` motion in Orca's custom G-code so the following travel can
be routed from a known position. Movements inside custom G-code are
checked, but only the generated travel after them is rerouted.
- Negative model parts are not applied to the raw object-intersection
mesh, so geometry removed only by a negative part can produce a
conservative false positive.
- Multi-nozzle object validation applies every relevant nozzle's volume
to the complete object rather than only its visibly painted surface.
- Support shared by several instances uses a conservative union of
relevant plate-space exclusions.
- Support avoidance trims or steers generated geometry but does not
perform structural support re-planning. Support above a raised volume
may resume over a void; native tree-support paths not using
TreeSupport3D are not yet volume-aware.
- Raised-only collision volumes are not yet fully represented in
prime/wipe-tower placement validation; the final G-code checker remains
the safety backstop.
- Existing cross-object support-to-support overlap behavior is outside
this PR.
- “No tool selected” carriage-only exclusions are not represented by
Orca's current backend and remain a possible future extension.

## Origin

This work began with the [Muon3D
M1](https://www.youtube.com/watch?v=jBatFQpTM6g), whose notched glass
bed leaves usable print volume above a low obstruction. Upstreaming the
capability lets other printers describe low clips, raised docks,
toolchanger hardware and per-tool clearance limits without requiring a
permanent fork.

Thank you to everyone who tested the implementation, reviewed the
architecture, identified regressions and helped improve the test
coverage—especially the multi-tool and macOS testers. Further
real-hardware feedback remains welcome, but the current implementation
and compatibility behavior are ready to merge.

Harry Loud  
Muon3D
2026-10-22 22:04:40 +08:00
..