Skip to content

tomasf/Engage

Repository files navigation

Engage

Engage is a library for Cadova that generates precise 3D gear models. It supports spur, helical, herringbone, and ring gears, bevel gears, worm drives, and linear racks, with involute tooth profiles.

Installation

Integrate Engage into your project with the Swift Package Manager by adding it as a dependency in your Package.swift file:

.package(url: "https://github.com/tomasf/Engage.git", .upToNextMinor(from: "0.1.0"))

Then, import Engage where it's needed:

import Engage

Usage

Gear Profile

All gears are defined by a ToothProfile, which sets the module (tooth size) and involute parameters. Meshing gears must share the same ToothProfile and have compatible tooth traces.

// Module 2 = 2 mm per tooth on the pitch circle
let profile = ToothProfile.standard(module: 2)

Spur Gears

CylindricalGear(
    toothCount: 18,
    toothProfile: .standard(module: 2),
    thickness: 10
)
.bored(diameter: 6)
.chamfered(depth: 0.6)

Helical and Herringbone Gears

Helical gears carry load more smoothly than spur gears. A mating pair requires equal and opposite helix angles:

let driver = CylindricalGear(toothCount: 20, toothProfile: .standard(module: 2), toothTrace: .helical(angle: 20°), thickness: 15)
let driven = CylindricalGear(toothCount: 35, toothProfile: .standard(module: 2), toothTrace: .helical(angle: -20°), thickness: 15)

Herringbone (double-helical) gears cancel axial thrust entirely:

CylindricalGear(
    toothCount: 22,
    toothProfile: .standard(module: 2),
    toothTrace: .doubleHelical(angle: 20°),
    thickness: 16
)
.bored(diameter: 8)
.chamfered(depth: 0.8)

Ring Gears

Internal (ring) gears have teeth cut on the inside surface. The rimThickness parameter controls the wall thickness beyond the tooth roots:

RingGear(
    toothProfile: .standard(module: 2),
    toothCount: 44,
    thickness: 12,
    rimThickness: 4
)

Bevel Gears

Bevel gears transmit motion between intersecting axes. Use BevelGearPair to create a matched pair with automatically derived cone angles:

let pair = BevelGearPair(
    toothProfile: .standard(module: 2),
    toothCountA: 16,
    toothCountB: 20,
    shaftAngle: 90°,
    faceWidth: 12
)

let a = pair.gearA.bored(diameter: 6)
let b = pair.gearB.bored(diameter: 6)

a.translated(z: -a.apexDistance)
    .adding {
        b.translated(z: -b.apexDistance)
            .rotated(y: pair.shaftAngle)
    }

pair.gearA and pair.gearB return the individual gears with matching cone angles and opposite tooth-trace hands. Translate each by -apexDistance along its own axis to bring the apexes to the origin, then rotate gear B by the shaft angle.

Racks

A rack is a linear gear that meshes with a cylindrical pinion sharing the same ToothProfile.

Rack(
    toothProfile: .standard(module: 2),
    length: 100,
    height: 10,
    faceWidth: 12,
    toothTrace: .helical(angle: 20°)
)

Use displacement(for:rotation:) to compute how far the rack moves for a given pinion rotation.

Worm Drives

A worm drive is useful for large speed reductions in a compact layout. It pairs a Worm with a matching WormGear, both defined by the same WormSpec:

let spec = WormSpec(
    toothProfile: .standard(module: 2),
    starts: 2,
    pitchDiameter: 20
)

let wheel = WormGear(
    spec: spec,
    toothCount: 15 * spec.starts,
    thickness: 14
)
.bored(diameter: 10)
.chamfered(depth: 0.8)

wheel
    .aligned(at: .center)
    .translated(x: wheel.centerDistance)

wheel.matingWorm(length: 60)
    .bored(diameter: 6)
    .chamfered(depth: 1.0)
    .rotated(x: 90°)
    .aligned(at: .center)

Meshing Gears

Use centerDistance(to:) to find the correct axis spacing between any two mating cylindrical gears:

let pinion = CylindricalGear(toothCount: 16, toothProfile: .standard(module: 2), thickness: 10)
let gear   = CylindricalGear(toothCount: 40, toothProfile: .standard(module: 2), thickness: 10)

let distance = pinion.centerDistance(to: gear)

This works for external–external and external–internal pairs.

Involute Parameters

The default is a standard 20° involute. You can customize pressure angle and profile shift to avoid undercut on small pinions:

let profile = ToothProfile(module: 1.5, pressureAngle: 25°, profileShift: 0.3)

Behavior

Engage uses Cadova's tolerance environment setting to add manufacturing clearance between mating surfaces. Set a tolerance appropriate for your printer or manufacturing process:

.withTolerance(0.2)

Contributing

We welcome contributions. Feel free to open issues for feedback or suggestions and submit pull requests for improvements to the codebase.