mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 02:25:55 +00:00
Shell rig: the drain floors, the rounded opening and the arc-sided plate as cases
The shell unit tests that checked geometry become shell rig cases built through commands: the trough and the pocket whose floors fall 1 deg to a central drain (the pyramid made as two triangular prisms intersected, in place of convex_polyhedron; the cavity integrated exactly over the cells where each moved facet is highest, sharp inner corners as the ladder's tier 09), the box opened at a bottom rounded R2 and R2.4 (refused: the rim would have no thickness) and R1.5 (built, exact volume), and the plate with a hole through its arc side. Four action-matrix shells that regressed (issue-616's lid, the ring-cut frame, the filleted shelled box shelled again, the up-down join) get small cases too. The ones that fail today are on KNOWN_FAILING with their cause, and the unit tests are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,21 +39,6 @@ fn shell_with_a_shallow_arc_side() {
|
||||
]));
|
||||
}
|
||||
|
||||
/// Shell of a plate with a hole whose wall meets the plate's arc side: the edge where the two
|
||||
/// cylinders meet is neither a line nor an arc, and is rebuilt through its moved points.
|
||||
#[test]
|
||||
fn shell_with_a_hole_through_a_curved_side() {
|
||||
script(json!([
|
||||
{"command": "sketch.create", "params": {"plane": "XY"}},
|
||||
{"command": "sketch.line", "params": {"points": [[0, 0], [42.5, 0], [42.5, 20.0], [0, 20.0]]}},
|
||||
{"command": "sketch.arc.three_point", "params": {"end": [0, 0], "start": [0, 20.0], "through": [-10.0, 10.0]}},
|
||||
{"command": "sketch.finish", "params": {}},
|
||||
{"command": "solid.extrude", "params": {"distance": 27.5}},
|
||||
{"command": "solid.cylinder", "params": {"axis": [1.0, 0.0, 0.0], "base": [-10.000000000000002, 12.5, 12.5], "height": 17.5, "operation": "cut", "radius": 5.0}},
|
||||
{"command": "solid.shell", "params": {"faces": [[42.5, 10.0, 13.75]], "thickness": 2.0}}
|
||||
]));
|
||||
}
|
||||
|
||||
/// A cut whose end only touches the plate's arc side (#897, robustness seed 14): the end lies
|
||||
/// tangent to the arc at its apex, the direct boolean fails, and the last-resort nudge used to
|
||||
/// push the end into the arc, leaving a sliver of it a tenth of a millimetre wide that a shell
|
||||
|
||||
@@ -2407,124 +2407,6 @@ fn orientation_mesh_reuses_missing_face_check_at_matching_tolerance() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A trough whose floor falls about 1° toward a central drain, the fall starting right at the
|
||||
/// trough edges: four faces meet at each bottom corner (two walls, two fall facets) and at the
|
||||
/// drain (four facets). A tab on one end makes the body non-convex. The moved planes of four
|
||||
/// faces don't meet at one point, so each such corner of the cavity becomes two corners joined
|
||||
/// by a short edge. Checked against the volume integrated by hand.
|
||||
#[test]
|
||||
fn shell_where_four_faces_meet_at_a_corner() {
|
||||
let (w, l, ht, t) = (100.0, 60.0, 40.0, 2.0);
|
||||
// Drain depth: the long facets fall 1°.
|
||||
let h = 30.0 * 1f64.to_radians().tan();
|
||||
let facet = |n: Vec3, p: Vec3| {
|
||||
let n = n.normalized().unwrap();
|
||||
HalfSpace { n, d: n.dot(p) }
|
||||
};
|
||||
let facets = [
|
||||
facet(Vec3::new(0.0, -h, -30.0), Vec3::ZERO),
|
||||
facet(Vec3::new(0.0, h, -30.0), Vec3::new(0.0, l, 0.0)),
|
||||
facet(Vec3::new(-h, 0.0, -50.0), Vec3::ZERO),
|
||||
facet(Vec3::new(h, 0.0, -50.0), Vec3::new(w, 0.0, 0.0)),
|
||||
];
|
||||
let mut hs = vec![
|
||||
HalfSpace { n: -Vec3::X, d: 0.0 },
|
||||
HalfSpace { n: Vec3::X, d: w },
|
||||
HalfSpace { n: -Vec3::Y, d: 0.0 },
|
||||
HalfSpace { n: Vec3::Y, d: l },
|
||||
HalfSpace { n: Vec3::Z, d: ht },
|
||||
];
|
||||
hs.extend(facets);
|
||||
let trough = convex_polyhedron(&hs).unwrap();
|
||||
let pyramid = w * l * h / 3.0;
|
||||
assert!(rel(measure(&trough).unwrap().volume, w * l * ht + pyramid) < 1e-9);
|
||||
let tab = box_solid(Vec3::new(w, 20.0, 20.0), Vec3::new(w + 20.0, 40.0, ht)).unwrap();
|
||||
let body = boolean(&trough, &tab, BoolOp::Union).unwrap().unwrap();
|
||||
let s = shell(&body, &[Vec3::new(50.0, 30.0, ht)], t).unwrap();
|
||||
// The cavity: the walls in by t, above the floor facets moved in by t (midpoint rule; the
|
||||
// floor is linear between its creases).
|
||||
let floor = |x: f64, y: f64| facets.iter().map(|f| (f.d - t - f.n.x * x - f.n.y * y) / f.n.z).fold(f64::NEG_INFINITY, f64::max);
|
||||
let (nx, ny) = (960, 560);
|
||||
let (dx, dy) = ((w - 2.0 * t) / nx as f64, (l - 2.0 * t) / ny as f64);
|
||||
let mut cavity = 0.0;
|
||||
for i in 0..nx {
|
||||
for j in 0..ny {
|
||||
cavity += (ht - floor(t + (i as f64 + 0.5) * dx, t + (j as f64 + 0.5) * dy)) * dx * dy;
|
||||
}
|
||||
}
|
||||
let tab_cavity = 20.0 * (20.0 - 2.0 * t) * (20.0 - t);
|
||||
let want = w * l * ht + pyramid + 8000.0 - cavity - tab_cavity;
|
||||
let m = measure(&s).unwrap();
|
||||
assert!(rel(m.volume, want) < 1e-5, "{} vs {want}", m.volume);
|
||||
}
|
||||
|
||||
/// The same trough cut as a pocket into a slab (four faces meet at each concave corner of the
|
||||
/// pocket floor), shelled with its top open.
|
||||
#[test]
|
||||
fn shell_of_a_pocket_whose_floor_falls_to_a_drain() {
|
||||
let (px, py, pw, pl, top, depth, t) = (20.0, 15.0, 100.0, 60.0, 50.0, 30.0, 3.0);
|
||||
let h = 30.0 * 1f64.to_radians().tan();
|
||||
let z0 = top - depth;
|
||||
let facet = |n: Vec3, p: Vec3| {
|
||||
let n = n.normalized().unwrap();
|
||||
HalfSpace { n, d: n.dot(p) }
|
||||
};
|
||||
let facets = [
|
||||
facet(Vec3::new(0.0, -h, -30.0), Vec3::new(px, py, z0)),
|
||||
facet(Vec3::new(0.0, h, -30.0), Vec3::new(px, py + pl, z0)),
|
||||
facet(Vec3::new(-h, 0.0, -50.0), Vec3::new(px, py, z0)),
|
||||
facet(Vec3::new(h, 0.0, -50.0), Vec3::new(px + pw, py, z0)),
|
||||
];
|
||||
let mut hs = vec![
|
||||
HalfSpace { n: -Vec3::X, d: -px },
|
||||
HalfSpace { n: Vec3::X, d: px + pw },
|
||||
HalfSpace { n: -Vec3::Y, d: -py },
|
||||
HalfSpace { n: Vec3::Y, d: py + pl },
|
||||
HalfSpace { n: Vec3::Z, d: top + 10.0 },
|
||||
];
|
||||
hs.extend(facets);
|
||||
let pocket = convex_polyhedron(&hs).unwrap();
|
||||
let slab = box_solid(Vec3::ZERO, Vec3::new(140.0, 90.0, top)).unwrap();
|
||||
let basin = boolean(&slab, &pocket, BoolOp::Cut).unwrap().unwrap();
|
||||
let pocket_vol = pw * pl * depth + pw * pl * h / 3.0;
|
||||
assert!(rel(measure(&basin).unwrap().volume, 140.0 * 90.0 * top - pocket_vol) < 1e-9);
|
||||
let s = shell(&basin, &[Vec3::new(5.0, 5.0, top)], t).unwrap();
|
||||
// The cavity's columns: from t up to the top, or up to the pocket floor moved down by t
|
||||
// inside the pocket's walls moved out by t.
|
||||
let floor = |x: f64, y: f64| facets.iter().map(|f| (f.d + t - f.n.x * x - f.n.y * y) / f.n.z).fold(f64::NEG_INFINITY, f64::max);
|
||||
let (nx, ny) = (1340, 840);
|
||||
let (dx, dy) = ((140.0 - 2.0 * t) / nx as f64, (90.0 - 2.0 * t) / ny as f64);
|
||||
let mut cavity = 0.0;
|
||||
for i in 0..nx {
|
||||
for j in 0..ny {
|
||||
let (x, y) = (t + (i as f64 + 0.5) * dx, t + (j as f64 + 0.5) * dy);
|
||||
let inside = x > px - t && x < px + pw + t && y > py - t && y < py + pl + t;
|
||||
let roof = if inside { floor(x, y) } else { top };
|
||||
cavity += (roof - t) * dx * dy;
|
||||
}
|
||||
}
|
||||
let want = 140.0 * 90.0 * top - pocket_vol - cavity;
|
||||
let m = measure(&s).unwrap();
|
||||
assert!(rel(m.volume, want) < 1e-4, "{} vs {want}", m.volume);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shell_open_beside_a_round_as_large_as_the_wall_is_refused() {
|
||||
// Opening the bottom of a box whose bottom outline is rounded: the cavity's side walls stand
|
||||
// the thickness in from the outside, where a round at least that large meets the bottom, so
|
||||
// the rim would have no thickness. Smaller rounds leave a rim.
|
||||
let b = box_solid(Vec3::ZERO, Vec3::new(40.0, 30.0, 10.0)).unwrap();
|
||||
let loop_ = [Vec3::new(20.0, 0.0, 0.0), Vec3::new(40.0, 15.0, 0.0), Vec3::new(20.0, 30.0, 0.0), Vec3::new(0.0, 15.0, 0.0)];
|
||||
let bottom = [Vec3::new(20.0, 15.0, 0.0)];
|
||||
for r in [2.0, 2.4] {
|
||||
let f = fillet(&b, &loop_, r).unwrap();
|
||||
let e = shell(&f, &bottom, 2.0).unwrap_err();
|
||||
assert!(e.to_string().starts_with("the operation failed: not supported yet: the rim"), "{r}: {e}");
|
||||
}
|
||||
let f = fillet(&b, &loop_, 1.5).unwrap();
|
||||
assert!(shell(&f, &bottom, 2.0).unwrap().validity().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loft_joined_onto_a_box_top_is_one_shell() {
|
||||
// #396: a loft from a Ø12 circle on the box top (z = 20) to a hexagon at z = 35. The union
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"sources": [
|
||||
"tangency-labs/solidcraft#316"
|
||||
],
|
||||
"what": "a 40 x 30 x 10 box, its bottom outline rounded R2.4, shelled 2 mm open at the bottom: the cavity's walls stand 2 in, where the round meets the bottom, so the rim would have no thickness: refused, naming the rim",
|
||||
"source": "analytic",
|
||||
"method": "the open bottom's rim runs from the round's contact with the bottom (r = 2.4 in from the outside) to the cavity's wall (2 in): the round's contact lies past the wall, so there is no rim; refused",
|
||||
"outcome": "refused",
|
||||
"refusal": "not supported yet: the rim"
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 40,
|
||||
"width": 30,
|
||||
"height": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.fillet",
|
||||
"params": {
|
||||
"edges": [
|
||||
[
|
||||
20,
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
40,
|
||||
15,
|
||||
0
|
||||
],
|
||||
[
|
||||
20,
|
||||
30,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
15,
|
||||
0
|
||||
]
|
||||
],
|
||||
"radius": 2.4,
|
||||
"tangent_chain": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
20,
|
||||
15,
|
||||
0
|
||||
]
|
||||
],
|
||||
"thickness": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"sources": [
|
||||
"tangency-labs/solidcraft#316"
|
||||
],
|
||||
"what": "a 40 x 30 x 10 box, its bottom outline rounded R2, shelled 2 mm open at the bottom: the cavity's walls stand 2 in, where the round meets the bottom, so the rim would have no thickness: refused, naming the rim",
|
||||
"source": "analytic",
|
||||
"method": "the open bottom's rim runs from the round's contact with the bottom (r = 2 in from the outside) to the cavity's wall (2 in): 0 wide, so there is no rim; refused",
|
||||
"outcome": "refused",
|
||||
"refusal": "not supported yet: the rim"
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 40,
|
||||
"width": 30,
|
||||
"height": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.fillet",
|
||||
"params": {
|
||||
"edges": [
|
||||
[
|
||||
20,
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
40,
|
||||
15,
|
||||
0
|
||||
],
|
||||
[
|
||||
20,
|
||||
30,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
15,
|
||||
0
|
||||
]
|
||||
],
|
||||
"radius": 2,
|
||||
"tangent_chain": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
20,
|
||||
15,
|
||||
0
|
||||
]
|
||||
],
|
||||
"thickness": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"sources": [
|
||||
"tangency-labs/solidcraft#316"
|
||||
],
|
||||
"what": "a 40 x 30 x 10 box, its bottom outline rounded R1.5, shelled 2 mm open at the bottom: the round is smaller than the wall, so a 0.5 mm rim is left",
|
||||
"source": "analytic",
|
||||
"method": "outside: the box less its mitred bottom round, (1-pi/4) 1.5^2 (140 - 8c), c = 1.5 (10-3pi)/(3(4-pi)). The round's inward offset by 2 vanishes (1.5 < 2), so the cavity is the sharp box x 2..38, y 2..28, z 0..8 open at the bottom, 7488: V = 4445.694671",
|
||||
"body_count": 1,
|
||||
"volume_mm3": 4445.694671058465
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 40,
|
||||
"width": 30,
|
||||
"height": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.fillet",
|
||||
"params": {
|
||||
"edges": [
|
||||
[
|
||||
20,
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
40,
|
||||
15,
|
||||
0
|
||||
],
|
||||
[
|
||||
20,
|
||||
30,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
15,
|
||||
0
|
||||
]
|
||||
],
|
||||
"radius": 1.5,
|
||||
"tangent_chain": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
20,
|
||||
15,
|
||||
0
|
||||
]
|
||||
],
|
||||
"thickness": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"sources": [
|
||||
"tangency-labs/solidcraft#545"
|
||||
],
|
||||
"what": "the frame of examples/regressions/ring_cut_below_recess_thin_floor (a recess from the top, a ring cut from the bottom, a 0.5 mm floor between) shelled 0.5 mm open at the ring cut's outer wall (action matrix (apps/solidcraft-cli/tests/action_matrix.rs): regressions/ring_cut_below_recess_thin_floor, Frame/F6:side:l2 face.shell)",
|
||||
"source": "invariants",
|
||||
"method": "every wall of the frame is at least 0.5 thick except the 0.5 mm floor, which a 0.5 shell hollows to nothing there: whether that floor's cavity closes is the offset's choice, so no closed form: one closed valid solid is the right answer",
|
||||
"body_count": 1
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XY",
|
||||
"offset": 0,
|
||||
"name": "Block"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"p1": [
|
||||
100.0,
|
||||
100.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "Block",
|
||||
"distance": 30,
|
||||
"body_name": "Frame"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XY",
|
||||
"offset": 30,
|
||||
"name": "Recess"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"p1": [
|
||||
94.0,
|
||||
94.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "Recess",
|
||||
"distance": -12,
|
||||
"operation": "cut",
|
||||
"targets": [
|
||||
"Frame"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XY",
|
||||
"offset": 0,
|
||||
"name": "Ring"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
2.5,
|
||||
2.5
|
||||
],
|
||||
"p1": [
|
||||
97.5,
|
||||
97.5
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
16.0,
|
||||
16.0
|
||||
],
|
||||
"p1": [
|
||||
84.0,
|
||||
84.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "Ring",
|
||||
"distance": 17.5,
|
||||
"operation": "cut",
|
||||
"targets": [
|
||||
"Frame"
|
||||
],
|
||||
"profiles": [
|
||||
{
|
||||
"point": [
|
||||
9.25,
|
||||
50.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
97.5,
|
||||
10.416666666666666,
|
||||
5.833333333333333
|
||||
]
|
||||
],
|
||||
"thickness": 0.5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"sources": [
|
||||
"tangency-labs/solidcraft#616"
|
||||
],
|
||||
"what": "#616's lid (a 2.4 mm plate with R3 corners, a 3 mm skirt, three openings and four 1.6 mm ribs, all boxes) shelled 0.5 mm with a rib's outer side face open (action matrix (apps/solidcraft-cli/tests/action_matrix.rs): corpus/issue-616-lid-ribs, Lid/F8:-x face.shell)",
|
||||
"source": "invariants",
|
||||
"method": "every wall is at least 1.4 thick, so a 0.5 shell fits everywhere; the cavity's corners at the openings and the R3 rounds' offsets make the volume long but not unknown, and the case guards the build: one closed valid solid is the right answer",
|
||||
"body_count": 1
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 76.8,
|
||||
"width": 89.3,
|
||||
"height": 2.4,
|
||||
"corner": [
|
||||
100,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"body_name": "Lid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.fillet",
|
||||
"params": {
|
||||
"edges": [
|
||||
[
|
||||
100,
|
||||
0,
|
||||
1.2
|
||||
],
|
||||
[
|
||||
176.8,
|
||||
0,
|
||||
1.2
|
||||
],
|
||||
[
|
||||
100,
|
||||
89.3,
|
||||
1.2
|
||||
],
|
||||
[
|
||||
176.8,
|
||||
89.3,
|
||||
1.2
|
||||
]
|
||||
],
|
||||
"radius": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 71.5,
|
||||
"width": 84,
|
||||
"height": 3,
|
||||
"corner": [
|
||||
102.65,
|
||||
2.65,
|
||||
2.4
|
||||
],
|
||||
"operation": "join",
|
||||
"targets": [
|
||||
"Lid"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 68,
|
||||
"width": 61,
|
||||
"height": 8,
|
||||
"corner": [
|
||||
104.4,
|
||||
5.4,
|
||||
-1
|
||||
],
|
||||
"operation": "cut"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 44,
|
||||
"width": 10,
|
||||
"height": 8,
|
||||
"corner": [
|
||||
116.4,
|
||||
72,
|
||||
-1
|
||||
],
|
||||
"operation": "cut"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 22,
|
||||
"width": 6,
|
||||
"height": 4,
|
||||
"corner": [
|
||||
127.4,
|
||||
84,
|
||||
2.4
|
||||
],
|
||||
"operation": "cut"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 1.6,
|
||||
"width": 6,
|
||||
"height": 11.7,
|
||||
"corner": [
|
||||
102.8,
|
||||
14,
|
||||
2.4
|
||||
],
|
||||
"operation": "join",
|
||||
"targets": [
|
||||
"Lid"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 1.6,
|
||||
"width": 6,
|
||||
"height": 11.7,
|
||||
"corner": [
|
||||
102.8,
|
||||
48,
|
||||
2.4
|
||||
],
|
||||
"operation": "join",
|
||||
"targets": [
|
||||
"Lid"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 1.6,
|
||||
"width": 6,
|
||||
"height": 11.7,
|
||||
"corner": [
|
||||
172.4,
|
||||
14,
|
||||
2.4
|
||||
],
|
||||
"operation": "join",
|
||||
"targets": [
|
||||
"Lid"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 1.6,
|
||||
"width": 6,
|
||||
"height": 11.7,
|
||||
"corner": [
|
||||
172.4,
|
||||
48,
|
||||
2.4
|
||||
],
|
||||
"operation": "join",
|
||||
"targets": [
|
||||
"Lid"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
102.8,
|
||||
17,
|
||||
6.85
|
||||
]
|
||||
],
|
||||
"thickness": 0.5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,3 +2,12 @@
|
||||
# rig gate (.github/workflows/kernel-rig.yml) fails on a case that fails and is not listed here,
|
||||
# and on a listed case that passes: a fix removes its line in the same pull request.
|
||||
# Baseline: 45f69c0e5 with SMLib 60b1c6a, aarch64 Linux.
|
||||
316-shell-open-beside-a-bottom-round-r2-4-as-large-as-the-wall-refused builds a shell where the rim has no thickness instead of refusing it
|
||||
316-shell-open-beside-a-bottom-round-r2-as-large-as-the-wall-refused builds a shell where the rim has no thickness instead of refusing it
|
||||
545-shell-ring-cut-frame-open-at-an-outer-wall SMLib status 1001
|
||||
616-shell-open-a-rib-side-face-of-a-lid SMLib status 1001
|
||||
cov-shell-again-open-at-an-inner-wall-of-a-shelled-box SMLib status 1001
|
||||
cov-shell-plate-with-a-hole-through-its-arc-side SMLib status 1001 where the hole's wall meets the arc side
|
||||
cov-shell-pocket-whose-floor-falls-to-a-drain SMLib status 1001 where four faces meet at the pocket floor's corners
|
||||
cov-shell-trough-whose-floor-falls-to-a-drain SMLib status 1001 where four faces meet at a corner
|
||||
cov-shell-up-down-joined-squares-open-at-a-side-wall SMLib status 1001
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"sources": [],
|
||||
"what": "a 70 x 50 x 30 box with R6 vertical rounds shelled 2 mm open on top, shelled again 0.5 mm open at an inner wall: its 2 mm walls hollowed (action matrix (apps/solidcraft-cli/tests/action_matrix.rs): typical/filleted-shelled-box, Body1/F4:inner:F2:side:l1 face.shell)",
|
||||
"source": "invariants",
|
||||
"method": "the 2 mm walls take a 0.5 shell (a 1 mm cavity inside them, open at the picked inner wall); the rounds' offsets are concentric, but the rim and the open faces' cavity ends are the offset's own: one closed valid solid is the right answer",
|
||||
"body_count": 1
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "parameters.change",
|
||||
"params": {
|
||||
"name": "height",
|
||||
"expression": "30 mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "parameters.change",
|
||||
"params": {
|
||||
"name": "wall",
|
||||
"expression": "2 mm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XY",
|
||||
"name": "Outline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.center",
|
||||
"params": {
|
||||
"center": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"corner": [
|
||||
35,
|
||||
25
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"distance": "height"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.fillet",
|
||||
"params": {
|
||||
"edges": [
|
||||
[
|
||||
35,
|
||||
25,
|
||||
15
|
||||
],
|
||||
[
|
||||
-35,
|
||||
25,
|
||||
15
|
||||
],
|
||||
[
|
||||
35,
|
||||
-25,
|
||||
15
|
||||
],
|
||||
[
|
||||
-35,
|
||||
-25,
|
||||
15
|
||||
]
|
||||
],
|
||||
"radius": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
30
|
||||
]
|
||||
],
|
||||
"thickness": "wall"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
-24.166666666667016,
|
||||
-22.999999915917346,
|
||||
4.666666666666665
|
||||
]
|
||||
],
|
||||
"thickness": 0.5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"sources": [],
|
||||
"what": "a 42.5 x 20 x 27.5 plate closed by a half-round side (r10), a blind hole r5 drilled in through that side, shelled 2 mm open at the far end: the edge where the hole's wall meets the arc side is neither a line nor an arc",
|
||||
"source": "invariants",
|
||||
"method": "the hole's wall moved 2 out meets the arc side moved 2 in along a curve of two cylinders; whether the cavity's corner at the hole's bottom is sharp or rounded is the offset's choice, so no closed form: one closed valid solid is the right answer",
|
||||
"body_count": 1
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.line",
|
||||
"params": {
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.5,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.5,
|
||||
20.0
|
||||
],
|
||||
[
|
||||
0,
|
||||
20.0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.arc.three_point",
|
||||
"params": {
|
||||
"end": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"start": [
|
||||
0,
|
||||
20.0
|
||||
],
|
||||
"through": [
|
||||
-10.0,
|
||||
10.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"distance": 27.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.cylinder",
|
||||
"params": {
|
||||
"radius": 5.0,
|
||||
"height": 17.5,
|
||||
"base": [
|
||||
-10.0,
|
||||
12.5,
|
||||
12.5
|
||||
],
|
||||
"axis": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"operation": "cut"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
42.5,
|
||||
10.0,
|
||||
13.75
|
||||
]
|
||||
],
|
||||
"thickness": 2.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"sources": [],
|
||||
"what": "a slab 140 x 90 x 50 with a 30 mm pocket whose floor falls 1 deg from its edges to a central drain (four faces meet at each of the pocket floor's concave corners), shelled 3 mm open at the top",
|
||||
"source": "analytic",
|
||||
"method": "The floor below z = 0 is a pyramid, apex at the centre h = 30 tan 1 deg = 0.523652 below: two triangular prisms (a triangle on XZ swept along y, one on YZ swept along x) intersected. Slab 140 x 90 x 50 less the pocket x 20..120, y 15..75 down to z = 20 and the pyramid below it: V0 = 630000 - (100 60 30 + 100 60 h/3). Shell 3 open at the top, offset faces extended to meet: the cavity is x 3..137, y 3..87 from z = 3 up to the top, except over the pocket's walls moved 3 out (x 17..123, y 12..78), where it rises only to the pocket's floor facets moved 3 down (their max, exactly over the cells where each is highest): cavity 297136.906075. V = 151815.790029",
|
||||
"body_count": 1,
|
||||
"volume_mm3": 151815.7900294403,
|
||||
"tolerance": {
|
||||
"rel": 1e-05
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 140.0,
|
||||
"width": 90.0,
|
||||
"height": 50.0,
|
||||
"body_name": "Slab"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 100.0,
|
||||
"width": 60.0,
|
||||
"height": 40,
|
||||
"corner": [
|
||||
20.0,
|
||||
15.0,
|
||||
20.0
|
||||
],
|
||||
"body_name": "Pocket"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XZ",
|
||||
"name": "FallX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.line",
|
||||
"params": {
|
||||
"points": [
|
||||
[
|
||||
20.0,
|
||||
-20.0
|
||||
],
|
||||
[
|
||||
120.0,
|
||||
-20.0
|
||||
],
|
||||
[
|
||||
70.0,
|
||||
-19.476348052153472
|
||||
]
|
||||
],
|
||||
"closed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "FallX",
|
||||
"distance": 75.0,
|
||||
"operation": "new",
|
||||
"body_name": "FallX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "YZ",
|
||||
"name": "FallY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.line",
|
||||
"params": {
|
||||
"points": [
|
||||
[
|
||||
15.0,
|
||||
20.0
|
||||
],
|
||||
[
|
||||
75.0,
|
||||
20.0
|
||||
],
|
||||
[
|
||||
45.0,
|
||||
19.476348052153472
|
||||
]
|
||||
],
|
||||
"closed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "FallY",
|
||||
"distance": 120.0,
|
||||
"operation": "new",
|
||||
"body_name": "FallY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.combine",
|
||||
"params": {
|
||||
"target": "FallX",
|
||||
"tools": [
|
||||
"FallY"
|
||||
],
|
||||
"operation": "intersect"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.combine",
|
||||
"params": {
|
||||
"target": "Pocket",
|
||||
"tools": [
|
||||
"FallX"
|
||||
],
|
||||
"operation": "join"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.combine",
|
||||
"params": {
|
||||
"target": "Slab",
|
||||
"tools": [
|
||||
"Pocket"
|
||||
],
|
||||
"operation": "cut"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"body": "Slab",
|
||||
"faces": [
|
||||
[
|
||||
5,
|
||||
5,
|
||||
50.0
|
||||
]
|
||||
],
|
||||
"thickness": 3.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"sources": [],
|
||||
"what": "a trough whose floor falls 1 deg from its edges to a central drain (four faces meet at each bottom corner and at the drain), a tab joined on one end, shelled 2 mm open at the top",
|
||||
"source": "analytic",
|
||||
"method": "The floor below z = 0 is a pyramid, apex at the centre h = 30 tan 1 deg = 0.523652 below: two triangular prisms (a triangle on XZ swept along y, one on YZ swept along x) intersected. Trough 100 x 60 x 40 plus the pyramid 100 60 h/3, plus the tab 20^3 at x 100..120, y 20..40, z 20..40. The shell moves every face 2 in, the offset faces extended to meet (sharp inner corners, as every shell in the ladder's tier 09): the cavity is x 2..98, y 2..58 from the four facets moved 2 up (z >= max of the moved planes, which no longer meet in one point) to the open top, Int (40 - max) dA exactly over the cells where each plane is highest = 205325.031680, and the tab's 20 x 16 x 18 = 5760. V = 37962.272215",
|
||||
"body_count": 1,
|
||||
"volume_mm3": 37962.27221527102,
|
||||
"tolerance": {
|
||||
"rel": 1e-05
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 100.0,
|
||||
"width": 60.0,
|
||||
"height": 40.0,
|
||||
"body_name": "Trough"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XZ",
|
||||
"name": "FallX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.line",
|
||||
"params": {
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
100.0,
|
||||
0
|
||||
],
|
||||
[
|
||||
50.0,
|
||||
0.5236519478465276
|
||||
]
|
||||
],
|
||||
"closed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "FallX",
|
||||
"distance": 60.0,
|
||||
"operation": "new",
|
||||
"body_name": "FallX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "YZ",
|
||||
"name": "FallY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.line",
|
||||
"params": {
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
60.0,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.0,
|
||||
-0.5236519478465276
|
||||
]
|
||||
],
|
||||
"closed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "FallY",
|
||||
"distance": 100.0,
|
||||
"operation": "new",
|
||||
"body_name": "FallY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.combine",
|
||||
"params": {
|
||||
"target": "FallX",
|
||||
"tools": [
|
||||
"FallY"
|
||||
],
|
||||
"operation": "intersect"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.combine",
|
||||
"params": {
|
||||
"target": "Trough",
|
||||
"tools": [
|
||||
"FallX"
|
||||
],
|
||||
"operation": "join"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.box",
|
||||
"params": {
|
||||
"length": 20,
|
||||
"width": 20,
|
||||
"height": 20,
|
||||
"corner": [
|
||||
100.0,
|
||||
20,
|
||||
20
|
||||
],
|
||||
"operation": "join",
|
||||
"targets": [
|
||||
"Trough"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
50,
|
||||
30,
|
||||
40.0
|
||||
]
|
||||
],
|
||||
"thickness": 2.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"sources": [],
|
||||
"what": "four squares drawn edge to edge, three extruded 10 up and three 10 down and joined, shelled 0.346 mm open at a side wall (action matrix (apps/solidcraft-cli/tests/action_matrix.rs): typical/up-down-join, Body1/F2:side:l1 face.shell)",
|
||||
"source": "invariants",
|
||||
"method": "every wall is 10 x 10 or more and the shell thin: the cavity's corners where the up and down parts overlap only along an edge are the offset's own choice, so no closed form: one closed valid solid is the right answer",
|
||||
"body_count": 1
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"command": "sketch.create",
|
||||
"params": {
|
||||
"plane": "XY",
|
||||
"name": "Squares"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"p1": [
|
||||
10,
|
||||
10
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
-10,
|
||||
0
|
||||
],
|
||||
"p1": [
|
||||
0,
|
||||
10
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
0,
|
||||
-10
|
||||
],
|
||||
"p1": [
|
||||
10,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.rectangle.two_point",
|
||||
"params": {
|
||||
"p0": [
|
||||
-10,
|
||||
-10
|
||||
],
|
||||
"p1": [
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "sketch.finish",
|
||||
"params": {}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "Squares",
|
||||
"profiles": [
|
||||
{
|
||||
"point": [
|
||||
-5,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"point": [
|
||||
-5,
|
||||
-5
|
||||
]
|
||||
},
|
||||
{
|
||||
"point": [
|
||||
5,
|
||||
-5
|
||||
]
|
||||
}
|
||||
],
|
||||
"distance": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.extrude",
|
||||
"params": {
|
||||
"sketch": "Squares",
|
||||
"profiles": [
|
||||
{
|
||||
"point": [
|
||||
5,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"point": [
|
||||
5,
|
||||
-5
|
||||
]
|
||||
},
|
||||
{
|
||||
"point": [
|
||||
-5,
|
||||
5
|
||||
]
|
||||
}
|
||||
],
|
||||
"distance": 10,
|
||||
"direction": "negative",
|
||||
"operation": "join"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "solid.shell",
|
||||
"params": {
|
||||
"faces": [
|
||||
[
|
||||
6.666666666666666,
|
||||
0.0,
|
||||
1.6666666666666665
|
||||
]
|
||||
],
|
||||
"thickness": 0.346
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user