Skip to content

Commit d7c6202

Browse files
committed
Merge branch 'dev'
2 parents da69a7a + 8fcc872 commit d7c6202

37 files changed

Lines changed: 627 additions & 95 deletions

Sources/Helical/Bolt/Bolt.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
import Foundation
22
import Cadova
33

4+
/// A bolt with a head, threaded section, and optional point.
45
public struct Bolt: Shape3D {
6+
/// The screw thread specification.
57
public let thread: ScrewThread
8+
/// Nominal length of the bolt, measured according to convention for the head type.
69
public let length: Double
10+
/// Length of the unthreaded portion.
711
public let unthreadedLength: Double
12+
/// Diameter of the unthreaded portion.
813
public let unthreadedDiameter: Double
14+
/// The bolt head geometry.
915
public let headShape: any BoltHeadShape
16+
/// Optional drive socket in the head.
1017
public let socket: (any BoltHeadSocket)?
18+
/// Optional bolt point geometry.
1119
public let point: (any BoltPoint)?
1220

21+
/// Creates a bolt with the specified thread, dimensions, and head configuration.
22+
///
23+
/// - Parameters:
24+
/// - thread: The screw thread specification.
25+
/// - length: Nominal length of the bolt.
26+
/// - unthreadedLength: Length of the unthreaded portion.
27+
/// - unthreadedDiameter: Diameter of the unthreaded portion. Defaults to the thread's major diameter.
28+
/// - headShape: The bolt head geometry.
29+
/// - socket: Optional drive socket in the head.
30+
/// - point: Optional bolt point geometry.
1331
public init(
1432
thread: ScrewThread,
1533
length: Double,
@@ -28,6 +46,16 @@ public struct Bolt: Shape3D {
2846
self.point = point
2947
}
3048

49+
/// Creates a bolt with a chamfered point.
50+
///
51+
/// - Parameters:
52+
/// - thread: The screw thread specification.
53+
/// - length: Nominal length of the bolt.
54+
/// - unthreadedLength: Length of the unthreaded portion.
55+
/// - unthreadedDiameter: Diameter of the unthreaded portion. Defaults to the thread's major diameter.
56+
/// - leadinChamferSize: Size of the lead-in chamfer at the bolt tip.
57+
/// - headShape: The bolt head geometry.
58+
/// - socket: Optional drive socket in the head.
3159
public init(
3260
thread: ScrewThread,
3361
length: Double,
@@ -48,7 +76,14 @@ public struct Bolt: Shape3D {
4876
)
4977
}
5078

51-
// A bolt without a screw thread, for purposes where the thread is unimportant
79+
/// Creates a bolt without threads, for cases where thread detail is unimportant.
80+
///
81+
/// - Parameters:
82+
/// - solidDiameter: Diameter of the bolt body.
83+
/// - length: Nominal length of the bolt.
84+
/// - headShape: The bolt head geometry.
85+
/// - socket: Optional drive socket in the head.
86+
/// - point: Optional bolt point geometry.
5287
public init(
5388
solidDiameter: Double,
5489
length: Double,
@@ -99,6 +134,12 @@ public struct Bolt: Shape3D {
99134
recessedHead ? (length + headShape.clearanceLength) : (length - headShape.consumedLength)
100135
}
101136

137+
/// Creates a clearance hole sized for this bolt.
138+
///
139+
/// - Parameters:
140+
/// - depth: Hole depth. Defaults to the bolt length minus head consumption.
141+
/// - edgeProfile: Optional edge profile at the hole opening.
142+
/// - Returns: A clearance hole configured for this bolt.
102143
public func clearanceHole(depth: Double? = nil, edgeProfile: EdgeProfile? = nil) -> ClearanceHole {
103144
ClearanceHole(
104145
diameter: thread.majorDiameter,
@@ -107,6 +148,12 @@ public struct Bolt: Shape3D {
107148
)
108149
}
109150

151+
/// Creates a clearance hole sized for this bolt, optionally with a recess for the head.
152+
///
153+
/// - Parameters:
154+
/// - depth: Hole depth. Defaults to a depth that accommodates the full bolt length.
155+
/// - recessedHead: Whether to include a recess matching the bolt head shape.
156+
/// - Returns: A clearance hole configured for this bolt.
110157
public func clearanceHole(depth: Double? = nil, recessedHead: Bool) -> ClearanceHole {
111158
return ClearanceHole(
112159
diameter: thread.majorDiameter,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import Foundation
22
import Cadova
33

4+
/// A protocol defining the geometry and dimensions of a bolt head.
45
public protocol BoltHeadShape: Shape3D {
6+
/// Total height of the head.
57
var height: Double { get }
8+
/// Portion of the nominal bolt length consumed by the head, such as the countersunk portion.
69
var consumedLength: Double { get }
10+
/// Additional depth beyond the nominal bolt length needed to fully recess the head.
711
var clearanceLength: Double { get }
12+
/// Shape to subtract when creating a recessed hole for this head.
813
@GeometryBuilder3D var recess: any Geometry3D { get }
14+
/// Additional geometry to subtract from the bolt body.
915
@GeometryBuilder3D var negativeBody: any Geometry3D { get }
1016
}
1117

1218
public extension BoltHeadShape {
19+
/// Defaults to zero for heads that sit entirely above the mounting surface.
1320
var consumedLength: Double { 0 }
21+
/// Defaults to the full head height, for heads that sit entirely above the nominal length.
1422
var clearanceLength: Double { height }
23+
/// Defaults to empty geometry.
1524
var negativeBody: any Geometry3D { Box(.zero) }
1625
}

Sources/Helical/Bolt/Parts/Heads/CountersunkBoltHeadShape.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
import Foundation
22
import Cadova
33

4+
/// A conical countersunk bolt head that sits flush with or below the mounting surface.
5+
///
6+
/// Optionally includes a raised lens (dome) above the cone. The head height is included
7+
/// in the nominal bolt length.
48
public struct CountersunkBoltHeadShape: BoltHeadShape {
59
let countersink: Countersink
610
let boltDiameter: Double
711
let lensHeight: Double
812

913
@Environment(\.tolerance) var tolerance
1014

15+
/// Creates a countersunk head with the specified countersink geometry.
16+
///
17+
/// - Parameters:
18+
/// - countersink: The countersink geometry defining the cone angle and top diameter.
19+
/// - boltDiameter: The bolt's major diameter, used to calculate head height.
20+
/// - lensHeight: Height of the optional raised lens above the cone. Defaults to zero.
1121
public init(countersink: Countersink, boltDiameter: Double, lensHeight: Double = 0) {
1222
self.countersink = countersink
1323
self.boltDiameter = boltDiameter
1424
self.lensHeight = lensHeight
1525
}
1626

27+
/// Creates a countersunk head with the specified angle and dimensions.
28+
///
29+
/// - Parameters:
30+
/// - angle: The countersink cone angle. Defaults to 90°.
31+
/// - topDiameter: The diameter at the top of the cone.
32+
/// - boltDiameter: The bolt's major diameter, used to calculate head height.
33+
/// - lensHeight: Height of the optional raised lens above the cone. Defaults to zero.
1734
public init(angle: Angle = 90°, topDiameter: Double, boltDiameter: Double, lensHeight: Double = 0) {
1835
self.init(
1936
countersink: Countersink(angle: angle, topDiameter: topDiameter),

Sources/Helical/Bolt/Parts/Heads/CylindricalBoltHeadShape.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import Foundation
22
import Cadova
33

4+
/// A cylindrical bolt head, such as those used for socket head cap screws or button head screws.
5+
///
6+
/// Supports optional edge profiles on top and bottom, or a spherically rounded top.
47
public struct CylindricalBoltHeadShape: BoltHeadShape {
58
let diameter: Double
69
public let height: Double
710
let topEdge: EdgeProfile?
811
let bottomEdge: EdgeProfile?
912
let roundedTopRadius: Double?
1013

14+
/// Creates a cylindrical head with optional edge profiles.
15+
///
16+
/// - Parameters:
17+
/// - diameter: The head diameter.
18+
/// - height: The head height.
19+
/// - topEdge: Optional edge profile for the top edge.
20+
/// - bottomEdge: Optional edge profile for the bottom edge.
1121
public init(diameter: Double, height: Double, topEdge: EdgeProfile? = nil, bottomEdge: EdgeProfile? = nil) {
1222
self.diameter = diameter
1323
self.height = height
@@ -16,6 +26,12 @@ public struct CylindricalBoltHeadShape: BoltHeadShape {
1626
self.roundedTopRadius = nil
1727
}
1828

29+
/// Creates a cylindrical head with a spherically rounded top, such as a button head.
30+
///
31+
/// - Parameters:
32+
/// - diameter: The head diameter.
33+
/// - height: The head height.
34+
/// - roundedTopRadius: Radius of the sphere used to round the top.
1935
public init(diameter: Double, height: Double, roundedTopRadius: Double) {
2036
self.diameter = diameter
2137
self.height = height

Sources/Helical/Bolt/Parts/Heads/PolygonalBoltHeadShape.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import Foundation
22
import Cadova
33

4+
/// A polygonal bolt head, such as a hex head or square head.
5+
///
6+
/// Supports configurable side count, chamfered corners, and flat diameter for washer faces.
47
public struct PolygonalBoltHeadShape: BoltHeadShape {
58
let sideCount: Int
69
let widthAcrossFlats: Double
710
public let height: Double
811
let flatDiameter: Double
912
let chamferAngle: Angle
1013

14+
/// Creates a polygonal head with full control over geometry.
15+
///
16+
/// - Parameters:
17+
/// - sideCount: Number of sides (6 for hex, 4 for square, etc.).
18+
/// - widthAcrossFlats: Distance between opposite flat faces.
19+
/// - height: The head height.
20+
/// - flatDiameter: Diameter of the flat top surface after chamfering.
21+
/// - chamferAngle: Angle of the corner chamfer. Defaults to zero.
1122
public init(sideCount: Int, widthAcrossFlats: Double, height: Double, flatDiameter: Double, chamferAngle: Angle = 0°) {
1223
self.sideCount = sideCount
1324
self.widthAcrossFlats = widthAcrossFlats
@@ -16,6 +27,13 @@ public struct PolygonalBoltHeadShape: BoltHeadShape {
1627
self.chamferAngle = chamferAngle
1728
}
1829

30+
/// Creates a polygonal head with chamfered corners.
31+
///
32+
/// - Parameters:
33+
/// - sideCount: Number of sides (6 for hex, 4 for square, etc.).
34+
/// - widthAcrossFlats: Distance between opposite flat faces.
35+
/// - height: The head height.
36+
/// - chamferAngle: Angle of the corner chamfer.
1937
public init(sideCount: Int, widthAcrossFlats: Double, height: Double, chamferAngle: Angle) {
2038
self.init(sideCount: sideCount, widthAcrossFlats: widthAcrossFlats, height: height, flatDiameter: widthAcrossFlats, chamferAngle: chamferAngle)
2139
}

Sources/Helical/Bolt/Parts/Heads/ProfiledBoltHeadShape.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import Foundation
22
import Cadova
33

4-
// A bolt head shape for bolts without a head, such as set screws
5-
4+
/// A headless bolt shape for fasteners like set screws and threaded studs.
5+
///
6+
/// Applies an edge profile to the top of the bolt body rather than adding a head.
67
public struct ProfiledBoltHeadShape: BoltHeadShape {
78
let edgeProfile: EdgeProfile
89

10+
/// Creates a headless bolt shape with the specified edge profile.
11+
///
12+
/// - Parameter edgeProfile: The edge profile to apply to the top of the bolt body.
913
public init(edgeProfile: EdgeProfile) {
1014
self.edgeProfile = edgeProfile
1115
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import Foundation
22
import Cadova
33

4+
/// A protocol defining the geometry at the tip of a bolt.
45
public protocol BoltPoint: Shape3D {
6+
/// Portion of the nominal bolt length consumed by the point geometry.
57
var consumedLength: Double { get }
8+
/// Geometry to subtract from the bolt body to form the point.
69
@GeometryBuilder3D var negativeBody: any Geometry3D { get }
710
}
811

912
public extension BoltPoint {
13+
/// Defaults to empty geometry.
1014
@GeometryBuilder3D var body: any Geometry3D {}
15+
/// Defaults to empty geometry.
1116
@GeometryBuilder3D var negativeBody: any Geometry3D { }
1217
}

Sources/Helical/Bolt/Parts/Points/ProfiledBoltPoint.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
import Foundation
22
import Cadova
33

4+
/// A bolt point defined by an edge profile, with an optional dog point extension.
5+
///
6+
/// Common profiles include chamfers for standard bolt tips. A dog point adds a
7+
/// reduced-diameter cylindrical extension at the tip.
48
public struct ProfiledBoltPoint: BoltPoint {
59
let profile: EdgeProfile
610
let dogPointLength: Double
711

12+
/// Creates a bolt point with the specified edge profile.
13+
///
14+
/// - Parameters:
15+
/// - profile: The edge profile defining the point shape.
16+
/// - dogPointLength: Length of the optional dog point extension. Defaults to zero.
817
public init(profile: EdgeProfile, dogPointLength: Double = 0) {
918
self.profile = profile
1019
self.dogPointLength = dogPointLength
1120
}
1221

22+
/// Creates a chamfered bolt point.
23+
///
24+
/// - Parameters:
25+
/// - chamferSize: Depth of the chamfer.
26+
/// - dogPointLength: Length of the optional dog point extension. Defaults to zero.
1327
public init(chamferSize: Double, dogPointLength: Double = 0) {
1428
self.init(profile: .chamfer(depth: chamferSize), dogPointLength: dogPointLength)
1529
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import Foundation
22
import Cadova
33

4+
/// A protocol defining the drive socket geometry in a bolt head.
45
public protocol BoltHeadSocket: Shape3D {
6+
/// Depth of the socket recess.
57
var depth: Double { get }
68
}

Sources/Helical/Bolt/Parts/Sockets/Phillips.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import Foundation
22
import Cadova
33

4+
/// Standard Phillips driver sizes.
45
public enum PhillipsSize: Sendable {
6+
/// PH0
57
case ph0
8+
/// PH1
69
case ph1
10+
/// PH2
711
case ph2
12+
/// PH3
813
case ph3
14+
/// PH4
915
case ph4
1016
}
1117

0 commit comments

Comments
 (0)