Edit Sketch no longer shows bodies a later feature deletes (#1329)

Fixes #1167. While a sketch is edited, a body that a rolled-off, unsuppressed Remove deletes is not shown (unless the sketch is built on it); the history stays rolled back, only the view changes. Drawing, picking, screenshots, thumbnails and the browser's Bodies folder agree; document.inspect reports removed_later. Checked on main + this branch: cargo check --workspace, the engine sketch_edit_removed/occurrences tests and the UI viewport/browser tests.
This commit is contained in:
Lasse Lian authored and GitHub committed 2026-10-15 06:34:01 -04:00
1 parent 5fa8e7d60a
commit 9fbbf8dc3a
9 files changed
+332 -4

No files matched your search

+7 -1
View File
@@ -1248,7 +1248,7 @@ fn entries(app: &SolveApp, comp: u64, folder: &str) -> Vec<Entry> {
.state()
.bodies
.iter()
.filter(|b| doc.model_body_component(b) == comp)
.filter(|b| doc.model_body_component(b) == comp && !app.session.body_removed_later(&b.name))
.map(|b| Entry {
key: b.name.clone(),
row_key: format!("b:{}", b.name),
@@ -1960,6 +1960,12 @@ fn occurrence_origin(app: &SolveApp, occurrence: u64) -> Option<solidcraft_engin
Some(solidcraft_engine::doc::apply_point(&solidcraft_engine::doc::mat_mul(&parent, &own), solidcraft_engine::geom::Vec3::ZERO))
}
/// The names the Bodies folder lists at the top level, for tests.
#[cfg(test)]
pub(crate) fn body_rows(app: &SolveApp) -> Vec<String> {
entries(app, 0, "bodies").into_iter().map(|e| e.key).collect()
}
#[cfg(test)]
#[path = "section_browser_tests.rs"]
mod section_browser_tests;
+4
View File
@@ -19,6 +19,10 @@ use crate::{SolveApp, icons};
#[path = "viewport_appearance_tests.rs"]
mod appearance_tests;
#[cfg(test)]
#[path = "viewport_removed_later_tests.rs"]
mod removed_later_tests;
#[cfg(test)]
#[path = "viewport_plane_target_tests.rs"]
mod plane_target_tests;
@@ -0,0 +1,55 @@
//! Editing a sketch rolls the timeline back to it; a body deleted after the sketch is not drawn
//! then (#1167), and is back in neither the viewport nor the browser's Bodies folder.
use super::build_scene;
use crate::{Services, SolveApp};
use serde_json::json;
use solidcraft_engine::Session;
/// `Kept` and `Gone` blocks, a sketch `Edited` made after both, and `Gone` deleted after it.
fn app() -> SolveApp {
let mut s = Session::default();
for (name, x) in [("Kept", 0.0), ("Gone", 20.0)] {
s.execute("sketch.create", &json!({"plane": "XY", "name": format!("{name}Sketch")})).unwrap();
s.execute("sketch.rectangle.two_point", &json!({"p0": [x, 0], "p1": [x + 10.0, 10]})).unwrap();
s.execute("sketch.finish", &json!({})).unwrap();
s.execute("solid.extrude", &json!({"sketch": format!("{name}Sketch"), "distance": 5, "body_name": name})).unwrap();
}
s.execute("sketch.create", &json!({"plane": "XY", "offset": "30 mm", "name": "Edited"})).unwrap();
s.execute("sketch.rectangle.two_point", &json!({"p0": [0, 0], "p1": [5, 5]})).unwrap();
s.execute("sketch.finish", &json!({})).unwrap();
s.execute("solid.remove", &json!({"bodies": ["Gone"]})).unwrap();
let mut app = SolveApp::new(s, Services::default());
app.ui.ground_shadow = false;
app.ui.show_origin = false;
app
}
fn triangles(app: &SolveApp) -> usize {
let scene = build_scene(app).merged();
scene.tris.len() + scene.pbr.len() + scene.trans.len() + scene.glass.len()
}
#[test]
fn a_body_deleted_later_is_not_drawn_while_a_sketch_is_edited() {
let mut app = app();
let drawn = triangles(&app);
assert!(drawn > 0, "the kept block is drawn");
let sketch = app.session.doc.find_feature("Edited").map(|f| f.id).unwrap();
app.edit_sketch(sketch);
assert_eq!(app.session.active_sketch, Some(sketch));
assert!(app.session.model.state().body("Gone").is_some(), "the rolled-back history has it");
assert_eq!(triangles(&app), drawn, "only the kept block is drawn");
app.finish_sketch();
assert_eq!(triangles(&app), drawn);
}
#[test]
fn the_bodies_folder_leaves_out_a_body_deleted_later() {
let mut app = app();
let sketch = app.session.doc.find_feature("Edited").map(|f| f.id).unwrap();
let names = |app: &SolveApp| crate::browser::body_rows(app).into_iter().collect::<Vec<_>>();
assert_eq!(names(&app), ["Kept"]);
app.edit_sketch(sketch);
assert_eq!(names(&app), ["Kept"], "the body is not listed with an eye that cannot show it");
}