What & why
BOSL2 is the de-facto standard library for OpenSCAD, and gears.scad is one of its most
useful modules. This epic ports bevel gears specifically, as a time-boxed probe of whether
a wider BOSL2-style parametric part library is viable on top of OCCTSwift's B-Rep kernel.
Source under assessment: BelfrySCAD/BOSL2/gears.scad
(4762 lines), specifically function bevel_gear() at lines 2486-2650 and its supporting
_gear_tooth_profile() at lines 3366-3541.
Assessment findings
1. BOSL2's bevel gear is not a spherical involute. It takes a planar involute profile
and applies scale(u), where u is normalised cone distance, then rotates it onto the pitch
cone (gears.scad:2546-2564). That is the Tredgold-family approximation. We already have a
working planar involute in this repo at recipes/04-spur-gear/main.swift:38-48, so the
mathematically intimidating part is largely solved.
2. The effort profile inverts when moving to OCCT. Of the ~165 lines in bevel_gear(),
roughly 120 are VNF vertex/face index bookkeeping (teeth_top_faces, flat_top_faces,
backing_side_faces, vnf_join). All of that disappears, because
ThruSectionsBuilder(isSolid: true) caps for us. In exchange we inherit a new risk class:
B-Rep robustness. OpenSCAD cannot fail to make a polyhedron; OCCT can absolutely fail to make
a solid.
3. The spiral is a cutter simulation. cutter_radius and spiral place a circle whose arc
between the inner and outer cone radii is the lengthwise tooth trace (gears.scad:2528-2537),
a direct model of a Gleason face-mill. Roughly 15 lines of 2D trig, low risk.
4. Estimated Swift line count
| Layer |
Est. lines |
Risk |
Pitch/root/cone radii, bevel_pitch_angle, pitch conversions |
~80 |
Low, one-line formulas |
| Cutter-arc spiral trace |
~15 |
Low |
| Per-slice transform stack |
~20 |
Low |
| 2D involute tooth profile |
~40 (mostly exists) |
Low |
| Solid construction |
~60 |
The entire risk |
| Conical/flat backing, bore, handedness |
~30 |
Low, easier in OCCT than in BOSL2 |
The strategic constraint
BOSL2 is mesh-first (VNF to polyhedron); OCCTSwift is B-Rep-first. A literal port throws
away the reason to use OCCT at all: faceted polygon soup inside a .brep file,
unfilletable, exporting a poor STEP. If we port it literally we would be better off just
running OpenSCAD.
The target is therefore: port BOSL2's parameterisation and math, reimplement the
construction on B-Rep primitives.
Explicitly out of scope
- The attachment system (
anchor/spin/orient/reorient/named_anchor/attachable),
thousands of lines of BOSL2 infrastructure with no OCCT analogue. Replaced by explicit
reference frames (see the placement sub-issue).
$gear_steps and _inherit_gear_* special-variable inheritance, replaced by Swift default
arguments.
profile_shift / gear_dist / auto_profile_shift. Note bevel_gear calls
_gear_tooth_profile without profile shift (gears.scad:2538-2545), so these are not needed.
- BOSL2's undercut simulation, jaggy-stripping and self-intersection clipping
(gears.scad:3424-3529). Real engineering value, but v2 material. Start at the recipe-04-level
profile.
worm_gear and enveloping_worm, noted here so the trap is on record. BOSL2 generates these
by simulating hobbing, sweeping the worm through the blank and differencing over many
angular steps. In OCCT that is dozens of sequential booleans. If a BOSL2 port ever gets
ambitious, that is where it stops.
Licensing
BOSL2 is BSD-2-Clause (Copyright 2017-2019 Revar Desmera); this repo is LGPL-2.1.
Permissive into copyleft is compatible. Attribution must be preserved in the header of any
ported file. No conflict with the open-source-boundary policy, since BOSL2 adds no dependency,
only algorithms.
Deliverable
A docs page reproducing BOSL2 bevel_gear() Examples 1, 2 and 3 side by side with the
OCCTSwift renders and the Swift source that generated them.
The construction: Route C
Neither Route A nor Route B is the construction. Route C is. Recording this prominently because
this decision record lagged reality by one spike, and #87 built its spiral trace on Route A after
Route A had already been shown unusable.
Route A's math port is still the foundation and is reused throughout; only its construction
step was replaced.
Plan
The 2.0.0 dependency #108 implied is gone: Route C works on the pinned 1.17.0.
Why bevel is the right probe
It exercises the exact three capabilities that decide whether a broader gears.scad port is
viable: sampled analytic curve to wire, multi-section loft with scale and twist, and N-fold
boolean patterning. If all three hold, most of the gear family follows (rack is trivial, ring
and crown gears are easy). If the boolean patterning fails, we learn that BOSL2 ports here must
stay loft-only, itself a cheap and valuable finding.
Sizing: 1-2 days if Route A holds; 3-5 if Route B's booleans need fighting.
What & why
BOSL2 is the de-facto standard library for OpenSCAD, and
gears.scadis one of its mostuseful modules. This epic ports bevel gears specifically, as a time-boxed probe of whether
a wider BOSL2-style parametric part library is viable on top of OCCTSwift's B-Rep kernel.
Source under assessment:
BelfrySCAD/BOSL2/gears.scad(4762 lines), specifically
function bevel_gear()at lines 2486-2650 and its supporting_gear_tooth_profile()at lines 3366-3541.Assessment findings
1. BOSL2's bevel gear is not a spherical involute. It takes a planar involute profile
and applies
scale(u), whereuis normalised cone distance, then rotates it onto the pitchcone (gears.scad:2546-2564). That is the Tredgold-family approximation. We already have a
working planar involute in this repo at
recipes/04-spur-gear/main.swift:38-48, so themathematically intimidating part is largely solved.
2. The effort profile inverts when moving to OCCT. Of the ~165 lines in
bevel_gear(),roughly 120 are VNF vertex/face index bookkeeping (
teeth_top_faces,flat_top_faces,backing_side_faces,vnf_join). All of that disappears, becauseThruSectionsBuilder(isSolid: true)caps for us. In exchange we inherit a new risk class:B-Rep robustness. OpenSCAD cannot fail to make a polyhedron; OCCT can absolutely fail to make
a solid.
3. The spiral is a cutter simulation.
cutter_radiusandspiralplace a circle whose arcbetween the inner and outer cone radii is the lengthwise tooth trace (gears.scad:2528-2537),
a direct model of a Gleason face-mill. Roughly 15 lines of 2D trig, low risk.
4. Estimated Swift line count
bevel_pitch_angle, pitch conversionsThe strategic constraint
BOSL2 is mesh-first (VNF to
polyhedron); OCCTSwift is B-Rep-first. A literal port throwsaway the reason to use OCCT at all: faceted polygon soup inside a
.brepfile,unfilletable, exporting a poor STEP. If we port it literally we would be better off just
running OpenSCAD.
The target is therefore: port BOSL2's parameterisation and math, reimplement the
construction on B-Rep primitives.
Explicitly out of scope
anchor/spin/orient/reorient/named_anchor/attachable),thousands of lines of BOSL2 infrastructure with no OCCT analogue. Replaced by explicit
reference frames (see the placement sub-issue).
$gear_stepsand_inherit_gear_*special-variable inheritance, replaced by Swift defaultarguments.
profile_shift/gear_dist/auto_profile_shift. Notebevel_gearcalls_gear_tooth_profilewithout profile shift (gears.scad:2538-2545), so these are not needed.(gears.scad:3424-3529). Real engineering value, but v2 material. Start at the recipe-04-level
profile.
worm_gearandenveloping_worm, noted here so the trap is on record. BOSL2 generates theseby simulating hobbing, sweeping the worm through the blank and differencing over many
angular steps. In OCCT that is dozens of sequential booleans. If a BOSL2 port ever gets
ambitious, that is where it stops.
Licensing
BOSL2 is BSD-2-Clause (Copyright 2017-2019 Revar Desmera); this repo is LGPL-2.1.
Permissive into copyleft is compatible. Attribution must be preserved in the header of any
ported file. No conflict with the open-source-boundary policy, since BOSL2 adds no dependency,
only algorithms.
Deliverable
A docs page reproducing BOSL2
bevel_gear()Examples 1, 2 and 3 side by side with theOCCTSwift renders and the Swift source that generated them.
The construction: Route C
Neither Route A nor Route B is the construction. Route C is. Recording this prominently because
this decision record lagged reality by one spike, and #87 built its spiral trace on Route A after
Route A had already been shown unusable.
ThruSectionsBuilder(isSolid: true)silently omits both end caps when a section wire has 2 ormore periods of out-of-plane variation, and lofting N teeth in one loop means k = N.
build()reports success;
healed()then reachesisValid == trueonly by demoting Solid to Shell.Root-caused in Find a 1.x route to a valid SOLID from the bevel gear loft (blocked by OCCTSwift#702) #108, raised upstream as
OCCTSwift#702.
circularPatternCut) produced a toothed rim, not a gear. Its lastingcontribution is the boolean-robustness result, which Route C depends on.
caps correctly, so the defect never triggers. Reaches a valid solid with no
heal()at all,and bore and backing verify against analytic predictions to 12 or more significant figures.
Route C: unequal mate_teeth, de-risk the blank at non-45-degree pitch angles #110 then showed it holds at every pitch angle from 2 to 88 degrees, so unequal
mate_teethissafe.
Route A's math port is still the foundation and is reused throughout; only its construction
step was replaced.
Plan
circularPatternCutproven to survive 60 near-tangential cuts.mate_teeth. No failure boundary found from 2 to 88 degrees.backing and bore now unblocked.
cone_backing = false), needed by Example 3.The 2.0.0 dependency #108 implied is gone: Route C works on the pinned 1.17.0.
Why bevel is the right probe
It exercises the exact three capabilities that decide whether a broader
gears.scadport isviable: sampled analytic curve to wire, multi-section loft with scale and twist, and N-fold
boolean patterning. If all three hold, most of the gear family follows (rack is trivial, ring
and crown gears are easy). If the boolean patterning fails, we learn that BOSL2 ports here must
stay loft-only, itself a cheap and valuable finding.
Sizing: 1-2 days if Route A holds; 3-5 if Route B's booleans need fighting.