Add continuous constant-wall spiral mode (thick-wall spiral vase) - #15527
Open
steventaitinger wants to merge 8 commits into
Open
Add continuous constant-wall spiral mode (thick-wall spiral vase)#15527steventaitinger wants to merge 8 commits into
steventaitinger wants to merge 8 commits into
Conversation
Port of the multi-wall spiral vase feature from the OrcaSlicer fork (staitinger/OrcaSlicer feature/multi-wall-vase) to PrusaSlicer 2.9.6. New print option spiral_vase_wall_count (default 1 = classic single-wall spiral vase, N = N concentric walls, 0 = automatic: fill the sliced wall completely, works for tapered shapes such as cones). Each layer's concentric perimeters are morphed into one continuous extrusion: flat rings at constant radius joined by short smoothstep transitions (~0.05 in of arc), uniformly re-spaced outer->inner so the wall is solid for any geometry, beads deposited ~15% wider than the ring pitch so adjacent rings fuse. Gap fill is suppressed in this mode (the morph covers the whole wall). Layers print flat at nominal Z with only the final ~1.27 mm ramping up to the next layer, alternating direction per layer so the ramp connects end-to-start. Slicing keeps Regular mode (inner holes preserved) when wall count != 1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Where the outer-going and hole-going offset fronts meet, the leftover strip can survive as a degenerate self-crossing loop: huge perimeter, tiny net area. It passed the nested/concentric filter (small area, centered centroid), and morphing against its angularly scrambled points lerped straight through the center, turning one layer into a criss-cross solid disc (cone test, layer 42). Gate each candidate loop on its isoperimetric quotient A/P^2 relative to the outer contour: scale-invariant, characterizes shape only. Real concentric rings keep or raise the outer's quotient as they shrink; bowtie slivers collapse to a few percent -> rejected at 35%. Also adds env-gated diagnostics (MULTIWALL_DEBUG=<layer>) dumping the collected loop radii for a layer. Verified: cone at wall count 0 slices 128/128 ring layers, 2 retractions, zero radial jumps, full wall span top to bottom. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nder) Replace the uniform +15% bead-overlap flow with locally-correct, globally-exact volume control. The morphed spiral is now a single ExtrusionMultiPath whose segments carry coverage-based flow: - flat ring arcs: one ring pitch of coverage - ring-step diagonals: pitch * cos(theta) (parallel diagonals sit closer perpendicular to their direction; constant flow over-deposited ~6% at the seam) - the final ring's seam arc: coverage tapered with the same smoothstep the incoming diagonal used, matching the narrowing leftover strip (constant flow re-deposited a full bead on the diagonal's tail - the seam blob that stacked into a ridge) Then all segment flows are scaled so the layer extrudes EXACTLY wall_area * layer_height, the sliced wall's true volume (wall area threaded from surface.expolygon into make_multiwall_spiral). Verified on the cone regression: total extruded volume 8928.9 mm3 vs sum of per-layer slice-area targets 8919.8 mm3 = +0.10%. Every layer still a clean ring, 2 retractions, seams intact. Also: MULTIWALL_DEBUG=-1 dumps per-layer volume normalization data. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tions The Z climb to the next layer is now its own 'elevator' arc on the midline between the last two rings - half a pitch inside the wall - so the climbing bead never sits on or squishes out of the interior or exterior surface. It runs backward along the seam arc, cancelling the path's angular advance so each layer's exit lands exactly on the next layer's entry. Flow tapers 0 -> pitch with the climb (nothing where it overlaps the current layer, a full bead into the next layer's seam interstice, whose own departure diagonal deposits ~nothing there). Both surface rings (first and final) are now complete undistorted circles every layer. Step-overs are straight linear diagonals spaced pitch*cos(theta) - the smoothstep S-curve diverged at its ends and left diamond voids down the seam. All segment boundaries share exact points (including the one-sample closing chords), so the whole part prints as ONE uninterrupted extrusion. Fixes an out-of-bounds read (fin[M]) in the elevator chunking when the seam arc quantized below 4 samples - garbage first points caused a retract + wild travel on most layers. Verified on the cone: 0 retractions in the entire 128-layer print, travels reduced 1550 -> 252 (all sub-mm seam hops, no retract), every layer a clean ring, total extruded volume +0.10% of the sliced wall volume. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace spiral_vase_wall_count and its forced-settings plumbing with a single checkbox: constant_wall_spiral. No other settings are touched. Every layer whose cross-section qualifies as a fully axisymmetric wall (exactly one hole, both boundaries circular by isoperimetric quotient, concentric within a quarter of the wall thickness) is printed as one continuous spiral of concentric rings: as many perimeters as fit, no gap fill, no infill, exact volumetric flow, in-wall elevator at the layer change. Layers that do not qualify (side holes, ports, non-round sections, solid regions) print with the regular profile settings - the per-layer spiral enable machinery disables the vase transform for them automatically (>1 perimeter entity or fills present). Classic spiral vase behavior is restored to upstream semantics (normalize/validate/slicing mode/GUI dialog). The classic generator is forced while the mode is on so qualifying layers can take the spiral path. Verified one-flag slice of the cone with stock defaults: every layer a ring, 2 retractions total (print start), all other travels sub-mm. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the in-plane climbing arc (micro-helix) with the straightforward design: the layer ends on a pad at the seam interstice midline, and the SpiralVase post-processor inserts a single straight VERTICAL extruding move there - one layer height up, with enough extrusion for a nozzle-diameter column bead. The climb is inserted immediately after the layer's last extrusion so the column lands exactly on the pad, before any trailing travel. The next layer's paths arc around the column: any point within one bead width of it is projected onto a bead-width-radius circle, giving smooth sub-mm entry/exit arcs around the elevator. Also: first layer now gets the full spiral treatment (skirt/brim/ bottom-solid gates bypassed for constant-wall mode - the flat-layer design coexists with them), and the elevator handshake is geometry-aware in both directions (climb only into a continuing spiral layer, discount the departure only when the layer below climbed here), fixing the first-layer flaps and transition artifacts. Verified: 127/127 ring layers, 0 retractions, total volume +0.1%, vertical column at the pad every layer change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…topology - Step-overs shrink from 1.27mm straight ramps to short tangent S-arcs (cosine blend, ~2 pitches of arc, one-wall-width corner radius) that curve around the elevator column. - All rings re-anchored to +X of the shared centroid after re-spacing, so the seam and the vertical elevator columns stack at the same angle on every layer instead of wandering with the chained alignment. - Path topology closed: elevator top -> MIN-flow connector (arcs around the column via the avoidance projection) -> first ring full circle from flat0 -> departure taper (full flow restored: the elevator is a point column, not a strip) -> rings -> final ring + closing taper -> pad at the anchor -> vertical climb. Every junction shares exact coordinates: mid-layer jumps eliminated. - Absolute-E mode: restore the E counter (G92) after the injected climb so following moves don't read as micro-retracts. Verified: 127/127 rings, 0 retractions, all travels <= 0.6mm (unretracted sub-bead hops), volume +0.08% incl. elevator columns. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The elevator column now sits ON the wall line itself - the climb happens at the end of the final ring (outer wall / inner wall, alternating with the radial direction), like a perfectly vertical stacked vase seam. The interstice pad, midline connector, and avoidance-arc projection are all gone. Odd layers now run the OPPOSITE rotation around the part (boustrophedon): each layer starts exactly where the previous layer's vertical climb ended and prints its whole spiral in one direction. This cancels the per-layer angular advance of the seam window, so the seam stays put with NO backward positioning move (the extruding 'wipe' at the layer start) and no connector at all. Verified: 127/127 rings, 0 retractions, volume +0.08%, remaining layer-boundary hops <= 0.73 mm unretracted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Continuous constant-wall spiral mode
Adds an optional one-click print mode for round, constant-wall shapes (tubes, cones, and other axisymmetric walls): a single checkbox, Continuous constant-wall spiral, under Print Settings → Layers and perimeters → Vertical shells.
It generalizes classic Spiral Vase to walls that are more than one perimeter thick, while keeping the seamless, retraction-free character of spiral vase.
What it does
For every layer whose cross-section is a fully axisymmetric wall (exactly one hole; both boundaries circular by isoperimetric quotient; concentric), the layer's concentric perimeters are morphed into one continuous extrusion:
wall_area × layer_height— locally coverage-corrected (flat arcs vs. step-overs) and globally normalized, so the wall is neither over- nor under-extruded.Layers that are not a constant circular wall (side holes, ports, non-round sections, solid tops/bottoms) fall back to the regular settings automatically — the per-layer spiral-vase enable machinery disables the transform for them. No other print settings are modified by the mode.
Implementation notes
process_classic); the morph replaces the collected loops with oneExtrusionMultiPath, so the existing per-layer spiral-vase gating inGCodeGeneratorstill sees a single perimeter and treats the layer as spiral.SpiralVase::process_layer_multiwall(flat layer + one vertical extruding move at the seam), with an absolute-EG92restore so following layers don't read as micro-retracts.spiral_vase_wall_countis superseded by the singleconstant_wall_spiralbool in the final commit; validation/normalization/slicing-mode adjustments are gated on the mode.Testing
Built and sliced locally against
version_2.9.6. On a tapered-cone regression (25 mm tall, ~3 mm wall, 0.2 mm layers): every layer slices as a clean concentric-ring wall, 0 retractions across the whole print, and total extruded volume within +0.1% of the sliced wall volume. A headless G-code analyzer (per-layer radius sweep, continuity, volumetric audit) was used to verify.This is offered for consideration and feedback — happy to iterate on API/UX (option naming, mode placement) or split it into smaller reviewable pieces if that's preferred.
🤖 Generated with Claude Code