This is meant to be the last 0.x release before 1.0, which is where the API settles down. If there's something you think should be fixed or reconsidered while breaking changes are still cheap, now is the time to file an issue.
Shape is now Geometry
Custom shapes now conform to Geometry2D and Geometry3D directly, so there's one geometry protocol instead of two parallel ones:
struct Bracket: Geometry3D {
var body: any Geometry3D {
Box([20, 10, 4])
.aligned(at: .center)
}
}Shape2D and Shape3D still work, but are deprecated in favor of Geometry2D and Geometry3D. Existing shapes keep compiling; only the protocol name in the conformance changes. Conforming to Geometry2D/Geometry3D directly is something earlier compilers rejected, so Cadova now requires Swift 6.3 (Xcode 26).
Lofting along a path
Loft is no longer limited to stacking cross-sections along Z. It can now follow any curve, using the same framing as Sweep:
Loft(along: path, pointing: .down, toward: .direction(.negativeZ)) {
Section(at: 0) { Circle(diameter: 12) }
Section(at: 40) { Rectangle(8) }
Section(at: 90) { Circle(diameter: 4) }
}SectionreplacesLoft.Layeras the way to define a cross-section. Its position is a distance along the path, measured as arc length, and it also accepts a range or aatRelative:offset from the previous section.layer(z:),layer(zOffset:)andLoft.Layerare deprecated in favor ofSection.LayerTransitionis nowLoft.Transition.- Path-following initializers require an explicit
pointing:/toward:pair. There's no default that works for both horizontal and vertical paths, soswept(along:)without them is deprecated. - The plain
Loft { ... }initializer is unchanged and still produces an untwisted vertical stack.
Additions
twisted(by:per:)twists at a fixed rate per unit of height, independent of the geometry's bounding box, anchored at z = 0. The existingtwisted(by:)still spreads a total angle over the full height.Evaluateis a standalone version ofevaluating(_:)for reads that aren't anchored to a receiver, such as geometry captured from an outer scope, or several unrelated geometries at once.
Documentation
- New guides: Transformations, Cutting & Splitting, Bending & Deforming, Extrusion & Revolution, Measuring, Repetition & Patterns, Curves & Paths, Designing for 3D Printing, and Anchors & Tags. Several existing pages were revised and illustrated.
Bug fixes
Arcwith a negative radius produced a mirrored sector with a real area instead of empty geometry.- 2D shapes with degenerate sizes now report an area of zero rather than a bogus value.
- Fixed an inverted emptiness check on curve subcurves.
- Empty items in a
Stackno longer consume spacing as if they had size. - Decomposing geometry no longer reports empty pieces as components.
- Trimming empty geometry no longer goes through mesh evaluation.
Renames
readPoints,readSamplesandreadMetricsare nowreadingPoints,readingSamplesandreadingMetrics.resizingandextendingare nowresizedandextended.readToleranceandreadOperationare deprecated. Use@Environment(\.tolerance)and@Environment(\.operation)instead.filled(), deprecated since 0.4.3, has been removed. UsefillingHoles().