ladder: 116 cases in 11 tiers, from primitives to a threaded, shelled housing

Tiers: primitives; booleans in the degeneracy classes (coincident and coplanar faces, edge-on-edge,
vertex-on-face, tangent along a line and a circle, near-tangent gaps and overlaps of 1e-3 and
1e-6 mm, seam and pole crossings) and cuts that end in a single line (a knife-edge wedge, a V
groove and a cylinder that pinch the part in two, a hole tangent to a face, a notch flush with an
end); line-and-arc extrudes and revolves (partial, touching the axis); spline profiles, sweeps
and lofts; holes and tapped holes (blind, drilled, counterbore, countersink, M5-M8 taps, into a
curved face, near and tangent to an edge, crossing); modelled threads (external, fine, partial,
to a shoulder, internal, into a chamfer, at a filleted shoulder); fillets (constant, tangent
chains, convex and concave, variable down to 1e-3 and to 0 at a vertex, corners with equal and
unequal radii, g2 corners); chamfers (two distances, angle, three- and two-edge corners, curved);
shells and offsets; patterns and mirrors (overlapping instances that cut a core free); and
cumulative parts.

A running part grows one tier at a time through `base` (back wall, revolved boss and slot,
spline window, tapped holes, rounds, chamfers, shell, vents), and the last case adds its thread:
it carries every tier. Answers are analytic wherever the geometry has them (Pappus, Steinmetz,
ISO 68-1 basic thread profiles, exact Gauss quadrature of Bezier profiles, inclusion-exclusion
for chamfered corners), otherwise invariants; each `method` gives the derivation, and
tools/kernel-ladder/cases.py (standard-library Python, like tools/oracle-analytic) writes them.
Capabilities SolidCraft lacks are `missing` cases: multi-start threads, thread runout lengths,
fillet corner setbacks.

The golden is the first recording on truck, each tier sorted by its time. SMLib booleans are
not on this branch yet, so the smlib column records "not supported yet" for every case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QWhMwdqJYQKQq8RCLSL1LT
This commit is contained in:
jyviko
2026-10-21 06:32:22 -04:00
parent 208c39461e
commit b249100eae
236 changed files with 8447 additions and 0 deletions
@@ -0,0 +1,24 @@
{
"sources": [],
"what": "a 60x40x20 box: the stock every later tier starts from",
"source": "analytic",
"method": "V = 60*40*20; A = 2(60*40 + 60*20 + 40*20); a box has 6 faces, 12 edges, 8 vertices",
"body_count": 1,
"volume_mm3": 48000,
"area_mm2": 8800,
"faces": 6,
"edges": 12,
"vertices": 8,
"bbox": {
"min": [
0,
0,
0
],
"max": [
60,
40,
20
]
}
}
@@ -0,0 +1,18 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
0,
0,
0
],
"length": 60,
"width": 40,
"height": 20,
"body_name": "Part"
}
}
]
}
@@ -0,0 +1,22 @@
{
"sources": [],
"what": "a cylinder r10 h30",
"source": "analytic",
"method": "V = pi r^2 h; A = 2 pi r^2 + 2 pi r h; faces: two disks and one whole cylinder",
"body_count": 1,
"volume_mm3": 9424.777960769,
"area_mm2": 2513.274122872,
"faces": 3,
"bbox": {
"min": [
-10,
-10,
0
],
"max": [
10,
10,
30
]
}
}
@@ -0,0 +1,16 @@
{
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
0,
0,
0
],
"radius": 10,
"height": 30
}
}
]
}
@@ -0,0 +1,22 @@
{
"sources": [],
"what": "a cone r10 h30 (no cone primitive: a revolved right triangle, its axis a sketch line)",
"source": "analytic",
"method": "V = pi r^2 h / 3; A = pi r^2 + pi r sqrt(r^2 + h^2); a disk and the cone face",
"body_count": 1,
"volume_mm3": 3141.59265359,
"area_mm2": 1307.618091939,
"faces": 2,
"bbox": {
"min": [
-10,
-10,
0
],
"max": [
10,
10,
30
]
}
}
@@ -0,0 +1,61 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
10,
0
],
[
0,
30
]
],
"ids": [
"b",
"s",
"ax"
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "ax"
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a cone frustum r10 -> r5, h20 (revolved trapezoid)",
"source": "analytic",
"method": "V = pi h/3 (R^2 + R r + r^2); A = pi (R^2 + r^2) + pi (R + r) sqrt((R-r)^2 + h^2)",
"body_count": 1,
"volume_mm3": 3665.191429188,
"area_mm2": 1364.182957455,
"faces": 3
}
@@ -0,0 +1,66 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
10,
0
],
[
5,
20
],
[
0,
20
]
],
"ids": [
"b",
"s",
"t",
"ax"
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "ax"
}
}
]
}
@@ -0,0 +1,22 @@
{
"sources": [],
"what": "a sphere r10",
"source": "analytic",
"method": "V = 4/3 pi r^3; A = 4 pi r^2; one face",
"body_count": 1,
"volume_mm3": 4188.790204786,
"area_mm2": 1256.637061436,
"faces": 1,
"bbox": {
"min": [
-10,
-10,
-10
],
"max": [
10,
10,
10
]
}
}
@@ -0,0 +1,10 @@
{
"commands": [
{
"command": "solid.sphere",
"params": {
"radius": 10
}
}
]
}
@@ -0,0 +1,22 @@
{
"sources": [],
"what": "a torus R20 r5",
"source": "analytic",
"method": "V = 2 pi^2 R r^2; A = 4 pi^2 R r; one face",
"body_count": 1,
"volume_mm3": 9869.604401089,
"area_mm2": 3947.841760436,
"faces": 1,
"bbox": {
"min": [
-25,
-25,
-5
],
"max": [
25,
25,
5
]
}
}
@@ -0,0 +1,11 @@
{
"commands": [
{
"command": "solid.torus",
"params": {
"major": 20,
"minor": 5
}
}
]
}
@@ -0,0 +1,23 @@
{
"sources": [],
"what": "a 60x40x10 box joined exactly on the stock's top face: one 60x40x30 box",
"source": "analytic",
"method": "the boxes share the whole face z=20 and every side is coplanar: the union is the box 60x40x30, V = 72000, its coplanar sides merged into 6 faces",
"body_count": 1,
"volume_mm3": 72000.0,
"faces": 6,
"edges": 12,
"vertices": 8,
"bbox": {
"min": [
0,
0,
0
],
"max": [
60,
40,
30
]
}
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
0,
0,
20
],
"length": 60,
"width": 40,
"height": 10,
"operation": "join",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "two 60x40x20 boxes overlapping 30x20 in plan, tops and bottoms coplanar",
"source": "analytic",
"method": "V = 2*48000 - 30*20*20; the plan outline is an 8-sided polygon: 8 sides + top + bottom",
"body_count": 1,
"volume_mm3": 84000,
"faces": 10
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
30,
20,
0
],
"length": 60,
"width": 40,
"height": 20,
"operation": "join",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a 20x20x10 pocket whose tool's top is the stock's top face",
"source": "analytic",
"method": "V = 48000 - 20*20*10; faces: 6 + 4 pocket walls + pocket floor",
"body_count": 1,
"volume_mm3": 44000,
"faces": 11
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
20,
10,
10
],
"length": 20,
"width": 20,
"height": 10,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [],
"what": "a cut tool that shares only the top front edge of the stock",
"source": "analytic",
"method": "the tool touches the stock only along the edge y=0, z=20: nothing is removed, the box stays as it was",
"body_count": 1,
"volume_mm3": 48000,
"faces": 6,
"edges": 12,
"vertices": 8
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
0,
-10,
20
],
"length": 60,
"width": 10,
"height": 10,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [],
"what": "an inverted cone whose apex touches the middle of the top face, cut",
"source": "analytic",
"method": "the cone (apex (30,20,20), base r10 at z=30) meets the stock only at its apex: the cut removes nothing",
"body_count": 1,
"volume_mm3": 48000,
"faces": 6,
"edges": 12,
"vertices": 8
}
@@ -0,0 +1,66 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
30,
20,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
20
],
[
10,
30
],
[
0,
30
]
],
"ids": [
"s",
"t",
"ax"
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "ax",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [],
"what": "a cylinder r10 along X lying on the top face (tangent along a line), cut",
"source": "analytic",
"method": "the cylinder (axis y=20, z=30) touches the top face z=20 only along the line y=20: nothing is removed",
"body_count": 1,
"volume_mm3": 48000,
"faces": 6,
"edges": 12,
"vertices": 8
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
-5,
20,
30
],
"radius": 10,
"height": 70,
"axis": "X",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [],
"what": "a cylinder r10 along X 1e-3 mm above the top face, cut",
"source": "analytic",
"method": "gap 1e-3 mm: no contact, nothing is removed",
"body_count": 1,
"volume_mm3": 48000,
"faces": 6,
"edges": 12,
"vertices": 8
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
-5,
20,
30.001
],
"radius": 10,
"height": 70,
"axis": "X",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [],
"what": "a cylinder r10 along X 1e-6 mm above the top face, cut",
"source": "analytic",
"method": "gap 1e-6 mm: no contact; even a kernel that treats it as touching must remove nothing",
"body_count": 1,
"volume_mm3": 48000,
"faces": 6,
"edges": 12,
"vertices": 8
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
-5,
20,
30.000001
],
"radius": 10,
"height": 70,
"axis": "X",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a cylinder r10 along X dipping 1e-3 mm into the top face, cut: a groove 1e-3 deep",
"source": "analytic",
"method": "circular segment of depth h=1e-3 in r=10: A = r^2 acos((r-h)/r) - (r-h) sqrt(2rh - h^2) = 1.886e-04 mm^2, times 60; the groove runs the whole length, so it splits the top face in two and adds one cylinder face: 6 - 1 + 2 + 1",
"body_count": 1,
"volume_mm3": 47999.988686461,
"faces": 8
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
-5,
20,
29.999
],
"radius": 10,
"height": 70,
"axis": "X",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,8 @@
{
"sources": [],
"what": "a cylinder r10 along X dipping 1e-6 mm into the top face, cut",
"source": "invariants",
"method": "a groove 1e-6 deep (V change ~1e-8) is at the kernels' tolerance: a groove or no change are both right; graded: one valid body, V = 48000",
"body_count": 1,
"volume_mm3": 48000
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
-5,
20,
29.999999
],
"radius": 10,
"height": 70,
"axis": "X",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a sphere r10 sitting in a through hole r10 at the top edge (tangent along the hole's top circle), cut",
"source": "analytic",
"method": "the lower half of the sphere lies inside the hole, tangent to its wall along the circle z=20, the upper half is outside: the sphere removes nothing more; V = 48000 - pi 100 20",
"body_count": 1,
"volume_mm3": 41716.81469282,
"faces": 7
}
@@ -0,0 +1,36 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
30,
20,
-1
],
"radius": 10,
"height": 22,
"operation": "cut",
"targets": [
"Part"
]
}
},
{
"command": "solid.sphere",
"params": {
"radius": 10,
"center": [
30,
20,
20
],
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a blind hole r10 10 deep, then a sphere r10 centred on its floor: the floor disk vanishes exactly",
"source": "analytic",
"method": "the sphere's equator is the floor's edge circle (tangent to the hole wall along it): removed = pi r^2 10 + 2/3 pi r^3; faces 6 + wall + bowl",
"body_count": 1,
"volume_mm3": 42764.012244017,
"faces": 8
}
@@ -0,0 +1,36 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
30,
20,
10
],
"radius": 10,
"height": 11,
"operation": "cut",
"targets": [
"Part"
]
}
},
{
"command": "solid.sphere",
"params": {
"radius": 10,
"center": [
30,
20,
10
],
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a 10x4 notch through a cylinder r10 across its +X side (where the seam lies)",
"source": "analytic",
"method": "removed section = int_-2^2 (sqrt(100 - y^2) - 5) dy = 19.731710021 (Gauss), times 20; faces: cylinder, 2 disks, 3 notch planes",
"body_count": 1,
"volume_mm3": 5888.551106754,
"faces": 6
}
@@ -0,0 +1,34 @@
{
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
0,
0,
0
],
"radius": 10,
"height": 20,
"body_name": "Part"
}
},
{
"command": "solid.box",
"params": {
"corner": [
5,
-2,
-1
],
"length": 10,
"width": 4,
"height": 22,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a 4x4 square post cut off the top of a sphere r10 through its pole",
"source": "analytic",
"method": "removed = int over the square |x|,|y|<=2 of (sqrt(100 - x^2 - y^2) - 5) = 77.846302682 (nested Gauss); faces: sphere, 4 sides, floor z=5",
"body_count": 1,
"volume_mm3": 4110.943902105,
"faces": 6
}
@@ -0,0 +1,28 @@
{
"commands": [
{
"command": "solid.sphere",
"params": {
"radius": 10,
"body_name": "Part"
}
},
{
"command": "solid.box",
"params": {
"corner": [
-2,
-2,
5
],
"length": 4,
"width": 4,
"height": 6,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,11 @@
{
"sources": [],
"what": "a triangular prism cut whose slope meets the bottom face along one line (a knife edge), its other faces on the stock's",
"source": "analytic",
"method": "the tool removes the half above the plane through the edge x=0,z=0 and the edge x=60,z=20: a wedge 60x40x20/2 = 24000 with a knife edge at x=0, z=0",
"body_count": 1,
"volume_mm3": 24000.0,
"faces": 5,
"edges": 9,
"vertices": 6
}
@@ -0,0 +1,61 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
41,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
60,
20
],
[
0,
20
]
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 42,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,8 @@
{
"sources": [],
"what": "a V groove whose apex touches the bottom face along a line, cut through: two pieces",
"source": "analytic",
"method": "apex (30, 0) on the bottom face, flanks through (18, 20) and (42, 20): removed triangle 24 wide x 20 high, times 40; the pieces meet only along the line x=30, z=0, so the regularized result is two solids",
"body_count": 2,
"volume_mm3": 38400.0
}
@@ -0,0 +1,61 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
41,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
15,
25
],
[
30,
0
],
[
45,
25
]
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 42,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,8 @@
{
"sources": [],
"what": "a cylinder r10 along X tangent to both the top and bottom faces, cut: two pieces with zero-angle cusps",
"source": "analytic",
"method": "the cylinder (axis y=20, z=10) spans the full height at y=20: removed pi r^2 60; the halves meet only along the lines y=20, z=0 and z=20: two solids",
"body_count": 2,
"volume_mm3": 29150.444078461
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
-5,
20,
10
],
"radius": 10,
"height": 70,
"axis": "X",
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,8 @@
{
"sources": [],
"what": "a through hole r10 tangent to the front face: the front face pinched to a line",
"source": "analytic",
"method": "the hole touches y=0 along the line x=30: removed pi r^2 20, the material behind keeps one body",
"body_count": 1,
"volume_mm3": 41716.81469282
}
@@ -0,0 +1,21 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.cylinder",
"params": {
"base": [
30,
10,
-1
],
"radius": 10,
"height": 22,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a notch 40x20 through the height, its end flush with the stock's end face: a U",
"source": "analytic",
"method": "the tool's end face is x=60, the stock's: V = 48000 - 16000; the U outline has 8 sides, + top + bottom",
"body_count": 1,
"volume_mm3": 32000,
"faces": 10
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
20,
10,
-1
],
"length": 40,
"width": 20,
"height": 22,
"operation": "cut",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,21 @@
{
"sources": [],
"what": "the running part: a 60x10x15 back wall joined on the stock's top, flush with its back and ends",
"source": "analytic",
"method": "an L section (6 sides) extruded along X: 8 faces; the coplanar back and end faces merge",
"body_count": 1,
"volume_mm3": 57000,
"faces": 8,
"bbox": {
"min": [
0,
0,
0
],
"max": [
60,
40,
35
]
}
}
@@ -0,0 +1,22 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.box",
"params": {
"corner": [
0,
30,
20
],
"length": 60,
"width": 10,
"height": 15,
"operation": "join",
"targets": [
"Part"
]
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a 60x40 profile with a semicircular end r20, extruded 20",
"source": "analytic",
"method": "A = 60*40 + pi 20^2 / 2; V = 20 A; sides: 3 planes and a half cylinder",
"body_count": 1,
"volume_mm3": 60566.370614359,
"area_mm2": 10513.274122872,
"faces": 6
}
@@ -0,0 +1,60 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
60,
40
],
[
0,
40
],
[
0,
0
],
[
60,
0
]
]
}
},
{
"command": "sketch.arc.three_point",
"params": {
"start": [
60,
0
],
"end": [
60,
40
],
"through": [
80,
20
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 20
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "an annulus r20/r10 extruded 15",
"source": "analytic",
"method": "V = pi (20^2 - 10^2) 15; faces: two annuli, two cylinders",
"body_count": 1,
"volume_mm3": 14137.166941154,
"area_mm2": 4712.388980385,
"faces": 4
}
@@ -0,0 +1,48 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 20
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 10
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 15,
"profiles": [
{
"point": [
15,
0
]
}
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a circle r10 extruded 20 with a -5 deg taper (inward): a cone frustum",
"source": "analytic",
"method": "positive taper grows outward (tests/oracle/05): top radius 10 - 20 tan5 = 8.250226729; V = pi h/3 (R^2 + R r + r^2)",
"body_count": 1,
"volume_mm3": 5247.894567706,
"faces": 3
}
@@ -0,0 +1,31 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 10
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 20,
"taper": -5
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a 10x30 rectangle 10 mm off the Z axis revolved 360 deg: a tube",
"source": "analytic",
"method": "V = pi (20^2 - 10^2) 30; faces: two annuli, two cylinders",
"body_count": 1,
"volume_mm3": 28274.333882308,
"area_mm2": 7539.822368616,
"faces": 4
}
@@ -0,0 +1,60 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
10,
0
],
[
20,
0
],
[
20,
30
],
[
10,
30
]
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "Z"
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a quarter disk r20 with an edge on the Z axis revolved 360 deg: a hemisphere",
"source": "analytic",
"method": "V = 2/3 pi r^3; A = 2 pi r^2 + pi r^2; the profile edge on the axis makes no face",
"body_count": 1,
"volume_mm3": 16755.160819146,
"area_mm2": 3769.911184308,
"faces": 2
}
@@ -0,0 +1,72 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
20
],
[
0,
0
],
[
20,
0
]
]
}
},
{
"command": "sketch.arc.center_point",
"params": {
"center": [
0,
0
],
"start": [
20,
0
],
"end": [
0,
20
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "Z"
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a 10x10 rectangle 10 mm off the axis revolved 90 deg",
"source": "analytic",
"method": "a quarter of the tube: V = (90/360) pi (20^2 - 10^2) 10; faces: 2 ends, 2 cylinders, top, bottom",
"body_count": 1,
"volume_mm3": 2356.194490192,
"faces": 6
}
@@ -0,0 +1,61 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
10,
0
],
[
20,
0
],
[
20,
10
],
[
10,
10
]
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "Z",
"angle": 90
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a 15x20 rectangle on the axis revolved 180 deg: a half cylinder",
"source": "analytic",
"method": "V = pi r^2 h / 2; the two end rectangles are coplanar and meet on the axis: one 30x20 face; + half disks top and bottom + half cylinder",
"body_count": 1,
"volume_mm3": 7068.583470577,
"area_mm2": 2249.336143135,
"faces": 4
}
@@ -0,0 +1,61 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
15,
0
],
[
15,
20
],
[
0,
20
]
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "Z",
"angle": 180
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a slot (centres 40 apart, width 20) extruded 10",
"source": "analytic",
"method": "A = 40*20 + pi 10^2; faces: 2 planes, 2 half cylinders, top, bottom",
"body_count": 1,
"volume_mm3": 11141.59265359,
"area_mm2": 3656.637061436,
"faces": 6
}
@@ -0,0 +1,34 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.slot.center_to_center",
"params": {
"p0": [
0,
0
],
"p1": [
40,
0
],
"width": 20
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 10
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "the running part: a revolved boss r8 h10 joined on the top, a slot 15x8 cut through the base",
"source": "analytic",
"method": "back-wall part (57000) + pi 8^2 10 - 20 (15*8 + pi 4^2); faces 8 + boss side and top + slot's 2 planes and 2 half cylinders",
"body_count": 1,
"volume_mm3": 55605.309649149,
"faces": 14
}
@@ -0,0 +1,107 @@
{
"base": "../../02-booleans/020-part-back-wall",
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
15,
15,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
20
],
[
8,
20
],
[
8,
30
],
[
0,
30
]
],
"ids": [
"b",
"s",
"t",
"ax"
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "ax",
"operation": "join",
"targets": [
"Part"
],
"name": "Boss"
}
},
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.slot.center_to_center",
"params": {
"p0": [
35,
10
],
"p1": [
50,
10
],
"width": 8
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 20,
"operation": "cut",
"targets": [
"Part"
],
"name": "Slot"
}
}
]
}
@@ -0,0 +1,21 @@
{
"sources": [],
"what": "a profile closed by a cubic Bezier arch (control-point spline, 4 points), extruded 10",
"source": "analytic",
"method": "a 4-point cubic control-point spline is one Bezier segment; A = 400 + int (y-10) dx over the arch (Green, exact Gauss) = 820.000000000; max y = 10 + 0.75*20",
"body_count": 1,
"volume_mm3": 8200.0,
"faces": 6,
"bbox": {
"min": [
0,
0,
0
],
"max": [
40,
25,
10
]
}
}
@@ -0,0 +1,66 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
10
],
[
0,
0
],
[
40,
0
],
[
40,
10
]
]
}
},
{
"command": "sketch.spline.control_point",
"params": {
"points": [
[
40,
10
],
[
30,
30
],
[
10,
30
],
[
0,
10
]
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 10
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a profile with a Bezier side (r from 20 to 15 over z 0..30) revolved 360 deg about Z",
"source": "analytic",
"method": "z(t) = 30 t is linear, so V = pi int r(t)^2 z'(t) dt (exact Gauss) = 34131.160186501; A = disks pi 20^2 + pi 15^2 + 2 pi int r |B'| dt",
"body_count": 1,
"volume_mm3": 34131.160186501,
"area_mm2": 5856.98245447,
"faces": 3
}
@@ -0,0 +1,82 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
15,
30
],
[
0,
30
],
[
0,
0
],
[
20,
0
]
]
}
},
{
"command": "sketch.spline.control_point",
"params": {
"points": [
[
20,
0
],
[
30,
10
],
[
10,
20
],
[
15,
30
]
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.revolve",
"params": {
"axis": "Z"
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a pipe d4 along a planar Bezier path",
"source": "analytic",
"method": "a disk swept square to a planar path whose curvature radius stays above 20.85 > 2: V = pi r^2 L, A = 2 pi r L + 2 pi r^2, L = 46.220575543",
"body_count": 1,
"volume_mm3": 580.824882281,
"area_mm2": 605.95762351
}
@@ -0,0 +1,64 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Path"
}
},
{
"command": "sketch.spline.control_point",
"params": {
"points": [
[
0,
0
],
[
0,
20
],
[
20,
20
],
[
20,
40
]
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.pipe",
"params": {
"path_sketch": "Path",
"path": [
"s1"
],
"diameter": 4
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a 4x4 square swept along the same Bezier path",
"source": "analytic",
"method": "the square's centre is on the planar path and it stays square to it: V = A L; side faces: the inner and outer walls have s(L -/+ a dtheta), the two others s L each, total 4 s L; + 2 ends",
"body_count": 1,
"volume_mm3": 739.529208687,
"area_mm2": 771.529208687
}
@@ -0,0 +1,88 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
},
"name": "Path"
}
},
{
"command": "sketch.spline.control_point",
"params": {
"points": [
[
0,
0
],
[
0,
20
],
[
20,
20
],
[
20,
40
]
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": "XY",
"name": "Square"
}
},
{
"command": "sketch.rectangle.center",
"params": {
"center": [
0,
0
],
"corner": [
2,
2
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.sweep",
"params": {
"sketch": "Square",
"path_sketch": "Path",
"path": [
"s1"
]
}
}
]
}
@@ -0,0 +1,10 @@
{
"sources": [],
"what": "a loft between a 40 square at z=0 and a 20 square at z=30",
"source": "analytic",
"method": "two sections loft ruled: a square frustum, V = h/3 (A0 + A1 + sqrt(A0 A1)); sides 4 trapezoids (40+20)/2 * sqrt(30^2+10^2)",
"body_count": 1,
"volume_mm3": 28000.0,
"area_mm2": 5794.733192202,
"faces": 6
}
@@ -0,0 +1,81 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY",
"name": "S0"
}
},
{
"command": "sketch.rectangle.center",
"params": {
"center": [
0,
0
],
"corner": [
20,
20
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
30
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "S1"
}
},
{
"command": "sketch.rectangle.center",
"params": {
"center": [
0,
0
],
"corner": [
10,
10
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.loft",
"params": {
"sections": [
{
"sketch": "S0"
},
{
"sketch": "S1"
}
]
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a loft between circles r20 at z=0 and r10 at z=30",
"source": "analytic",
"method": "a ruled loft between coaxial circles is a cone frustum: V = pi h/3 (R^2 + R r + r^2)",
"body_count": 1,
"volume_mm3": 21991.148575129,
"faces": 3
}
@@ -0,0 +1,75 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY",
"name": "S0"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 20
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
30
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "S1"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 10
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.loft",
"params": {
"sections": [
{
"sketch": "S0"
},
{
"sketch": "S1"
}
]
}
}
]
}
@@ -0,0 +1,8 @@
{
"sources": [],
"what": "a smooth loft through circles r20, r10, r20 at z = 0, 20, 40",
"source": "invariants",
"method": "the interpolation between sections is the loft's own: no closed-form volume; one valid body bounded by two disks and one lofted face",
"body_count": 1,
"faces": 3
}
@@ -0,0 +1,115 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY",
"name": "S0"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 20
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
20
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "S1"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 10
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
40
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "S2"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 20
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.loft",
"params": {
"sections": [
{
"sketch": "S0"
},
{
"sketch": "S1"
},
{
"sketch": "S2"
}
]
}
}
]
}
@@ -0,0 +1,7 @@
{
"sources": [],
"what": "a loft from a 40 square at z=0 to a circle r10 at z=30",
"source": "invariants",
"method": "sections with different edge counts: the matching is the loft's own; one valid body",
"body_count": 1
}
@@ -0,0 +1,78 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY",
"name": "S0"
}
},
{
"command": "sketch.rectangle.center",
"params": {
"center": [
0,
0
],
"corner": [
20,
20
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
0,
30
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
1,
0
]
},
"name": "S1"
}
},
{
"command": "sketch.circle.center",
"params": {
"center": [
0,
0
],
"radius": 10
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.loft",
"params": {
"sections": [
{
"sketch": "S0"
},
{
"sketch": "S1"
}
]
}
}
]
}
@@ -0,0 +1,7 @@
{
"sources": [],
"what": "a closed periodic fit-point spline through 6 points, extruded 10",
"source": "invariants",
"method": "the fit's parametrisation is the spline's own: no closed-form area, and how many side faces a periodic spline makes is the kernel's own; one valid body",
"body_count": 1
}
@@ -0,0 +1,52 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY"
}
},
{
"command": "sketch.spline.fit_point",
"params": {
"points": [
[
20,
0
],
[
10,
17
],
[
-10,
17
],
[
-20,
0
],
[
-10,
-17
],
[
10,
-17
]
],
"periodic": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 10
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "the running part: a Bezier-arched window cut through the back wall",
"source": "analytic",
"method": "the arch over z=22 from x=20 to 40 rises to z = 22 + 0.75*12 = 31, under the wall top (35): removed 10 * 133.200000000; + window floor and arch faces",
"body_count": 1,
"volume_mm3": 54273.309649149,
"faces": 16
}
@@ -0,0 +1,80 @@
{
"base": "../../03-analytic-profiles/009-part-boss-and-slot",
"commands": [
{
"command": "sketch.create",
"params": {
"plane": {
"origin": [
0,
40,
0
],
"x_dir": [
1,
0,
0
],
"y_dir": [
0,
0,
1
]
}
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
20,
22
],
[
40,
22
]
]
}
},
{
"command": "sketch.spline.control_point",
"params": {
"points": [
[
40,
22
],
[
37,
34
],
[
23,
34
],
[
20,
22
]
]
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 10,
"operation": "cut",
"targets": [
"Part"
],
"name": "Window"
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a d10 through hole in the stock's top",
"source": "analytic",
"method": "removed pi 5^2 20; + one cylinder face",
"body_count": 1,
"volume_mm3": 46429.203673205,
"faces": 7
}
@@ -0,0 +1,16 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.hole",
"params": {
"position": [
30,
20,
20
],
"diameter": 10
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a d10 blind hole 10 deep, flat bottom",
"source": "analytic",
"method": "removed pi 5^2 10; + wall and floor",
"body_count": 1,
"volume_mm3": 47214.601836603,
"faces": 8
}
@@ -0,0 +1,17 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.hole",
"params": {
"position": [
30,
20,
20
],
"diameter": 10,
"depth": 10
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a d10 drilled hole 10 deep to the shoulder with a 118 deg point",
"source": "analytic",
"method": "depth to the shoulder (tests/oracle/18); point cone h = r / tan59; removed pi r^2 10 + pi r^2 h/3; + wall and cone",
"body_count": 1,
"volume_mm3": 47135.949365496,
"faces": 8
}
@@ -0,0 +1,19 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.hole",
"params": {
"position": [
30,
20,
20
],
"diameter": 10,
"depth": 10,
"type": "drilled",
"tip_angle": 118
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a counterbored hole: d6.6 through, d11 x 6.4 counterbore",
"source": "analytic",
"method": "removed pi 3.3^2 (20 - 6.4) + pi 5.5^2 6.4; + bore, counterbore wall, its floor annulus",
"body_count": 1,
"volume_mm3": 46926.505223898,
"faces": 9
}
@@ -0,0 +1,19 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.hole",
"params": {
"position": [
30,
20,
20
],
"diameter": 6.6,
"type": "counterbore",
"cb_diameter": 11,
"cb_depth": 6.4
}
}
]
}
@@ -0,0 +1,9 @@
{
"sources": [],
"what": "a countersunk hole: d6.6 through, d12 x 90 deg countersink",
"source": "analytic",
"method": "countersink frustum r6 -> r3.3 over (6-3.3)/tan45 = 2.7; + bore below it; + cone and bore faces",
"body_count": 1,
"volume_mm3": 47219.571836181,
"faces": 8
}
@@ -0,0 +1,19 @@
{
"base": "../../01-primitives/001-box",
"commands": [
{
"command": "solid.hole",
"params": {
"position": [
30,
20,
20
],
"diameter": 6.6,
"type": "countersink",
"cs_diameter": 12,
"cs_angle": 90
}
}
]
}

Some files were not shown because too many files have changed in this diff Show More