-
Notifications
You must be signed in to change notification settings - Fork 1
Core Concepts: 1. Geometry
To use Cadova effectively, it helps to understand how it models geometry, how you build and combine shapes, and how to think about units and dimensions. If you’re familiar with SwiftUI, you’ll find that Cadova shares a similar declarative and compositional style.
At the heart of Cadova is the Geometry
protocol. This protocol is generic over a type called Dimensionality
, which distinguishes between 2D and 3D geometries. Most of the time, though, you’ll interact with the type aliases:
-
Geometry2D
– for two-dimensional geometry -
Geometry3D
– for three-dimensional geometry
When you create your own geometry types, you typically conform to either Shape2D
or Shape3D
, which conform to Geometry
, and implement the body
property:
struct MyThing: Shape3D {
var body: any Geometry3D {
// Your shape composition here
}
}
Just like View
in SwiftUI, a Shape
is a lightweight value type that acts as a description of how geometry should be built. Instances can be composed, transformed, passed around, and reused.
Cadova models are typically constructed by combining and transforming simpler shapes. You’ll use methods like:
.adding { ... }
.subtracting { ... }
.intersecting { ... }
…or their freestanding equivalents:
Union {
shapeA
shapeB
}
Intersection {
shapeA
shapeB
}
You can apply transformations to geometry:
-
.translated(x:y:)
,.translated(x:y:z:)
-
.rotated(x:y:z:)
(Euler angles) .scaled(...)
.transformed(...)
Cadova includes a standard library of primitive shapes: Circle
, Rectangle
, Sphere
, Box
, Cylinder
, and more.
To export your model, wrap it in a Model
:
Model("myModel") {
Cylinder(diameter: 5, height: 10)
.adding { ... }
}
The recommended way to build reusable components is by defining new types that conform to Shape2D
or Shape3D
. This makes your geometry composable and clean:
struct Bracket: Shape3D {
let size: Double
var body: any Geometry3D {
Box(x: size, y: size / 2, z: size / 4)
}
}
However, this isn't always necessary. Because geometries are just values, it's often fine to use functions that return geometry, especially for small or parameterized components. The system is flexible — use whatever feels practical.
Cadova supports both 2D and 3D workflows. You can:
-
Start in 2D (e.g.
Rectangle
,Polygon
) and:-
.extruded(height:)
into 3D -
.revolve(in:)
around the Z axis, over a range of angles (e.g.0°..<90°
) -
.swept(...)
along a 3D path
-
-
Model directly in 3D using primitives like
Sphere
,Box
,Cylinder
You can also convert 3D shapes into 2D via slicing or projection, but this is less common. The choice depends on your use case — both approaches are fully supported and can be combined as needed.