88 lines
3.7 KiB
Rust
88 lines
3.7 KiB
Rust
//! 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() {
|
||
let cases = [
|
||
("ja", "薄肉押し出し", "壁の位置", "外側の厚さ"),
|
||
("de", "Dünnwandig extrudieren", "Wandlage", "Dicke außen"),
|
||
("uk", "Тонке видавлювання", "Розташування стінки", "Товщина назовні"),
|
||
];
|
||
for (lang, thin, location, outside) in cases {
|
||
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");
|
||
}
|
||
}
|