From bec9db59e6f9fb4fbd102b1dcc66947017365e63 Mon Sep 17 00:00:00 2001 From: Brennen Herbruck Date: Wed, 21 Oct 2026 06:20:27 -0400 Subject: [PATCH] kernel-cases: sweeps loft cases from #96-#3936 (shallow cuts, cones, comb, rails) A shallow loft cut from a slab top face, a loft cut whose sections touch the block sides given in either order, circles lofted into a cone on a turned-over plane, a loft guided by a rail, a circle lofted to a comb outline, a square lofted to a circle, and a circle-to-rectangle loft joined to a cylinder. Co-Authored-By: Claude Sonnet 5.5 --- .../expected.json | 24 +++ .../recipe.json | 146 +++++++++++++++ .../expected.json | 22 +++ .../recipe.json | 171 ++++++++++++++++++ .../expected.json | 22 +++ .../recipe.json | 95 ++++++++++ .../expected.json | 23 +++ .../recipe.json | 92 ++++++++++ .../expected.json | 23 +++ .../recipe.json | 92 ++++++++++ .../expected.json | 21 +++ .../recipe.json | 109 +++++++++++ .../expected.json | 11 ++ .../recipe.json | 115 ++++++++++++ .../expected.json | 11 ++ .../recipe.json | 115 ++++++++++++ .../expected.json | 10 + .../recipe.json | 146 +++++++++++++++ 18 files changed, 1248 insertions(+) create mode 100644 tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/expected.json create mode 100644 tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/recipe.json create mode 100644 tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/expected.json create mode 100644 tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/recipe.json create mode 100644 tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/expected.json create mode 100644 tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/recipe.json create mode 100644 tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/expected.json create mode 100644 tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/recipe.json create mode 100644 tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/expected.json create mode 100644 tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/recipe.json create mode 100644 tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/expected.json create mode 100644 tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/recipe.json create mode 100644 tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/expected.json create mode 100644 tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/recipe.json create mode 100644 tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/expected.json create mode 100644 tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/recipe.json create mode 100644 tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/expected.json create mode 100644 tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/recipe.json diff --git a/tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/expected.json b/tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/expected.json new file mode 100644 index 0000000000..6a6b12c04d --- /dev/null +++ b/tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/expected.json @@ -0,0 +1,24 @@ +{ + "sources": [ + "tangency-labs/solidcraft#201", + "tangency-labs/solidcraft#3371" + ], + "what": "a loft from a circle of radius 5 to a circle of radius 10, 20 mm above, guided by one straight rail through (5,0,0) and (10,0,20)", + "source": "analytic", + "method": "the rail lies on the cone through both circles, so the loft is that cone frustum: V = 20/3 pi (25 + 100 + 50) = 3665.2.", + "body_count": 1, + "volume_mm3": 3665.191429188092, + "faces": 3, + "bbox": { + "min": [ + -10, + -10, + 0 + ], + "max": [ + 10, + 10, + 20 + ] + } +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/recipe.json b/tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/recipe.json new file mode 100644 index 0000000000..023b7fe609 --- /dev/null +++ b/tests/kernel-cases/sweeps/201-loft-one-guide-rail-cone-frustum/recipe.json @@ -0,0 +1,146 @@ +{ + "commands": [ + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "A" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 5 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "B" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 10 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 0, + 1 + ] + }, + "name": "Rail" + } + }, + { + "command": "sketch.line", + "params": { + "points": [ + [ + 5, + 0 + ], + [ + 10, + 20 + ] + ], + "infer": false, + "ids": [ + "r1" + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "A" + }, + { + "sketch": "B" + } + ], + "rails": [ + { + "sketch": "Rail", + "curves": [ + "r1" + ] + } + ], + "operation": "new" + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/expected.json b/tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/expected.json new file mode 100644 index 0000000000..37ff5b5462 --- /dev/null +++ b/tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/expected.json @@ -0,0 +1,22 @@ +{ + "sources": [ + "tangency-labs/solidcraft#2570", + "tangency-labs/solidcraft#3670" + ], + "what": "a loft between a circle and a 20-edge comb outline (not star-shaped from its centroid: the teeth turn the vertex directions back on themselves), 40 mm apart (the circle was wound about ten times, the app froze)", + "source": "invariants", + "method": "no closed form for the circle-to-comb pairing, so only invariants: the loft builds one closed valid solid, and as every ruling joins a point of the comb to a point of the circle, the solid lies in the hull of both sections: bbox x +-18, y -2..18 (the circle r 10 about (0,8) reaches below the comb), z 0..40.", + "body_count": 1, + "bbox": { + "min": [ + -18, + -2, + 0 + ], + "max": [ + 18, + 18, + 40 + ] + } +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/recipe.json b/tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/recipe.json new file mode 100644 index 0000000000..072c4dc8aa --- /dev/null +++ b/tests/kernel-cases/sweeps/2570-loft-circle-to-a-non-star-shaped-comb/recipe.json @@ -0,0 +1,171 @@ +{ + "commands": [ + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Comb" + } + }, + { + "command": "sketch.line", + "params": { + "points": [ + [ + -18, + 0 + ], + [ + 18, + 0 + ], + [ + 18, + 16 + ], + [ + 14, + 16 + ], + [ + 14, + 6 + ], + [ + 10, + 6 + ], + [ + 10, + 16 + ], + [ + 6, + 16 + ], + [ + 6, + 6 + ], + [ + 2, + 6 + ], + [ + 2, + 16 + ], + [ + -2, + 16 + ], + [ + -2, + 6 + ], + [ + -6, + 6 + ], + [ + -6, + 16 + ], + [ + -10, + 16 + ], + [ + -10, + 6 + ], + [ + -14, + 6 + ], + [ + -14, + 16 + ], + [ + -18, + 16 + ] + ], + "infer": false, + "closed": true + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 40.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Round" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 8 + ], + "radius": 10 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Comb" + }, + { + "sketch": "Round" + } + ], + "operation": "new" + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/expected.json b/tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/expected.json new file mode 100644 index 0000000000..9b6ead3ff0 --- /dev/null +++ b/tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/expected.json @@ -0,0 +1,22 @@ +{ + "sources": [ + "tangency-labs/solidcraft#3326", + "tangency-labs/solidcraft#3402" + ], + "what": "a loft from a 20 mm square to a circle of radius 10 offset 20 mm (the loft tool symbol): the loft geometry looked wrong", + "source": "invariants", + "method": "the square and the circle are inscribed in each other (circle r 10 touches the square sides), and the pairing of corners to circle points is not canonical, so only invariants are graded: one closed valid solid inside the hull of both sections, bbox x, y +-10, z 0..20.", + "body_count": 1, + "bbox": { + "min": [ + -10, + -10, + 0 + ], + "max": [ + 10, + 10, + 20 + ] + } +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/recipe.json b/tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/recipe.json new file mode 100644 index 0000000000..fb363842e1 --- /dev/null +++ b/tests/kernel-cases/sweeps/3326-loft-20mm-square-to-a-circle/recipe.json @@ -0,0 +1,95 @@ +{ + "commands": [ + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Square" + } + }, + { + "command": "sketch.rectangle.center", + "params": { + "center": [ + 0, + 0 + ], + "corner": [ + 10, + 10 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Circle" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 10 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Square" + }, + { + "sketch": "Circle" + } + ], + "operation": "new" + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/expected.json b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/expected.json new file mode 100644 index 0000000000..f2da24a452 --- /dev/null +++ b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/expected.json @@ -0,0 +1,23 @@ +{ + "sources": [ + "tangency-labs/solidcraft#3541" + ], + "what": "a loft from a circle of radius 8 to a circle of radius 20, 30 mm below it (sections given small first, the small one drawn on a plane turned over (normal pointing down)): \"a horizontal narrowing is created\" instead of a cone", + "source": "analytic", + "method": "two coaxial circles lofted ruled give a cone frustum whichever way the section planes face: V = h/3 (A1 + A2 + sqrt(A1 A2)) = 10 pi (400 + 64 + 160) = 19603.5; faces: cone and two caps.", + "body_count": 1, + "volume_mm3": 19603.538158400308, + "faces": 3, + "bbox": { + "min": [ + -20, + -20, + 0 + ], + "max": [ + 20, + 20, + 30 + ] + } +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/recipe.json b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/recipe.json new file mode 100644 index 0000000000..4655290f2f --- /dev/null +++ b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-flipped-plane/recipe.json @@ -0,0 +1,92 @@ +{ + "commands": [ + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Big" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 20 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 30.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + -1, + 0 + ] + }, + "name": "Small" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 8 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Small" + }, + { + "sketch": "Big" + } + ], + "operation": "new" + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/expected.json b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/expected.json new file mode 100644 index 0000000000..2b89d02f7e --- /dev/null +++ b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/expected.json @@ -0,0 +1,23 @@ +{ + "sources": [ + "tangency-labs/solidcraft#3541" + ], + "what": "a loft from a circle of radius 8 to a circle of radius 20, 30 mm below it (sections given small first, the small one drawn on a plane facing the same way): \"a horizontal narrowing is created\" instead of a cone", + "source": "analytic", + "method": "two coaxial circles lofted ruled give a cone frustum whichever way the section planes face: V = h/3 (A1 + A2 + sqrt(A1 A2)) = 10 pi (400 + 64 + 160) = 19603.5; faces: cone and two caps.", + "body_count": 1, + "volume_mm3": 19603.538158400308, + "faces": 3, + "bbox": { + "min": [ + -20, + -20, + 0 + ], + "max": [ + 20, + 20, + 30 + ] + } +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/recipe.json b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/recipe.json new file mode 100644 index 0000000000..206685aab9 --- /dev/null +++ b/tests/kernel-cases/sweeps/3541-loft-two-circles-into-a-cone-same-sense/recipe.json @@ -0,0 +1,92 @@ +{ + "commands": [ + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Big" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 20 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 30.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Small" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 8 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Small" + }, + { + "sketch": "Big" + } + ], + "operation": "new" + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/expected.json b/tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/expected.json new file mode 100644 index 0000000000..51c4328dda --- /dev/null +++ b/tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/expected.json @@ -0,0 +1,21 @@ +{ + "sources": [ + "tangency-labs/solidcraft#3936" + ], + "what": "a loft from the circle on top of a cylinder (r 10, height 15) to a 40 x 30 rectangle 30 mm above, joined to the cylinder (builds as a new body in 2 ms, the join never returns)", + "source": "invariants", + "method": "the loft pairing of circle and rectangle is not canonical, so no volume is graded: the join must give one closed valid solid in the hull of the cylinder and both sections, bbox x +-20, y +-15, z 0..45.", + "body_count": 1, + "bbox": { + "min": [ + -20, + -15, + 0 + ], + "max": [ + 20, + 15, + 45 + ] + } +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/recipe.json b/tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/recipe.json new file mode 100644 index 0000000000..d9cb42f0d8 --- /dev/null +++ b/tests/kernel-cases/sweeps/3936-loft-join-circle-to-rectangle-on-a-cylinder/recipe.json @@ -0,0 +1,109 @@ +{ + "commands": [ + { + "command": "solid.cylinder", + "params": { + "radius": 10, + "height": 15, + "base": [ + 0, + 0, + 0 + ], + "axis": "Z", + "body_name": "Post" + } + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 15.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Bottom" + } + }, + { + "command": "sketch.circle.center", + "params": { + "center": [ + 0, + 0 + ], + "radius": 10 + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 45.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Top" + } + }, + { + "command": "sketch.rectangle.center", + "params": { + "center": [ + 0, + 0 + ], + "corner": [ + 20, + 15 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Bottom" + }, + { + "sketch": "Top" + } + ], + "operation": "join" + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/expected.json b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/expected.json new file mode 100644 index 0000000000..b2d59f28e2 --- /dev/null +++ b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/expected.json @@ -0,0 +1,11 @@ +{ + "sources": [ + "tangency-labs/solidcraft#122", + "tangency-labs/solidcraft#96" + ], + "what": "a loft cut through a 100 x 60 x 30 block from its whole 100 x 60 outline at z = 20 (edges flush with the side faces) down to a 10 x 10 pad in a corner at z = 11, sections given pad first (the cut panicked for one order)", + "source": "analytic", + "method": "the loft is a ruled prismatoid between the 100 x 60 rectangle at z = 20 and the 10 x 10 square at z = 11 (corner at (2,2)..(12,12)): V = h/6 (A0 + 4 Am + A1) with h = 9, Am = (110/2) (70/2): V_loft = 20700.0. The top section covers the whole cross-section at z = 20, so the 10 mm slab above it is cut loose from the rest: two bodies, together 180000 - V_loft; the result must not depend on the order of the sections.", + "body_count": 2, + "volume_mm3": 159300.0 +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/recipe.json b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/recipe.json new file mode 100644 index 0000000000..8dd11ee9eb --- /dev/null +++ b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-pad-first/recipe.json @@ -0,0 +1,115 @@ +{ + "commands": [ + { + "command": "solid.box", + "params": { + "length": 100, + "width": 60, + "height": 30, + "corner": [ + 0, + 0, + 0 + ], + "body_name": "Basin" + } + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Top" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 0, + 0 + ], + "p1": [ + 100, + 60 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 11.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Pad" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 2, + 2 + ], + "p1": [ + 12, + 12 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Pad" + }, + { + "sketch": "Top" + } + ], + "operation": "cut", + "targets": [ + "Basin" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/expected.json b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/expected.json new file mode 100644 index 0000000000..d06de6b46a --- /dev/null +++ b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/expected.json @@ -0,0 +1,11 @@ +{ + "sources": [ + "tangency-labs/solidcraft#122", + "tangency-labs/solidcraft#96" + ], + "what": "a loft cut through a 100 x 60 x 30 block from its whole 100 x 60 outline at z = 20 (edges flush with the side faces) down to a 10 x 10 pad in a corner at z = 11, sections given top first (the cut panicked for one order)", + "source": "analytic", + "method": "the loft is a ruled prismatoid between the 100 x 60 rectangle at z = 20 and the 10 x 10 square at z = 11 (corner at (2,2)..(12,12)): V = h/6 (A0 + 4 Am + A1) with h = 9, Am = (110/2) (70/2): V_loft = 20700.0. The top section covers the whole cross-section at z = 20, so the 10 mm slab above it is cut loose from the rest: two bodies, together 180000 - V_loft; the result must not depend on the order of the sections.", + "body_count": 2, + "volume_mm3": 159300.0 +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/recipe.json b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/recipe.json new file mode 100644 index 0000000000..9d633693d1 --- /dev/null +++ b/tests/kernel-cases/sweeps/96-loft-cut-box-sections-top-first/recipe.json @@ -0,0 +1,115 @@ +{ + "commands": [ + { + "command": "solid.box", + "params": { + "length": 100, + "width": 60, + "height": 30, + "corner": [ + 0, + 0, + 0 + ], + "body_name": "Basin" + } + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Top" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 0, + 0 + ], + "p1": [ + 100, + 60 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 11.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Pad" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 2, + 2 + ], + "p1": [ + 12, + 12 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "Top" + }, + { + "sketch": "Pad" + } + ], + "operation": "cut", + "targets": [ + "Basin" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/expected.json b/tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/expected.json new file mode 100644 index 0000000000..7ecce37e74 --- /dev/null +++ b/tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/expected.json @@ -0,0 +1,10 @@ +{ + "sources": [ + "tangency-labs/solidcraft#96" + ], + "what": "a loft cut from a 556.68 x 99 rectangle on the top face of a 900 x 480 x 160 slab down 4 mm to an 80 x 80 square (a kernel panic in healing; the sides are about 0.9 degrees from horizontal)", + "source": "analytic", + "method": "a ruled loft of two rectangles: V = h/6 (A0 + 4 Am + A1) with h = 4, A0 = 556.68 * 99, A1 = 80 * 80, Am = 318.34 * 89.5 = 116984.69 removed from the slab 900 * 480 * 160 = 69120000.", + "body_count": 1, + "volume_mm3": 69003015.30666667 +} \ No newline at end of file diff --git a/tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/recipe.json b/tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/recipe.json new file mode 100644 index 0000000000..eccc24ca3a --- /dev/null +++ b/tests/kernel-cases/sweeps/96-shallow-loft-cut-starting-in-the-top-face/recipe.json @@ -0,0 +1,146 @@ +{ + "commands": [ + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "Base" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 0, + 0 + ], + "p1": [ + 900, + 480 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.extrude", + "params": { + "distance": 160, + "name": "Slab" + } + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 160.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "LoftTop" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 171.66, + 329.34 + ], + "p1": [ + 728.34, + 428.34 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "sketch.create", + "params": { + "plane": { + "origin": [ + 0.0, + 0.0, + 156.0 + ], + "x_dir": [ + 1, + 0, + 0 + ], + "y_dir": [ + 0, + 1, + 0 + ] + }, + "name": "LoftBottom" + } + }, + { + "command": "sketch.rectangle.two_point", + "params": { + "p0": [ + 410, + 338.84 + ], + "p1": [ + 490, + 418.84 + ] + } + }, + { + "command": "sketch.finish", + "params": {} + }, + { + "command": "solid.loft", + "params": { + "sections": [ + { + "sketch": "LoftTop" + }, + { + "sketch": "LoftBottom" + } + ], + "operation": "cut", + "name": "LoftCut" + } + } + ] +} \ No newline at end of file