mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-23 15:21:01 +00:00
# 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