face.delete heal: false leaves an open surface body (#861)
Delete Face takes heal (default true, as before). With heal: false the picked faces are removed and the gap stays open, leaving the remaining faces as a surface body (kernel remove_faces); deleting every face is refused. Saved only when false, noted under format 18.
This commit is contained in:
1 parent
c616f50bd0
commit
b52d4390a0
7 files changed
+80
-5
No files matched your search
@@ -67,7 +67,7 @@ pub static COMMANDS: &[CommandSpec] = &[
|
||||
CommandSpec::new("face.delete", "Delete Face", delete_face)
|
||||
.at("SOLID", "MODIFY")
|
||||
.icon("delete")
|
||||
.params("faces: [[x,y,z] points on the faces]; body?. The neighbouring planes close the gap, as when a rounded edge, hole or boss is taken off"),
|
||||
.params("faces: [[x,y,z] points on the faces]; body?; heal?: bool (default true: the neighbouring planes close the gap, as when a rounded edge, hole or boss is taken off; false: the gap stays open and the faces left are a surface body)"),
|
||||
CommandSpec::new("solid.offset_face", "Offset Face", offset_face)
|
||||
.at("SOLID", "MODIFY")
|
||||
.icon("offset_face")
|
||||
@@ -1649,7 +1649,8 @@ fn scale(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
fn delete_face(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let faces = face_points(p, "face.delete")?;
|
||||
add_feature(s, p, FeatureKind::DeleteFace { faces, body: str_(p, "body").map(str::to_string) })
|
||||
let heal = bool_(p, "heal").unwrap_or(true);
|
||||
add_feature(s, p, FeatureKind::DeleteFace { faces, body: str_(p, "body").map(str::to_string), heal })
|
||||
}
|
||||
|
||||
fn offset_face(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
@@ -338,6 +338,32 @@ mod tests {
|
||||
assert!(s.execute("surface.reverse_normal", &json!({"body": "Cube"})).is_err());
|
||||
}
|
||||
|
||||
/// Delete Face without healing: a box's top taken off leaves a five-face surface; patching
|
||||
/// the opening and stitching gives back a box of the same volume. By default the gap still
|
||||
/// heals (here it can't: refused); deleting every face is refused.
|
||||
#[test]
|
||||
fn delete_face_without_healing_leaves_an_open_surface() {
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "solid.box", json!({"length": 10, "width": 10, "height": 10, "body_name": "Box"}));
|
||||
run(&mut s, "face.delete", json!({"faces": [[5, 5, 10]], "heal": false}));
|
||||
let st = s.world_state();
|
||||
let open = &st.body("Box").unwrap().body;
|
||||
assert!(open.is_surface() && open.face_count() == 5);
|
||||
let rim = json!([[5, 0, 10], [10, 5, 10], [5, 10, 10], [0, 5, 10]]);
|
||||
run(&mut s, "surface.patch", json!({"edges": rim, "body": "Box", "body_name": "Lid"}));
|
||||
run(&mut s, "surface.stitch", json!({"bodies": ["Box", "Lid"]}));
|
||||
assert!(!s.world_state().body("Box").unwrap().body.is_surface());
|
||||
assert!((volume(&s, "Box") - 1000.0).abs() < 1e-9);
|
||||
let cold = Session::new(solidcraft_doc::Document::from_json(&s.doc.to_json()).unwrap());
|
||||
assert!((volume(&cold, "Box") - 1000.0).abs() < 1e-9);
|
||||
// By default the gap heals, and a box's sides can't close its top: refused, the box kept.
|
||||
run(&mut s, "solid.box", json!({"length": 10, "width": 10, "height": 10, "corner": [20, 0, 0], "body_name": "Healed"}));
|
||||
assert!(s.execute("face.delete", &json!({"faces": [[25, 5, 10]], "body": "Healed"})).is_err());
|
||||
assert!(!s.world_state().body("Healed").unwrap().body.is_surface());
|
||||
let all = json!([[25, 5, 10], [25, 5, 0], [25, 0, 5], [25, 10, 5], [20, 5, 5], [30, 5, 5]]);
|
||||
assert!(s.execute("face.delete", &json!({"faces": all, "body": "Healed", "heal": false})).is_err());
|
||||
}
|
||||
|
||||
/// The planned surface commands are registered but refuse to run: disabled with the
|
||||
/// issue that tracks them, an error (never a panic) from every caller, and the design left
|
||||
/// as it was.
|
||||
|
||||
Reference in new issue
Block a user