fix(sketch): merged adjacent profiles have whole edges where shared ones ended (#509)
When adjacent profiles are merged for one extrude, collinear lines on either side of where a shared boundary ended are joined back into one edge, so the body has no split faces or extra vertices for later booleans to trip on. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2f7046efac
commit
bb431f7ac2
3 files changed
+82
-1
No files matched your search
@@ -363,6 +363,51 @@ fn revolve_a_spherical_shell_off_the_origin() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extrude_of_adjacent_profiles_has_whole_edges() {
|
||||
// A holder from two regions of one sketch (a disc and the ring around it, both cut off by a
|
||||
// chord): the chord used to stay split where the inner circle met it, leaving vertices right
|
||||
// on the surface of a handle of that radius, and cutting the handle out of the holder failed.
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "sketch.create", json!({"plane": "XZ", "name": "Holder"}));
|
||||
run(&mut s, "sketch.circle.center", json!({"center": [0, 0], "radius": 40}));
|
||||
run(&mut s, "sketch.circle.center", json!({"center": [0, 0], "radius": 35}));
|
||||
let x = (40.0f64 * 40.0 - 33.0 * 33.0).sqrt();
|
||||
run(&mut s, "sketch.line", json!({"points": [[-x, -33], [x, -33]]}));
|
||||
run(&mut s, "sketch.finish", json!({}));
|
||||
let si = run(&mut s, "sketch.inspect", json!({"sketch": "Holder"}));
|
||||
let below: Vec<Value> = si["profiles"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|p| (500.0..4900.0).contains(&p["area_mm2"].as_f64().unwrap()))
|
||||
.map(|p| p["index"].clone())
|
||||
.collect();
|
||||
assert_eq!(below.len(), 2, "{si}");
|
||||
run(&mut s, "solid.extrude", json!({"sketch": "Holder", "profiles": below, "distance": 23, "body_name": "Holder"}));
|
||||
let topo = run(&mut s, "model.faces", json!({"body": "Holder"}));
|
||||
assert_eq!(topo["faces"].as_array().unwrap().len(), 5, "a cut-off cylinder: {topo}");
|
||||
let lo = run(&mut s, "inspect.measure", json!({"bodies": ["Holder"]}))["bodies"][0]["bbox"]["min"][1].as_f64().unwrap();
|
||||
run(&mut s, "solid.move", json!({"bodies": ["Holder"], "translate": [0, -5.0 - lo, 0]}));
|
||||
// The handle: r35 on the Y axis with a bevelled end.
|
||||
run(&mut s, "sketch.create", json!({"plane": "XY", "name": "Handle"}));
|
||||
for pts in [
|
||||
[[0.0, 0.0], [0.0, 230.0]],
|
||||
[[0.0, 0.0], [25.0, 0.0]],
|
||||
[[25.0, 0.0], [35.0, 11.5]],
|
||||
[[35.0, 11.5], [35.0, 230.0]],
|
||||
[[35.0, 230.0], [0.0, 230.0]],
|
||||
] {
|
||||
run(&mut s, "sketch.line", json!({ "points": pts }));
|
||||
}
|
||||
run(&mut s, "sketch.finish", json!({}));
|
||||
run(&mut s, "solid.revolve", json!({"sketch": "Handle", "profiles": [0], "axis": "Y", "body_name": "Handle"}));
|
||||
let before = run(&mut s, "inspect.measure", json!({"bodies": ["Holder"]}))["total"]["volume_mm3"].as_f64().unwrap();
|
||||
run(&mut s, "solid.combine", json!({"target": "Holder", "tools": ["Handle"], "operation": "cut", "keep_tools": true}));
|
||||
let after = run(&mut s, "inspect.measure", json!({"bodies": ["Holder"]}))["total"]["volume_mm3"].as_f64().unwrap();
|
||||
assert!(after > 1000.0 && after < before * 0.5, "{before} -> {after}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sketch_tools_and_constraints() {
|
||||
let mut s = Session::default();
|
||||
|
||||
Reference in new issue
Block a user