forgecad 0.9.16 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AdminPage-CXvls4-J.js → AdminPage-DwYHz72L.js} +1 -1
- package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-a9_f-1US.js} +1 -1
- package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DodHpvmf.js} +1 -1
- package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-B5LePEuj.js} +8 -858
- package/dist/assets/EditorApp-QXsAISLR.js +16307 -0
- package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-DdEHGUMU.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-yhhOodbf.js} +1 -1
- package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-5RbKRGYK.js} +1 -1
- package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-E3Rma7aV.js} +1 -1
- package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-BJZcM97j.js} +1 -1
- package/dist/assets/{app-T0pDcSX4.js → app-DSYrDg0V.js} +733 -205
- package/dist/assets/cli/{render-C5pcIISc.js → render-ZMHR9HkV.js} +19 -46
- package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
- package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-DbNs7Dkp.js} +3798 -1622
- package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
- package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DO6mnXn_.js} +1 -1
- package/dist/assets/{manifold-BWgsjmAM.js → manifold-BGlQBBH9.js} +1 -1
- package/dist/assets/{manifold-rZexZI0G.js → manifold-BU-tJwQh.js} +1 -1
- package/dist/assets/{manifold-D6IFSkhH.js → manifold-fy2MV7K1.js} +2 -2
- package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-DO6hcQbh.js} +7155 -2437
- package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-o90NSNmF.js} +3940 -1742
- package/dist/assets/{scanProxyWorker-Vl4Wxa1y.js → scanProxyWorker-2GtDLk-R.js} +1 -1
- package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +3 -3
- package/dist/docs-raw/AI/usage.md +1 -1
- package/dist/docs-raw/CLI.md +63 -241
- package/dist/docs-raw/README.md +6 -0
- package/dist/docs-raw/component-model.md +17 -150
- package/dist/docs-raw/generated/assembly.md +139 -598
- package/dist/docs-raw/generated/concepts.md +245 -3501
- package/dist/docs-raw/generated/core.md +277 -1251
- package/dist/docs-raw/generated/curves.md +387 -1608
- package/dist/docs-raw/generated/legacy.md +162 -0
- package/dist/docs-raw/generated/lib.md +227 -85
- package/dist/docs-raw/generated/output.md +38 -73
- package/dist/docs-raw/generated/runtime-names.md +23 -23
- package/dist/docs-raw/generated/sdf.md +68 -284
- package/dist/docs-raw/generated/sheet-metal.md +68 -335
- package/dist/docs-raw/generated/sketch.md +240 -1161
- package/dist/docs-raw/generated/viewport.md +75 -316
- package/dist/docs-raw/generated/wood.md +21 -49
- package/dist/docs-raw/guides/coordinate-system.md +4 -42
- package/dist/docs-raw/guides/inspection-bundles.md +44 -442
- package/dist/docs-raw/guides/joint-design.md +18 -79
- package/dist/docs-raw/guides/positioning.md +21 -143
- package/dist/docs-raw/guides/scene-presentation.md +89 -0
- package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
- package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
- package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
- package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
- package/dist/docs-raw/skills/forgecad-lld.md +19 -113
- package/dist/docs-raw/skills/forgecad-make-a-model.md +112 -532
- package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
- package/dist/docs-raw/skills/forgecad-project.md +13 -131
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
- package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
- package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
- package/dist/docs-raw/skills/forgecad.md +19 -18
- package/dist/docs-raw/skills/index.md +2 -0
- package/dist/docs-raw/welcome.md +2 -2
- package/dist/index.html +1 -1
- package/dist/llms.txt +1 -2
- package/dist/sitemap.xml +13 -13
- package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-JTVBITCR.js} +1 -1
- package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-3FFLSMVN.js} +1 -1
- package/dist-cli/{chunk-SPZE3DUY.js → chunk-OAN5T4XD.js} +4412 -2212
- package/dist-cli/forgecad.js +507 -179
- package/dist-skill/CONTEXT.md +2172 -8377
- package/dist-skill/SKILL.md +15 -15
- package/dist-skill/docs/API/core/concepts.md +27 -157
- package/dist-skill/docs/CLI.md +63 -241
- package/dist-skill/docs/generated/assembly.md +138 -549
- package/dist-skill/docs/generated/core.md +277 -1251
- package/dist-skill/docs/generated/curves.md +387 -1609
- package/dist-skill/docs/generated/lib.md +227 -85
- package/dist-skill/docs/generated/output.md +38 -73
- package/dist-skill/docs/generated/runtime-names.md +16 -21
- package/dist-skill/docs/generated/sdf.md +68 -284
- package/dist-skill/docs/generated/sheet-metal.md +68 -335
- package/dist-skill/docs/generated/sketch.md +240 -1160
- package/dist-skill/docs/generated/viewport.md +75 -223
- package/dist-skill/docs/generated/wood.md +21 -49
- package/dist-skill/docs/guides/coordinate-system.md +4 -42
- package/dist-skill/docs/guides/inspection-bundles.md +44 -442
- package/dist-skill/docs/guides/joint-design.md +18 -79
- package/dist-skill/docs/guides/positioning.md +21 -143
- package/dist-skill/docs/guides/scene-presentation.md +89 -0
- package/dist-skill/docs/guides/surface-members.md +26 -0
- package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
- package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
- package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
- package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +110 -532
- package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
- package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
- package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
- package/dist-skill/library/forgecad-project/SKILL.md +13 -133
- package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
- package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
- package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
- package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
- package/dist-skill/website/skills/forgecad-component-model.md +53 -0
- package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
- package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
- package/dist-skill/website/skills/forgecad-lld.md +41 -0
- package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
- package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
- package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
- package/dist-skill/website/skills/forgecad-project.md +26 -0
- package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
- package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
- package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
- package/dist-skill/website/skills/forgecad.md +122 -0
- package/dist-skill/website/skills/index.md +26 -0
- package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
- package/examples/api/conformal-product-ribbon.forge.js +1 -1
- package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
- package/examples/api/extrude-options.forge.js +4 -2
- package/examples/api/field-loft-drive-tip.forge.js +40 -0
- package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +10 -10
- package/examples/api/mesh-import-slats.forge.js +1 -1
- package/examples/api/real-product-curves.forge.js +1 -1
- package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
- package/examples/api/sdf-shapes.forge.js +2 -5
- package/examples/api/sketch-rounding-strategies.forge.js +6 -6
- package/examples/api/surface-member-bottle-cage.forge.js +3 -3
- package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
- package/examples/api/surface-member-razor-inlay.forge.js +1 -1
- package/examples/api/variable-sweep-test.forge.js +3 -3
- package/examples/mechanical/airplane-propeller.forge.js +74 -39
- package/examples/nurbs-surface.forge.js +1 -1
- package/examples/products/iphone.forge.js +1 -1
- package/package.json +1 -1
- package/dist/assets/EditorApp-BHMQlJ-D.js +0 -14686
- package/dist/docs-raw/guides/geometry-conventions.md +0 -52
- package/dist/docs-raw/guides/modeling-recipes.md +0 -78
- package/dist-skill/docs/guides/geometry-conventions.md +0 -52
- package/dist-skill/docs/guides/modeling-recipes.md +0 -78
- package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/gen-api-docs.mjs. Do not edit by hand. -->
|
|
2
|
+
<!-- BUILD GUARD: no skill-group frontmatter, ever — this file is a lookup table for
|
|
3
|
+
agents editing old models, not taught context. Banned from the skill bundle via
|
|
4
|
+
BUNDLE_BANNED_DOCS in scripts/build-forgecad-skill.mjs. -->
|
|
5
|
+
|
|
6
|
+
# Legacy API Names
|
|
7
|
+
|
|
8
|
+
These names still run but are no longer taught; new code must use the replacement.
|
|
9
|
+
Each emits a one-time deprecation warning per script run.
|
|
10
|
+
They may be removed in a future release.
|
|
11
|
+
|
|
12
|
+
## core
|
|
13
|
+
|
|
14
|
+
| Old name | Use instead |
|
|
15
|
+
|----------|-------------|
|
|
16
|
+
| `composeChain()` | `Transform.compose(a, b, ...)` |
|
|
17
|
+
| `importSvgSketch()` | `Import.svgSketch(file, options)` |
|
|
18
|
+
| `importMesh()` | `Import.mesh(file, options)` |
|
|
19
|
+
| `importStep()` | `Import.step(file)` |
|
|
20
|
+
| `Constraint.makeParallel()` | `sk.parallel(a, b)` |
|
|
21
|
+
| `Constraint.horizontal()` | `sk.horizontal(line)` |
|
|
22
|
+
| `Constraint.vertical()` | `sk.vertical(line)` |
|
|
23
|
+
| `Constraint.equalLength()` | `sk.equal(a, b)` |
|
|
24
|
+
| `Constraint.distance()` | `sk.distance(a, b, value)` |
|
|
25
|
+
| `Constraint.fix()` | `sk.fix(point, x, y)` |
|
|
26
|
+
| `Constraint.coincident()` | `sk.coincident(a, b)` |
|
|
27
|
+
| `Constraint.perpendicular()` | `sk.perpendicular(a, b)` |
|
|
28
|
+
| `Constraint.length()` | `sk.length(line, value)` |
|
|
29
|
+
| `Slot.rounded()` | `SurfaceMembers.roundedSlot({ length, width }) — same builder, same fluent chain` |
|
|
30
|
+
| `Counterbore.cylindrical()` | `SurfaceMembers.counterbore({ diameter, clearanceDiameter, depth }) — same builder, same fluent chain` |
|
|
31
|
+
| `Ribs.repeated()` | `SurfaceMembers.ribs({ count, height }) — same feature object` |
|
|
32
|
+
|
|
33
|
+
## sketch
|
|
34
|
+
|
|
35
|
+
| Old name | Use instead |
|
|
36
|
+
|----------|-------------|
|
|
37
|
+
| `point()` | `new Point2D(x, y) — or cs.point(x, y) inside constrainedSketch()` |
|
|
38
|
+
| `line()` | `Line2D.fromCoordinates(x1, y1, x2, y2) — or cs.line(a, b) inside constrainedSketch()` |
|
|
39
|
+
| `circle()` | `Circle2D.fromCenterAndRadius(new Point2D(cx, cy), r) — or circle2d(r) for a sketch profile` |
|
|
40
|
+
| `addRect()` | `sk.rect({ x: 0, y: 0, width: 100, height: 50 }) — same options, called on the constrainedSketch() builder` |
|
|
41
|
+
| `addPolygon()` | `sk.addPolygon({ points: [[0,0],[100,0],[50,80]] }) — same options, called on the constrainedSketch() builder` |
|
|
42
|
+
| `addRegularPolygon()` | `sk.regularPolygon({ sides: 6, radius: 25 }) — same options, called on the constrainedSketch() builder` |
|
|
43
|
+
| `filletTrackedEdge()` | `fillet(shape, radius, shape.edge('vert-br')) — same exact compiler-owned path, no quadrant tuple needed` |
|
|
44
|
+
| `chamferTrackedEdge()` | `chamfer(shape, size, shape.edge('vert-br')) — same exact compiler-owned path, no quadrant tuple needed` |
|
|
45
|
+
| `filletCorners()` | `polygon(points).filletCorner([x, y], radius) — seed-point corner selection; or .filletCorners(radius) for all corners` |
|
|
46
|
+
| `star()` | `polygon(tips.flatMap((tip, i) => [tip, valleys[i]])) with tips = polygonVertices(n, outerR, { startDeg: -90 }) and valleys = polygonVertices(n, innerR, { startDeg: -90 + 180 / n })` |
|
|
47
|
+
| `ConstrainedSketchBuilder.importPoint()` | `sk.point(pt.x, pt.y, fixed) — constraint methods auto-import Point2D values directly` |
|
|
48
|
+
| `ConstrainedSketchBuilder.importLine()` | `sk.line(sk.point(l.start.x, l.start.y, fixed), sk.point(l.end.x, l.end.y, fixed)) — constraint methods auto-import Line2D values directly` |
|
|
49
|
+
| `ConstrainedSketchBuilder.importRectangle()` | `sk.rect({ x, y, width, height }) — returns richer named sides (bottom/right/top/left) and vertices` |
|
|
50
|
+
|
|
51
|
+
## assembly
|
|
52
|
+
|
|
53
|
+
| Old name | Use instead |
|
|
54
|
+
|----------|-------------|
|
|
55
|
+
| `bomToCsv()` | `solvedAssembly.bomCsv() — the method form covers BOM CSV export` |
|
|
56
|
+
| `SolvedAssembly.mateExplodeHints()` | `explode hints derive automatically from connect()/match() joints — use explodeView()` |
|
|
57
|
+
| `SolvedAssembly.mateDof()` | `diagnostics for the legacy mate() solver — position parts with connect()/match() and inspect kinematics instead` |
|
|
58
|
+
| `SolvedAssembly.mateConverged()` | `diagnostics for the legacy mate() solver — position parts with connect()/match() and inspect kinematics instead` |
|
|
59
|
+
| `SolvedAssembly.toScene()` | `toSceneObjects() — same return shape; or return the SolvedAssembly directly` |
|
|
60
|
+
| `Assembly.usedPortRefs()` | `usedConnectorRefs — same ReadonlySet` |
|
|
61
|
+
| `Assembly.mate()` | `connect("Parent.connectorA", "Child.connectorB") / match("Child.connectorB", "Parent.connectorA") — connector-frame joints replace string-ref mates` |
|
|
62
|
+
| `Assembly.getPort()` | `getConnector(ref) — same "PartName.connectorName" ref; fields are partName/connectorName/connector` |
|
|
63
|
+
| `Assembly.linkToward()` | `linkAlong(name, fromLink, towardLink, distance) — same arguments; positive distance moves toward towardLink, negative moves away` |
|
|
64
|
+
| `Assembly.linkAwayFrom()` | `linkAlong(name, fromLink, awayFromLink, -distance) — negate the distance: negative values extend away from the reference link` |
|
|
65
|
+
| `Assembly.toJointsView()` | `return the Assembly directly (return mech) — solver-backed controls appear automatically; use addAnimation(name, { keyframes }) for animation clips` |
|
|
66
|
+
| `ImportedAssembly.part()` | `getPart(name, state?) — same offset-aware accessor; note that solve(state).getPart(name) does NOT apply the placeReference() offset stored on the imported assembly` |
|
|
67
|
+
| `ImportedAssembly.translate()` | `toGroup().translate(x, y, z) — the explicit toGroup(state?) call shows where kinematics become a static group; or placeReference() to position by a named point` |
|
|
68
|
+
| `ImportedAssembly.rotate()` | `toGroup().rotate(axis, angleDeg, options) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
69
|
+
| `ImportedAssembly.rotateX()` | `toGroup().rotateX(angleDeg, options) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
70
|
+
| `ImportedAssembly.rotateY()` | `toGroup().rotateY(angleDeg, options) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
71
|
+
| `ImportedAssembly.rotateZ()` | `toGroup().rotateZ(angleDeg, options) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
72
|
+
| `ImportedAssembly.scale()` | `toGroup().scale(v) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
73
|
+
| `ImportedAssembly.mirror()` | `toGroup().mirror(normal) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
74
|
+
| `ImportedAssembly.color()` | `toGroup().color(hex) — the explicit toGroup(state?) call shows where kinematics become a static group` |
|
|
75
|
+
|
|
76
|
+
## curves
|
|
77
|
+
|
|
78
|
+
| Old name | Use instead |
|
|
79
|
+
|----------|-------------|
|
|
80
|
+
| `nurbsSurface()` | `Surface.Nurbs(controlGrid, options) — same arguments and options, including thickness` |
|
|
81
|
+
| `surfacePatch()` | `Surface.Patch(curves, { approximate: true }) — Surface.Patch defaults approximate: false (pass { approximate: true } for sampled Curve3D/Vec3[] boundaries) and returns an open sheet; use .thicken(t) instead of the thickness option` |
|
|
82
|
+
| `Surface.MatchEdge()` | `Surface.Match()` |
|
|
83
|
+
| `Product.ovalProfile()` | `Product.profiles.oval(width, depth, options) — identical arguments` |
|
|
84
|
+
| `Product.roundedRectProfile()` | `Product.profiles.roundedRect(width, depth, radius) — identical arguments` |
|
|
85
|
+
| `Product.circleProfile()` | `Product.profiles.circle(diameter, options) — identical arguments` |
|
|
86
|
+
| `Product.superEllipseProfile()` | `Product.profiles.superEllipse(width, depth, options) — identical arguments` |
|
|
87
|
+
| `Product.spout()` | `Product.place(loft(sectionSketches, heights).as('spout'), ref) — loft the local spout sections at origin, then place the result on the ProductSurfaceRef frame (or ref.attach(...) with offset/inset options)` |
|
|
88
|
+
| `Product.handle()` | `sweep(gripProfile, spinePoints) with spine points derived from ref.frame().point, plus Product.place(padShape, ref) for landing pads — composes loft/sweep with connector frames instead of a fixed handle archetype` |
|
|
89
|
+
| `Curve.Polyline()` | `pass the Vec3[] points array directly — sweep(profile, points) and Curve.Trim/Reverse accept raw point arrays; use Curve.Route.fromPolyline(points) when the centerline needs bend/port metadata` |
|
|
90
|
+
| `Curve.Spline()` | `Curve.Fit(points) — exact NURBS interpolation through the same points (add { closed: true } for loops); unlike the sampled Catmull-Rom spline it works with Curve.Trim/Reverse, sweeps, and exact surface boundaries` |
|
|
91
|
+
|
|
92
|
+
## sheet-metal
|
|
93
|
+
|
|
94
|
+
| Old name | Use instead |
|
|
95
|
+
|----------|-------------|
|
|
96
|
+
| `kerfCompensateOutline()` | `sketch.offset(-kerf / 2) — or let FlatPart.profile(kerf) / Laser.kit({ kerf }) apply kerf compensation automatically` |
|
|
97
|
+
| `kerfCompensateTabs()` | `sketch.offset(kerf / 2) — or let FlatPart.profile(kerf) / Laser.kit({ kerf }) apply kerf compensation automatically` |
|
|
98
|
+
| `kerfCompensateSlots()` | `sketch.offset(kerf / 2) — or let FlatPart.profile(kerf) / Laser.kit({ kerf }) apply kerf compensation automatically` |
|
|
99
|
+
| `kerfCompensatePart()` | `FlatPart.profile(kerf) / FlatPart.solid(kerf) — or Laser.kit({ kerf }), which compensates every part automatically` |
|
|
100
|
+
| `lookupKerf()` | `Laser.lookupKerf(material, thickness, laserType)` |
|
|
101
|
+
| `flatPanel()` | `Laser.panel(name, width, height, thickness, options) — identical arguments` |
|
|
102
|
+
| `flatPart()` | `Laser.part(name, profile, thickness, edges, options) — identical arguments` |
|
|
103
|
+
| `fingerJoint()` | `Laser.fingerJoint(partA, edgeA, partB, edgeB, options) — identical arguments` |
|
|
104
|
+
| `tabSlot()` | `Laser.tabSlot(partA, edgeA, partB, edgeB, options) — identical arguments` |
|
|
105
|
+
| `assemblyPreview()` | `Laser.kit(...).assemblyPreview(options) — the kit collects joints and applies its kerf (default 0.2 mm; this standalone form defaulted kerf to 0, so use Laser.kit({ kerf: 0 }) for byte-identical preview geometry); Laser.assemblyPreview(parts, joints, options) keeps the standalone form` |
|
|
106
|
+
| `assemblyInstructions()` | `Laser.kit(...).assemblyInstructions(options) — the kit collects joints for you; Laser.instructions(parts, joints, options) keeps the standalone form` |
|
|
107
|
+
| `formatInstructions()` | `Laser.kit(...).formatInstructions(options) — or Laser.formatInstructions(result) for the standalone form` |
|
|
108
|
+
| `laserKit()` | `Laser.kit(options) — identical arguments` |
|
|
109
|
+
| `COMMON_KERFS` | `Laser.COMMON_KERFS` |
|
|
110
|
+
|
|
111
|
+
## viewport
|
|
112
|
+
|
|
113
|
+
| Old name | Use instead |
|
|
114
|
+
|----------|-------------|
|
|
115
|
+
| `viewConfig()` | `scene({ jointOverlay: { ... } }) — same keys, on the one renderer-config global` |
|
|
116
|
+
| `jointsView()` | `return the Assembly directly (return mech) — solver-backed controls appear automatically; use mech.addAnimation(name, { keyframes }) for animation clips` |
|
|
117
|
+
| `showLabels()` | `Viewport.highlight(shape, { labels: true }) — then return the shape; highlight returns void` |
|
|
118
|
+
| `highlight()` | `Viewport.highlight(target, options) — same arguments, namespaced with the other render-only overlays` |
|
|
119
|
+
|
|
120
|
+
## output
|
|
121
|
+
|
|
122
|
+
| Old name | Use instead |
|
|
123
|
+
|----------|-------------|
|
|
124
|
+
| `dimLine()` | `dim(line, opts) — dim() accepts a Line2D (or EdgeRef) directly` |
|
|
125
|
+
|
|
126
|
+
## lib
|
|
127
|
+
|
|
128
|
+
| Old name | Use instead |
|
|
129
|
+
|----------|-------------|
|
|
130
|
+
| `lib.boltHole()` | `shape.hole(face, { diameter, depth }) — face-relative blind/through holes with counterbore/countersink/thread support` |
|
|
131
|
+
| `lib.counterbore()` | `shape.hole(face, { diameter: holeDia, counterbore: { diameter: boreDia, depth: boreDepth } }) — through by default; pass depth for blind holes` |
|
|
132
|
+
| `lib.hexNut()` | `lib.nut(holeDia, { acrossFlats, height, boreDiameter: holeDia }) — exact same geometry` |
|
|
133
|
+
| `lib.sideGear()` | `lib.faceGear(options) — identical arguments` |
|
|
134
|
+
| `lib.sideGearPair()` | `lib.faceGearPair({ face, vertical, ... }) — same options with the side member renamed to face; diagnostics use facegear.* codes` |
|
|
135
|
+
| `lib.gearBodyDisk()` | `lib.gearBodies.disk(options) — identical arguments` |
|
|
136
|
+
| `lib.gearBodyDiskWithHub()` | `lib.gearBodies.diskWithHub(options) — identical arguments` |
|
|
137
|
+
| `lib.gearBodySpoked()` | `lib.gearBodies.spoked(options) — identical arguments` |
|
|
138
|
+
| `lib.gearBodyFromProfile()` | `lib.gearBodies.fromProfile(profile, options) — identical arguments` |
|
|
139
|
+
|
|
140
|
+
## sdf
|
|
141
|
+
|
|
142
|
+
| Old name | Use instead |
|
|
143
|
+
|----------|-------------|
|
|
144
|
+
| `combine()` | `sdf.combine(value, { op })` |
|
|
145
|
+
| `Sculpt.circle()` | `Sculpt.disk(radius, thickness)` |
|
|
146
|
+
| `Sculpt.path()` | `Sculpt.tube(points, options)` |
|
|
147
|
+
| `sdf.morph()` | `a.morph(b, t)` |
|
|
148
|
+
| `sdf.tpmsBlock()` | `sdf.gyroid({ cellSize, wallThickness }).intersect(sdf.box(x, y, z))` |
|
|
149
|
+
| `sdf.withinBox()` | `shape.intersect(sdf.box(x, y, z))` |
|
|
150
|
+
| `sdf.twist()` | `shape.twist(degreesPerUnit)` |
|
|
151
|
+
| `sdf.bend()` | `shape.bend(radius)` |
|
|
152
|
+
| `sdf.repeat()` | `shape.repeat(spacing, count)` |
|
|
153
|
+
| `sdf.circularArray()` | `shape.circularArray(count, offset)` |
|
|
154
|
+
| `SdfShape.move()` | `.at(x, y, z)` |
|
|
155
|
+
| `SdfShape.goop()` | `.blend(other, { radius })` |
|
|
156
|
+
| `SdfShape.keep()` | `.smoothIntersect(other, radius)` |
|
|
157
|
+
| `SdfShape.clipBox()` | `.intersect(sdf.box(x, y, z))` |
|
|
158
|
+
| `SdfShape.fillWith()` | `.intersect(pattern)` |
|
|
159
|
+
| `SdfShape.fillWithGyroid()` | `.intersect(sdf.gyroid({ cellSize, wallThickness }))` |
|
|
160
|
+
| `SdfShape.fillWithSchwarzP()` | `.intersect(sdf.schwarzP({ cellSize, wallThickness }))` |
|
|
161
|
+
| `SdfShape.fillWithDiamond()` | `.intersect(sdf.diamond({ cellSize, wallThickness }))` |
|
|
162
|
+
| `SdfShape.fillWithLidinoid()` | `.intersect(sdf.lidinoid({ cellSize, wallThickness }))` |
|
|
@@ -33,55 +33,27 @@ Pre-built fasteners, gears, pipes, structural profiles, and utility shapes. Acce
|
|
|
33
33
|
|
|
34
34
|
**Methods:**
|
|
35
35
|
|
|
36
|
-
#### `toSketch()` — Convert the loop centerline into a thin visual sketch.
|
|
36
|
+
#### `toSketch(width?: number): Sketch` — Convert the loop centerline into a thin visual sketch.
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
toSketch(width?: number): Sketch
|
|
40
|
-
```
|
|
38
|
+
#### `toProfile(): Sketch` — Convert the loop into a filled profile using the pitch path itself as the boundary.
|
|
41
39
|
|
|
42
|
-
#### `
|
|
43
|
-
|
|
44
|
-
```ts
|
|
45
|
-
toProfile(): Sketch
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
#### `offsetBand()` — Build a belt band sketch by offsetting the route to inner and outer pulley radii.
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
offsetBand(thickness: number): Sketch
|
|
52
|
-
```
|
|
40
|
+
#### `offsetBand(thickness: number): Sketch` — Build a belt band sketch by offsetting the route to inner and outer pulley radii.
|
|
53
41
|
|
|
54
42
|
### `DriveWheelBuilder`
|
|
55
43
|
|
|
56
|
-
#### `addSpurTeethBetween()` — Add an involute spur-tooth window on part of the pitch circle.
|
|
57
|
-
|
|
58
|
-
```ts
|
|
59
|
-
addSpurTeethBetween(options: DriveWheelSpurTeethRegionOptions): this
|
|
60
|
-
```
|
|
44
|
+
#### `addSpurTeethBetween(options: DriveWheelSpurTeethRegionOptions): this` — Add an involute spur-tooth window on part of the pitch circle.
|
|
61
45
|
|
|
62
46
|
`DriveWheelSpurTeethRegionOptions`: `{ name?: string, teethOnFullCircle: number, toothCount: number, firstTooth?: number, faceWidth?: number }`
|
|
63
47
|
|
|
64
|
-
#### `addSolidArcBetween()` — Add a constant-radius solid arc region such as a dwell, stop, or pusher.
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
addSolidArcBetween(options: DriveWheelSolidArcRegionOptions): this
|
|
68
|
-
```
|
|
48
|
+
#### `addSolidArcBetween(options: DriveWheelSolidArcRegionOptions): this` — Add a constant-radius solid arc region such as a dwell, stop, or pusher.
|
|
69
49
|
|
|
70
50
|
**`DriveWheelSolidArcRegionOptions`**: `name?: string`, `fromAngleDeg: number`, `toAngleDeg: number`, `innerRadius?: number`, `outerRadius: number`, `faceWidth?: number`, `segments?: number`
|
|
71
51
|
|
|
72
|
-
#### `addShapeRegion()` — Add a fully custom region shape while preserving region metadata.
|
|
73
|
-
|
|
74
|
-
```ts
|
|
75
|
-
addShapeRegion(name: string, shape: Shape, options?: DriveWheelShapeRegionOptions): this
|
|
76
|
-
```
|
|
52
|
+
#### `addShapeRegion(name: string, shape: Shape, options?: DriveWheelShapeRegionOptions): this` — Add a fully custom region shape while preserving region metadata.
|
|
77
53
|
|
|
78
54
|
`DriveWheelShapeRegionOptions`: `{ fromAngleDeg?: number, toAngleDeg?: number, innerRadius?: number, outerRadius?: number }`
|
|
79
55
|
|
|
80
|
-
#### `build()` — Build the final wheel shape with a bore connector and region metadata.
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
build(): Shape
|
|
84
|
-
```
|
|
56
|
+
#### `build(): Shape` — Build the final wheel shape with a bore connector and region metadata.
|
|
85
57
|
|
|
86
58
|
---
|
|
87
59
|
|
|
@@ -91,69 +63,239 @@ build(): Shape
|
|
|
91
63
|
|
|
92
64
|
Pre-built parametric parts available in user scripts as `lib.*`.
|
|
93
65
|
|
|
94
|
-
Every key in this object becomes a method or namespace on the `lib` object exposed to `.forge.js` scripts
|
|
66
|
+
Every key in this object becomes a method or namespace on the `lib` object exposed to `.forge.js` scripts — see the member list below for the catalog. Sizes outside the supported ranges throw at runtime with a descriptive error.
|
|
67
|
+
|
|
68
|
+
- `fastenerHole(opts: FastenerHoleOptions): Shape` — ISO metric fastener hole cutter with optional counterbore or countersink.
|
|
69
|
+
|
|
70
|
+
Returns a cutter shape (subtract from a solid to produce the hole). Sizes outside M2–M10 will throw.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const plate = box(60, 40, 8)
|
|
74
|
+
.subtract(lib.fastenerHole({ size: 'M5', fit: 'normal', depth: 8 })
|
|
75
|
+
.translate(15, 10, 4));
|
|
76
|
+
```
|
|
77
|
+
- `tube(outerX: number, outerY: number, outerZ: number, wall: number): Shape` — Rectangular hollow tube (thin-wall box section).
|
|
78
|
+
|
|
79
|
+
Both the outer and inner boxes are centered on the XY plane with their base at Z=0.
|
|
80
|
+
- `pipe(height: number, outerRadius: number, wall: number, segments?: number): Shape` — Hollow cylindrical pipe.
|
|
81
|
+
|
|
82
|
+
Centered on the XY plane, extending upward along +Z from z=0 to z=height. For complex routed pipe geometry, see `lib.pipeRoute`.
|
|
83
|
+
- `explode<T extends ExplodeItem[] | ShapeGroup>(items: T, options?: ExplodeOptions): T` — Apply deterministic exploded-view offsets to an assembly tree.
|
|
84
|
+
|
|
85
|
+
Traverses arrays, nested `{ name, group: [...] }` structures, and [`ShapeGroup`](/docs/core#shapegroup) outputs, translating each node while preserving names, colors, and nesting; returns the same structure type as the input. `radial` mode is branch-aware and parent-relative — nested assemblies peel apart level by level. Named items accept an inline `explode: { stage?, direction?, axisLock? }` override. Bakes the offset into geometry (e.g. driven by a `param()` slider); for a viewport-only slider use [`explodeView()`](/docs/viewport#explodeview) instead.
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const explodeAmt = param('Explode', 0, { min: 0, max: 40, unit: 'mm' });
|
|
89
|
+
|
|
90
|
+
return lib.explode(assembly, {
|
|
91
|
+
amount: explodeAmt,
|
|
92
|
+
stages: [0.4, 0.8],
|
|
93
|
+
mode: 'radial',
|
|
94
|
+
byName: { Shaft: { direction: [1, 0, 0], stage: 1.4 } },
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
- `bracket(width: number, height: number, depth: number, thick: number, holeDia?: number): Shape` — L-shaped mounting bracket with optional through-holes.
|
|
98
|
+
|
|
99
|
+
Produces a right-angle bracket: a horizontal base plate and a vertical wall. Both legs share `width`. Optional holes are drilled through the base (along Z) and the wall (along Y).
|
|
100
|
+
- `holePattern(rows: number, cols: number, spacingX: number, spacingY: number, holeDia: number, depth: number): Shape` — Rectangular grid of cylindrical hole cutters.
|
|
101
|
+
|
|
102
|
+
Returns the union of `rows × cols` cylinders laid out on a regular grid. Subtract from a solid to produce the full pattern.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const pattern = lib.holePattern(3, 4, 20, 20, 4, 10);
|
|
106
|
+
const panel = box(80, 70, 10).subtract(pattern.translate(-30, -20, 0));
|
|
107
|
+
```
|
|
108
|
+
- `thread(diameter: number, pitch: number, length: number, options?: { depth?: number; segments?: number; }): Shape` — External helical thread — clean mesh, no SDF grid artifacts.
|
|
109
|
+
|
|
110
|
+
Builds a cross-section with a single trapezoidal tooth from the root radius out to the crest radius, then twist-extrudes it so the tooth traces a helix. Manifold's extrude+twist produces structured quad-based geometry that follows the thread profile cleanly.
|
|
111
|
+
|
|
112
|
+
Returns a threaded cylinder along +Z from z=0 to z=length.
|
|
113
|
+
- `bolt(diameter: number, length: number, options?: { ... }): Shape` — ISO-style hex bolt with real helical threads.
|
|
114
|
+
|
|
115
|
+
The hex head sits from z=0 up to z=headHeight. The shaft extends downward along −Z by `length` mm. An unthreaded shank section is included when `threadLength < length`.
|
|
116
|
+
|
|
117
|
+
Default proportions follow ISO 4762 loosely: pitch ≈ 0.15×diameter, head height ≈ 0.65×diameter, across-flats ≈ 1.6×diameter.
|
|
118
|
+
|
|
119
|
+
For standard M-size bolts pre-configured for a complete joint, use `fastenerSet` instead.
|
|
120
|
+
- `nut(diameter: number, options?: { ... }): Shape` — ISO-style hex nut with a clearance bore.
|
|
121
|
+
|
|
122
|
+
Constructed from the intersection of three rotated slabs with a cylindrical bore subtracted. The nut is centered at the origin, height along Z (−height/2 to +height/2).
|
|
123
|
+
|
|
124
|
+
Default proportions follow ISO 4032 loosely: height ≈ 0.8×diameter, across-flats ≈ 1.6×diameter. The bore is a clearance bore — `diameter` + 0.2 mm by default, override with `boreDiameter` for exact bore control — not modelled with helical threads, for rendering efficiency.
|
|
125
|
+
|
|
126
|
+
For standard M-size nuts pre-configured for a complete joint, use `fastenerSet` instead.
|
|
127
|
+
- `washer(size: MetricSize, options?: { standard?: WasherStandard; segments?: number; }): Shape` — ISO metric flat washer (DIN 125-A).
|
|
128
|
+
|
|
129
|
+
Returns a flat ring centered at the origin, thickness along Z. Dimensions are taken from `WASHER_TABLE`. Sizes outside M2–M10 will throw.
|
|
130
|
+
- `fastenerSet(size: MetricSize, boltLength: number, options?: FastenerSetOptions): FastenerSetResult` — Complete ISO metric fastener set — bolt, nut, optional washers, and matching hole cutters.
|
|
131
|
+
|
|
132
|
+
Returns all geometry for one bolted joint: the bolt, nut, up to two washers, a clearance-hole cutter, and a tap-drill cutter. All shapes are returned **un-positioned** (each on the Z-axis). Place them with `.translate()`.
|
|
133
|
+
|
|
134
|
+
Sizes outside M4–M10 are supported for the washer (M2–M10); unsupported combinations will throw.
|
|
95
135
|
|
|
96
|
-
|
|
136
|
+
```ts
|
|
137
|
+
const hw = lib.fastenerSet('M5', 20);
|
|
97
138
|
|
|
98
|
-
|
|
139
|
+
const topPlate = box(60, 40, 8).translate(0, 0, 12)
|
|
140
|
+
.subtract(hw.clearanceHole.translate(15, 10, 12));
|
|
141
|
+
const botPlate = box(60, 40, 8)
|
|
142
|
+
.subtract(hw.clearanceHole.translate(15, 10, 0));
|
|
99
143
|
|
|
100
|
-
|
|
144
|
+
return [
|
|
145
|
+
{ name: 'Top Plate', shape: topPlate },
|
|
146
|
+
{ name: 'Bot Plate', shape: botPlate },
|
|
147
|
+
{ name: 'Bolt', shape: hw.bolt.translate(15, 10, 20) },
|
|
148
|
+
{ name: 'Nut', shape: hw.nut.translate(15, 10, -4) },
|
|
149
|
+
];
|
|
150
|
+
```
|
|
151
|
+
- `pipeRoute(points: Vec3[], radius: number, options?: { bendRadius?: number; wall?: number; segments?: number; }): Shape` — Route a pipe (solid or hollow) through 3D waypoints with smooth bends.
|
|
101
152
|
|
|
102
|
-
|
|
153
|
+
This is a convenience recipe over `Curve.Route.fromPolyline()` and [`sweep()`](/docs/curves#sweep). Use `Curve.Route` directly when you need route metadata, named ports, or custom swept profiles.
|
|
154
|
+
- `elbow(pipeRadius: number, bendRadius: number, angle?: number | { ... }, options?: { ... }): Shape` — Pipe elbow — a curved pipe section for connecting two pipe directions.
|
|
103
155
|
|
|
104
|
-
|
|
156
|
+
This is a convenience recipe over `Curve.Arc()` and [`sweep()`](/docs/curves#sweep). Use `Curve.Route.fromPolyline()` directly when you need named route ports, segment metadata, or multi-bend pipe runs.
|
|
157
|
+
- `beltDrive(options: BeltDriveOptions): BeltDriveResult` — Create a flat open-belt body around two pulley pitch circles.
|
|
105
158
|
|
|
106
|
-
|
|
159
|
+
The belt is generated as a tangent loop in the XY plane and extruded along +Z by `beltWidth`. The result includes the solid belt, the 2D belt profile, a thin pitch-path sketch for visualization, total belt length, tangent spans, and wrap metadata for each pulley.
|
|
107
160
|
|
|
108
|
-
|
|
161
|
+
For more than two pulleys, the API intentionally asks for route intent before geometry is created. Use `route: "outer"` for the future outside-envelope mode, or an ordered route for future serpentine/idler layouts.
|
|
109
162
|
|
|
110
|
-
|
|
163
|
+
```ts
|
|
164
|
+
const drive = lib.beltDrive({
|
|
165
|
+
pulleys: [
|
|
166
|
+
{ name: "motor", center: [0, 0], pitchRadius: 12 },
|
|
167
|
+
{ name: "output", center: [80, 0], pitchRadius: 28 },
|
|
168
|
+
],
|
|
169
|
+
beltWidth: 8,
|
|
170
|
+
beltThickness: 2,
|
|
171
|
+
});
|
|
172
|
+
return drive.belt;
|
|
173
|
+
```
|
|
174
|
+
- `tangentLoop2d(circles: TangentCircle2D[], options?: TangentLoop2DOptions): TangentLoop2D` — Build a closed 2D route made from common tangent spans and pulley wrap arcs.
|
|
111
175
|
|
|
112
|
-
|
|
176
|
+
Use this when you need reusable belt/chain route geometry before creating a solid body. The first implementation supports two circles. `mode: "open"` uses external tangents; `mode: "crossed"` uses internal tangents.
|
|
113
177
|
|
|
114
|
-
|
|
178
|
+
```ts
|
|
179
|
+
const route = lib.tangentLoop2d([
|
|
180
|
+
{ center: [0, 0], radius: 12 },
|
|
181
|
+
{ center: [80, 0], radius: 28 },
|
|
182
|
+
]);
|
|
183
|
+
const belt = route.offsetBand(2).extrude(8);
|
|
184
|
+
```
|
|
185
|
+
- `tSlotProfile(options?: TSlotProfileOptions): Sketch` — Build a 2D T-slot cross-section sketch.
|
|
115
186
|
|
|
116
|
-
|
|
117
|
-
- `fastenerHole(opts: FastenerHoleOptions): Shape` — ISO metric fastener hole cutter with optional counterbore or countersink. **Details** Returns a cutter shape (subtract from a solid to produce the hole). Sizes outside M2–M10 will throw. Extend `METRIC_HOLE_TABLE` in this file to add new sizes. **Example** ```ts const plate = box(60, 40, 8) .subtract(lib.fastenerHole({ size: 'M5', fit: 'normal', depth: 8 }) .translate(15, 10, 4)); ```
|
|
118
|
-
- `counterbore(holeDia: number, boreDia: number, boreDepth: number, totalDepth: number): Shape` — Counterbore hole cutter — through-hole with a wider cylindrical recess at the top. Use for socket-head cap screws that must sit flush. Subtract from a solid. For ISO metric sizing and fit classes, prefer {
|
|
119
|
-
- `tube(outerX: number, outerY: number, outerZ: number, wall: number): Shape` — Rectangular hollow tube (thin-wall box section). Both the outer and inner boxes are centered on the XY plane with their base at Z=0.
|
|
120
|
-
- `pipe(height: number, outerRadius: number, wall: number, segments?: number): Shape` — Hollow cylindrical pipe. Centered on the XY plane, extending upward along +Z from z=0 to z=height. For complex routed pipe geometry, see `lib.pipeRoute`.
|
|
121
|
-
- `explode<T extends ExplodeItem[] | ShapeGroup>(items: T, options?: ExplodeOptions): T` — Apply deterministic exploded-view offsets to an assembly tree. **Details** Traverses arrays of shapes/sketches/named items, nested `{ name, group: [...] }` structures, and [`ShapeGroup`](/docs/core#shapegroup) outputs, translating each node by a computed offset while preserving names, colors, and nesting. Returns the same structure type as the input. In `radial` mode the algorithm is branch-aware and parent-relative: each node fans out from its immediate parent's center, so nested assemblies peel apart level by level. Named items may also include an inline `explode: { stage?, direction?, axisLock? }` property to override per-item behavior. Use this function when you want to bake the explode offset into the geometry before returning (e.g. to drive the amount with a `param()` slider). For a viewport-only explode slider without rerunning the script, use [`explodeView()`](/docs/viewport#explodeview) instead. **Example** ```js const explodeAmt = param('Explode', 0, { min: 0, max: 40, unit: 'mm' }); return lib.explode(assembly, { amount: explodeAmt, stages: [0.4, 0.8], mode: 'radial', byName: { Shaft: { direction: [1, 0, 0], stage: 1.4 } }, }); ```
|
|
122
|
-
- `hexNut(acrossFlats: number, height: number, holeDia: number): Shape` — Generic hex nut with a cylindrical bore. Constructed via intersection of three rotated rectangular slabs, then a bore is subtracted. Centered at origin, height along Z. For standard ISO metric nuts by thread size, use `lib.nut` instead.
|
|
123
|
-
- `bracket(width: number, height: number, depth: number, thick: number, holeDia?: number): Shape` — L-shaped mounting bracket with optional through-holes. Produces a right-angle bracket: a horizontal base plate and a vertical wall. Both legs share `width`. Optional holes are drilled through the base (along Z) and the wall (along Y).
|
|
124
|
-
- `holePattern(rows: number, cols: number, spacingX: number, spacingY: number, holeDia: number, depth: number): Shape` — Rectangular grid of cylindrical hole cutters. Returns the union of `rows × cols` cylinders laid out on a regular grid. Subtract from a solid to produce the full pattern. **Example** ```ts const pattern = lib.holePattern(3, 4, 20, 20, 4, 10); const panel = box(80, 70, 10).subtract(pattern.translate(-30, -20, 0)); ```
|
|
125
|
-
- `thread(diameter: number, pitch: number, length: number, options?: { depth?: number; segments?: number; }): Shape` — External helical thread — clean mesh, no SDF grid artifacts. **Details** Builds a cross-section with a single trapezoidal tooth from the root radius out to the crest radius, then twist-extrudes it so the tooth traces a helix. Manifold's extrude+twist produces structured quad-based geometry that follows the thread profile cleanly. Returns a threaded cylinder along +Z from z=0 to z=length. **Example** ```ts const t = lib.thread(5, 0.8, 12); // M5 × 0.8 pitch, 12 mm long ```
|
|
126
|
-
- `bolt(diameter: number, length: number, options?: { ... }): Shape` — ISO-style hex bolt with real helical threads. **Details** The hex head sits from z=0 up to z=headHeight. The shaft extends downward along −Z by `length` mm. An unthreaded shank section is included when `threadLength < length`. Default proportions follow ISO 4762 loosely: pitch ≈ 0.15×diameter, head height ≈ 0.65×diameter, across-flats ≈ 1.6×diameter. For standard M-size bolts pre-configured for a complete joint, use { **Example** ```ts const b = lib.bolt(5, 20); // M5 × 20 mm ```
|
|
127
|
-
- `nut(diameter: number, options?: { pitch?: number; height?: number; acrossFlats?: number; segments?: number; }): Shape` — ISO-style hex nut with a threaded bore. **Details** Constructed from the intersection of three rotated slabs with a cylindrical bore subtracted. The nut is centered at the origin, height along Z. Default proportions follow ISO 4032 loosely: height ≈ 0.8×diameter, across-flats ≈ 1.6×diameter. The bore is a clearance bore (not modelled with helical threads) for rendering efficiency. For standard M-size nuts pre-configured for a complete joint, use { **Example** ```ts const n = lib.nut(5); // M5 nut ```
|
|
128
|
-
- `washer(size: MetricSize, options?: { standard?: WasherStandard; segments?: number; }): Shape` — ISO metric flat washer (DIN 125-A). **Details** Returns a flat ring centered at the origin, thickness along Z. Dimensions are taken from { **Example** ```ts const w = lib.washer('M5'); // DIN 125-A M5 washer ```
|
|
129
|
-
- `fastenerSet(size: MetricSize, boltLength: number, options?: FastenerSetOptions): FastenerSetResult` — Complete ISO metric fastener set — bolt, nut, optional washers, and matching hole cutters. **Details** Returns all geometry for one bolted joint: the bolt, nut, up to two washers, a clearance-hole cutter, and a tap-drill cutter. All shapes are returned **un-positioned** (each on the Z-axis). Place them with `.translate()`. Sizes outside M4–M10 are supported for the washer (M2–M10); unsupported combinations will throw. **Example** ```ts const hw = lib.fastenerSet('M5', 20); const topPlate = box(60, 40, 8).translate(0, 0, 12) .subtract(hw.clearanceHole.translate(15, 10, 12)); const botPlate = box(60, 40, 8) .subtract(hw.clearanceHole.translate(15, 10, 0)); return [ { name: 'Top Plate', shape: topPlate }, { name: 'Bot Plate', shape: botPlate }, { name: 'Bolt', shape: hw.bolt.translate(15, 10, 20) }, { name: 'Nut', shape: hw.nut.translate(15, 10, -4) }, ]; ```
|
|
130
|
-
- `pipeRoute(points: [ number, number, number ][], radius: number, options?: { bendRadius?: number; wall?: number; segments?: number; }): Shape` — Route a pipe (solid or hollow) through 3D waypoints with smooth bends. This is a convenience recipe over `Curve.Route.fromPolyline()` and [`sweep()`](/docs/curves#sweep). Use `Curve.Route` directly when you need route metadata, named ports, or custom swept profiles.
|
|
131
|
-
- `elbow(pipeRadius: number, bendRadius: number, angle?: number | { ... }, options?: { ... }): Shape` — Pipe elbow — a curved pipe section for connecting two pipe directions. This is a convenience recipe over `Curve.Arc()` and [`sweep()`](/docs/curves#sweep). Use `Curve.Route.fromPolyline()` directly when you need named route ports, segment metadata, or multi-bend pipe runs.
|
|
132
|
-
- `beltDrive(options: BeltDriveOptions): BeltDriveResult` — Create a flat open-belt body around two pulley pitch circles. The belt is generated as a tangent loop in the XY plane and extruded along +Z by `beltWidth`. The result includes the solid belt, the 2D belt profile, a thin pitch-path sketch for visualization, total belt length, tangent spans, and wrap metadata for each pulley. For more than two pulleys, the API intentionally asks for route intent before geometry is created. Use `route: "outer"` for the future outside-envelope mode, or an ordered route for future serpentine/idler layouts. ```ts const drive = lib.beltDrive({ pulleys: [ { name: "motor", center: [0, 0], pitchRadius: 12 }, { name: "output", center: [80, 0], pitchRadius: 28 }, ], beltWidth: 8, beltThickness: 2, }); return drive.belt; ```
|
|
133
|
-
- `tangentLoop2d(circles: TangentCircle2D[], options?: TangentLoop2DOptions): TangentLoop2D` — Build a closed 2D route made from common tangent spans and pulley wrap arcs. Use this when you need reusable belt/chain route geometry before creating a solid body. The first implementation supports two circles. `mode: "open"` uses external tangents; `mode: "crossed"` uses internal tangents. ```ts const route = lib.tangentLoop2d([ { center: [0, 0], radius: 12 }, { center: [80, 0], radius: 28 }, ]); const belt = route.offsetBand(2).extrude(8); ```
|
|
134
|
-
- `tSlotProfile(options?: TSlotProfileOptions): Sketch` — Build a 2D T-slot cross-section sketch. Default parameters describe a 20x20 B-type profile with slot 6. Use this when you want a drawing-ready profile sketch before extrusion.
|
|
187
|
+
Default parameters describe a 20x20 B-type profile with slot 6. Use this when you want a drawing-ready profile sketch before extrusion.
|
|
135
188
|
- `tSlotExtrusion(length: number, options?: TSlotExtrusionOptions): Shape` — Build a T-slot extrusion from the generated 2D profile. Extrudes along +Z by default.
|
|
136
|
-
- `profile2020BSlot6Profile(options?: Profile2020BSlot6ProfileOptions): Sketch` — Accurate-ish 2D profile for 20x20 B-type slot 6.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
- `
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
- `
|
|
143
|
-
|
|
144
|
-
|
|
189
|
+
- `profile2020BSlot6Profile(options?: Profile2020BSlot6ProfileOptions): Sketch` — Accurate-ish 2D profile for 20x20 B-type slot 6.
|
|
190
|
+
|
|
191
|
+
Returns a drawing-ready Sketch centered at origin.
|
|
192
|
+
- `profile2020BSlot6(length: number, options?: Profile2020BSlot6Options): Shape` — 20x20 B-type slot 6 extrusion with profile-accurate defaults.
|
|
193
|
+
|
|
194
|
+
Pass option overrides if your supplier's profile differs slightly.
|
|
195
|
+
- `spurGear(options: SpurGearOptions): Shape` — Involute external spur gear with optional center bore.
|
|
196
|
+
|
|
197
|
+
Specify module, teeth, faceWidth as required parameters. Optional tuning includes pressureAngleDeg (default 20), backlash, clearance, addendum, dedendum, boreDiameter, and segmentsPerTooth (default 10).
|
|
198
|
+
|
|
199
|
+
**Connectors (for assembly-based positioning):**
|
|
200
|
+
|
|
201
|
+
- `bore`: revolute connector at the bore center, axis along +Z. Carries measurements: `{ module, teeth, pitchRadius, outerRadius, faceWidth }`.
|
|
202
|
+
|
|
203
|
+
Use `.connect("Housing.seat", "Gear.bore")` to mount a gear on a shaft seat.
|
|
204
|
+
- `bevelGear(options: BevelGearOptions): Shape` — Conical bevel gear generated from a tapered involute extrusion. Specify pitchAngleDeg directly or derive it from mateTeeth + shaftAngleDeg.
|
|
205
|
+
|
|
206
|
+
**Connectors (for assembly-based positioning):**
|
|
207
|
+
|
|
208
|
+
- `bore`: revolute connector at the large-end bore center (Z=0), axis along -Z (away from teeth).
|
|
209
|
+
- `apex`: connector at the cone apex above the gear (the point where the pitch cone converges), axis along +Z. Useful for meshing two bevel gears — their apices should coincide.
|
|
210
|
+
|
|
211
|
+
Carries measurements: `{ module, teeth, pitchRadius, pitchAngleDeg, coneDistance, faceWidth }`.
|
|
212
|
+
- `faceGear(options: FaceGearOptions): Shape` — Face gear (crown style) where the teeth project axially from one face (top or bottom) of the disk instead of the outer cylindrical rim.
|
|
213
|
+
|
|
214
|
+
Uses the same involute tooth sizing as spurGear, then projects the tooth band axially from the chosen side (`side`, default `'top'`) with axial tooth height `toothHeight` (default: one module). To mesh it with a perpendicular spur pinion, prefer `lib.faceGearPair()` — it rotates and positions the pinion at the face tooth band for you.
|
|
215
|
+
|
|
216
|
+
**Connectors (for assembly-based positioning):**
|
|
217
|
+
|
|
218
|
+
- `bore`: revolute connector at the bore center on the body side (the face opposite the teeth), axis pointing away from the teeth. Carries measurements: `{ module, teeth, pitchRadius, outerRadius, faceWidth, toothSide }`.
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
const crown = lib.faceGear({ module: 1.5, teeth: 30, faceWidth: 5, boreDiameter: 6 });
|
|
222
|
+
assembly().connect("Housing.crown_seat", "Crown.bore");
|
|
223
|
+
```
|
|
224
|
+
- `ringGear(options: RingGearOptions): Shape` — Internal ring gear with involute-derived tooth spaces. Specify rimWidth or outerDiameter for the annular body.
|
|
225
|
+
|
|
226
|
+
**Connectors (for assembly-based positioning):**
|
|
227
|
+
|
|
228
|
+
- `bore`: connector at the ring center, axis along +Z. For planetary gearboxes, this is where the ring mounts to the housing. Carries measurements: `{ module, teeth, pitchRadius, innerRadius, outerRadius, faceWidth }`.
|
|
229
|
+
- `rackGear(options: RackGearOptions): Shape` — Linear rack gear with pressure-angle flanks. Use with spurGear for rack-and-pinion mechanisms.
|
|
230
|
+
|
|
231
|
+
**Orientation:** teeth run along the X axis with tooth tips pointing +Y (pitch line at Y=0). The rack is extruded +Z by `faceWidth`. Rotate the rack to align with a different slide axis.
|
|
232
|
+
|
|
233
|
+
**Connectors (for assembly-based positioning):**
|
|
234
|
+
|
|
235
|
+
- `teeth`: prismatic connector at the pitch line center, axis along +X (slide direction). Carries measurements: `{ module, teeth, faceWidth, length }`.
|
|
236
|
+
|
|
237
|
+
Connect to a housing's rack channel:
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
housing.withConnectors({
|
|
241
|
+
rack_channel: connector("rack-channel", {
|
|
242
|
+
origin: [pitchR, 0, channelZ], axis: [1, 0, 0], kind: "prismatic",
|
|
243
|
+
}),
|
|
244
|
+
});
|
|
245
|
+
assembly.connect("Housing.rack_channel", "Rack.teeth", { as: "slide" });
|
|
246
|
+
```
|
|
247
|
+
- `gearPair(options: GearPairOptions): GearPairResult` — Build or validate a spur-gear pair and return ratio, backlash, and mesh diagnostics.
|
|
248
|
+
|
|
249
|
+
Accepts either shapes from spurGear() or analytical specs for each member. When place is true (default), the gear is auto-positioned at the correct center distance.
|
|
145
250
|
- `bevelGearPair(options: BevelGearPairOptions): BevelGearPairResult` — Build or validate a bevel-gear pair and return ratio diagnostics plus recommended joint placement vectors.
|
|
146
|
-
- `faceGearPair(options: FaceGearPairOptions): FaceGearPairResult` —
|
|
147
|
-
- `
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
251
|
+
- `faceGearPair(options: FaceGearPairOptions): FaceGearPairResult` — Pair helper for a face (crown) gear + perpendicular "vertical" spur gear. Auto-placement rotates the spur around +Y and positions it to mesh at the face tooth band.
|
|
252
|
+
- `gearRatio(teethA: number, teethB: number, options?: { internal?: boolean; }): number` — Coupling ratio between two meshed spur gears.
|
|
253
|
+
|
|
254
|
+
When gear A turns 1°, gear B turns `-teethA / teethB` degrees (negative because meshed external gears rotate in opposite directions).
|
|
255
|
+
|
|
256
|
+
```js
|
|
257
|
+
const drivenPerDriver = lib.gearRatio(12, 24); // -0.5
|
|
258
|
+
verify.equal("external spur ratio", drivenPerDriver, -0.5);
|
|
259
|
+
|
|
260
|
+
Pass `{ internal: true }` for internal gear pairs (ring gear + spur/planet),
|
|
261
|
+
where the two rotate in the same direction.
|
|
262
|
+
```
|
|
263
|
+
- `rackRatio(module: number, pinionTeeth: number): number` — Coupling ratio between a pinion and a rack.
|
|
264
|
+
|
|
265
|
+
When the pinion rotates by `θ` degrees, the rack slides by `θ × (π × module × teeth / 360)` mm. Equivalently, 1mm of rack travel = `180 / (π × pitchRadius)` degrees of pinion rotation.
|
|
266
|
+
|
|
267
|
+
```js
|
|
268
|
+
const pinionDegPerMm = lib.rackRatio(1.5, 12); // ~6.37 deg/mm
|
|
269
|
+
```
|
|
270
|
+
- `planetaryRatio(sunTeeth: number, ringTeeth: number): number` — Planetary gear reduction ratio when the ring is held fixed.
|
|
271
|
+
|
|
272
|
+
Input: sun. Output: carrier. Ratio: `1 + ringTeeth / sunTeeth`. One turn of the sun produces `1 / ratio` turns of the carrier.
|
|
273
|
+
- `boltPattern(options: BoltPatternOptions): BoltPattern` — Define a bolt pattern once and cut it from multiple parts.
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
const bolts = lib.boltPattern({
|
|
277
|
+
size: 'M5',
|
|
278
|
+
positions: [[20, 15], [-20, 15], [20, -15], [-20, -15]],
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
const base = bolts.cut(box(60, 50, 10), 12, { from: -1 });
|
|
282
|
+
const cover = bolts.cut(box(60, 50, 3), 5, { from: -1 });
|
|
283
|
+
// Same positions in both parts — guaranteed aligned.
|
|
284
|
+
```
|
|
152
285
|
- `driveWheel(options?: DriveWheelOptions): DriveWheelBuilder` — Start a composable exceptional gear or drive wheel.
|
|
153
286
|
- `readDriveWheelMeta(shape: Shape): DriveWheelMeta | null` — Read the functional-region metadata attached by `driveWheel().build()`.
|
|
154
|
-
- `sectorGear(options: SectorGearOptions): Shape` — Involute sector gear with teeth on only part of the pitch circle.
|
|
287
|
+
- `sectorGear(options: SectorGearOptions): Shape` — Involute sector gear with teeth on only part of the pitch circle.
|
|
288
|
+
|
|
289
|
+
Specify the full-circle pitch as `teethOnFullCircle`, then choose the active tooth window with `firstTooth` and `toothCount`. The body is separate from the tooth region: pass a `gearBody...` shape for spokes, hubs, and product styling, or omit it for a simple root-radius disk.
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
const body = lib.gearBodies.spoked({
|
|
293
|
+
outerRadius: 22, rimWidth: 3, hubDiameter: 10,
|
|
294
|
+
spokeCount: 5, spokeWidth: 2.5, faceWidth: 8, boreDiameter: 5,
|
|
295
|
+
});
|
|
296
|
+
const sector = lib.sectorGear({
|
|
297
|
+
module: 1.25, teethOnFullCircle: 36, toothCount: 10,
|
|
298
|
+
faceWidth: 8, body,
|
|
299
|
+
});
|
|
300
|
+
```
|
|
155
301
|
- `gearBodies: { ... }` — Gear body preset namespace: disk, diskWithHub, spoked, and fromProfile.
|
|
156
|
-
- `gearBodyDisk(options: GearBodyDiskOptions): Shape` — Solid disk/ring gear body, independent from any tooth geometry.
|
|
157
|
-
- `gearBodyDiskWithHub(options: GearBodyDiskWithHubOptions): Shape` — Disk gear body with a raised center hub.
|
|
158
|
-
- `gearBodySpoked(options: GearBodySpokedOptions): Shape` — Spoked gear body with an outer rim, center hub, and radial spokes.
|
|
159
|
-
- `gearBodyFromProfile(profile: Sketch, options: GearBodyFromProfileOptions): Shape` — Extrude a custom 2D profile into a gear body.
|