Skip to content

Spike 1: bevel gear math port + Route A (ThruSections loft) #85

Description

@gsdali

Part of #84.

Goal

Port the bevel gear math from BOSL2 and build the first solid via Route A: a stack of
closed section wires fed to ThruSectionsBuilder. This is the faithful port. It mirrors what
BOSL2 does, with no booleans.

Time-box: half a day.

Question this spike answers

Does OCCT loft a stack of ~1100-point closed section wires into a valid solid, and how slow is it?

Scope

Straight/zerol teeth only (spiral = 0), no backing, no bore, single gear.

Math to port (all pure functions, low risk)

From gears.scad:

BOSL2 Line Notes
bevel_pitch_angle(teeth, mate_teeth, drive_angle) 4142 atan(sin S / (N_mate/N + cos S))
pitch_radius() 3928
outer_radius() 3985
_root_radius_basic() 4069
_base_radius() 4105
circular_pitch() / module_value() 3744 / 3803 pitch-system conversions
cone radii + face_width default 2518-2526 default_face_width = min(ocone_rad/3, 10*mod)

The 2D involute tooth profile can start from the existing implementation at
recipes/04-spur-gear/main.swift:38-48 rather than porting BOSL2's full
_gear_tooth_profile() (gears.scad:3366). The undercut, rounding and clipping machinery is
explicitly deferred (see #84).

Construction (Route A)

Port the per-slice transform stack at gears.scad:2546-2564:

scale(u) -> xrot(pitch_angle) -> back(u*pr) -> zrot(ang/sin(pitch_angle)) -> up(...)

where u = dist / ocone_rad. For each of slices+1 stations build one closed section wire
containing all teeth tooth profiles around the full circle, then:

let loft = ThruSectionsBuilder(isSolid: true, isRuled: false)
// addWire per slice

Relevant OCCTSwift API notes:

  • ThruSectionsBuilder(isSolid:isRuled:precision:), addWire(_:), build(), shape
  • checkCompatibility(_:) reorders wires to avoid twists; likely needed here
  • Upstream warns that mixing closed and open profiles causes a SIGSEGV inside OCCT
    (BRepFill_CompatibleWires). All our sections are closed, so keep it that way.

Acceptance criteria

  • A 36-tooth zerol bevel gear builds as a solid with isValid == true
  • Volume and bounding box recorded (sanity-checkable against the cone geometry)
  • Build wall-clock time recorded at 16, 28 and 36 teeth
  • Face count recorded. The prediction is ~5500 faces for 36 teeth, which would be a red
    flag for downstream filleting and STEP export
  • Findings written up in the issue: does it hold, and is the B-Rep usable or soup?

Prediction on record

Route A works and gets us a picture quickly, but produces a bloated B-Rep. Recording the numbers
is the point. They are the input to the Route A vs Route B decision in #86.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:spikeInvestigation / research, not a fix

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions