Files
solidcraft-upstream/crates/ui-egui/src/thin_extrude_tests.rs
T
Lasse Lian 6df69e9def Thin Extrude: walls of a set thickness along sketch curves (#721) (#991)
Thin Extrude builds walls of a set thickness along sketch curves, open chains and closed loops, with the wall centred, inside, outside or on both sides at two thicknesses. Saved under format 20 (thin on an Extrude); an extrude without thin saves as before. Closes #721.
2026-10-14 11:46:16 -04:00

85 lines
3.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! The Extrude dialog's Thin Extrude (#721): a picked profile's outline becomes the wall's
//! curves, and editing a thin extrude keeps it thin.
use crate::scenario::Harness;
use serde_json::json;
use solidcraft_engine::Sel;
use solidcraft_engine::doc::{FeatureKind, ThinSide};
fn rectangle(h: &mut Harness) -> u64 {
h.app.run("sketch.create", json!({"plane":"XY","name":"Base"})).unwrap();
h.app.run("sketch.rectangle.two_point", json!({"p0":[0,0],"p1":[40,20]})).unwrap();
h.app.run("sketch.finish", json!({})).unwrap();
h.app.session.doc.find_feature("Base").unwrap().id
}
fn volume(h: &Harness) -> f64 {
h.app.session.world_state().bodies.iter().map(|b| solidcraft_engine::doc::kernel::measure(&b.body).unwrap().volume).sum()
}
#[test]
fn a_thin_extrude_of_a_picked_profile_follows_its_outline() {
let mut h = Harness::new();
let sketch = rectangle(&mut h);
h.step(&json!({"call":"ui.start","params":{"command":"solid.extrude"}})).unwrap();
h.frames(3);
h.app.dialog.as_mut().unwrap().inputs[0].items = vec![Sel::Profile { sketch, index: 0 }];
h.step(&json!({"widget":"Thin Extrude"})).unwrap();
h.frames(3);
assert!(h.widget("Wall Thickness").is_some(), "the wall rows show once Thin is on");
h.step(&json!({"widget":"OK"})).unwrap();
assert!(h.app.dialog.is_none(), "{:?}", h.app.session.log);
let f = h.app.session.doc.features.last().unwrap();
let FeatureKind::Extrude { thin: Some(thin), .. } = &f.kind else { panic!("a thin extrude: {:?}", f.kind) };
assert_eq!(thin.curves.len(), 4);
assert_eq!(thin.side, ThinSide::Center);
// A 2 mm wall centred on the 40 × 20 outline, 10 mm high.
assert!((volume(&h) - (42.0 * 22.0 - 38.0 * 18.0) * 10.0).abs() < 1e-6, "{}", volume(&h));
}
#[test]
fn editing_a_thin_extrude_keeps_its_wall() {
let mut h = Harness::new();
rectangle(&mut h);
h.app
.run(
"solid.extrude",
json!({"sketch":"Base","thin":true,"thickness":"3 mm","side":"two_sides","thickness2":"1 mm","distance":"5 mm","name":"Wall"}),
)
.unwrap();
h.frames(4);
let before = h.app.session.doc.find_feature("Wall").unwrap().clone();
let v = volume(&h);
h.step(&json!({"call":"ui.editFeature","params":{"feature":"Wall"}})).unwrap();
h.frames(8);
assert!(h.widget("Thickness Outside").is_some());
h.step(&json!({"widget":"OK"})).unwrap();
assert!(h.app.dialog.is_none(), "{:?}", h.app.session.log);
let after = h.app.session.doc.find_feature("Wall").unwrap();
assert_eq!(after.kind, before.kind);
assert_eq!(after.param_names, before.param_names);
assert!((volume(&h) - v).abs() < 1e-9);
}
#[test]
fn the_thin_rows_are_translated() {
for (lang, thin, location, outside) in
[("ja", "薄肉押し出し", "壁の位置", "外側の厚さ"), ("de", "Dünnwandig extrudieren", "Wandlage", "Dicke außen")]
{
let mut h = Harness::new();
h.app.preferences.language = lang.into();
rectangle(&mut h);
h.app
.run(
"solid.extrude",
json!({"sketch":"Base","thin":true,"thickness":"3 mm","side":"two_sides","thickness2":"1 mm","distance":"5 mm","name":"Wall"}),
)
.unwrap();
h.step(&json!({"call":"ui.editFeature","params":{"feature":"Wall"}})).unwrap();
h.frames(8);
for word in [thin, location, outside] {
assert!(h.widget(word).is_some(), "{lang}: {word:?} must be on screen");
}
assert!(h.widget("Wall Location").is_none(), "{lang}: must not fall back to English");
}
}