diff --git a/crates/ui-egui/src/agent_chat/tests.rs b/crates/ui-egui/src/agent_chat/tests.rs index 05564e2d6a..958d890b05 100644 --- a/crates/ui-egui/src/agent_chat/tests.rs +++ b/crates/ui-egui/src/agent_chat/tests.rs @@ -2293,12 +2293,17 @@ fn the_picks_go_with_the_next_message_once() { } /// Two clicks on two rims are two things, not four edges (a click on a rim selects both halves for -/// the commands; the chat counts and describes what was clicked). +/// the commands; the chat counts and describes what was clicked). The cylinder is a circle drawn +/// as two half arcs, extruded, so each rim is in two halves. #[test] fn a_rim_clicked_once_is_one_item_not_its_pieces() { use solidcraft_engine::Sel; let (mut app, script, ctx) = app_with_script(); - app.run("solid.cylinder", json!({"radius": 10, "height": 20})).expect("a cylinder"); + app.run("sketch.create", json!({"plane": "XY"})).expect("a sketch"); + app.run("sketch.arc.three_point", json!({"start": [10, 0], "end": [-10, 0], "through": [0, 10]})).expect("an arc"); + app.run("sketch.arc.three_point", json!({"start": [-10, 0], "end": [10, 0], "through": [0, -10]})).expect("an arc"); + app.run("sketch.finish", json!({})).expect("the sketch"); + app.run("solid.extrude", json!({"distance": 20})).expect("a cylinder"); let (name, top, bottom, mid_top, mid_bottom) = { let st = crate::open_meshing::session_world(&app.session); let body = &st.bodies[0]; diff --git a/crates/ui-egui/src/dialogs_motion.rs b/crates/ui-egui/src/dialogs_motion.rs index 47f697b426..10b7d15682 100644 --- a/crates/ui-egui/src/dialogs_motion.rs +++ b/crates/ui-egui/src/dialogs_motion.rs @@ -1103,10 +1103,11 @@ mod tests { assert!(matches!(&target.certificate, Some(solidcraft_engine::doc::config::FaceCertificate::ExtrudeSide { curve, .. }) if curve == "outer")); let state = h.app.session.model.state(); let body = state.body("Ring").unwrap(); + // The outer circle, one closed curve, is one wall face. let indices = h.app.session.doc.configuration_face_indices(body, target).unwrap(); - assert_eq!(indices.len(), 2); + assert_eq!(indices.len(), 1); let painted = h.app.session.doc.face_colors(body); - assert_eq!(painted.len(), 2); + assert_eq!(painted.len(), 1); assert!(painted.iter().all(|(index, _)| indices.contains(index))); } diff --git a/crates/ui-egui/src/viewport.rs b/crates/ui-egui/src/viewport.rs index 04acbc8674..4a59d6adf8 100644 --- a/crates/ui-egui/src/viewport.rs +++ b/crates/ui-egui/src/viewport.rs @@ -8304,6 +8304,21 @@ mod tests { app } + /// A Ø20 × 20 cylinder whose wall and rims are each in two halves: a circle drawn as two + /// half arcs, extruded (one wall face per arc). SMLib's own cylinder has one wall and one + /// edge per rim; a rim or wall in pieces comes from a profile like this one or an import. + fn split_cylinder_app() -> SolveApp { + let mut s = solidcraft_engine::Session::default(); + s.execute("sketch.create", &json!({"plane": "XY"})).unwrap(); + s.execute("sketch.arc.three_point", &json!({"start": [10, 0], "end": [-10, 0], "through": [0, 10]})).unwrap(); + s.execute("sketch.arc.three_point", &json!({"start": [-10, 0], "end": [10, 0], "through": [0, -10]})).unwrap(); + s.execute("sketch.finish", &json!({})).unwrap(); + s.execute("solid.extrude", &json!({"distance": 20})).unwrap(); + let mut app = SolveApp::new(s, crate::Services::default()); + app.set_origin_shown(false); + app + } + /// Moving the pointer across a face keeps its highlight (a scanned mesh is one face of /// millions of triangles): only another face, edge or plane builds it again. #[test] @@ -8642,9 +8657,13 @@ mod tests { }) }) .unwrap(); - assert!(mesh.seams[crease], "the fixture must exercise the coarse seam false positive"); + // Truck's coarse seam fit took this crease for a seam between pieces of one surface; + // the seam flags now compare the exact surfaces (`topo::seam_flags`). Either way the + // certified crease is sharp, drawn in wireframe and picked. Its kink of a millionth is + // too close to tangent to show in the shading (`smooth_edges::Join`: smooth and a + // measured crease at once), so the shaded view leaves it out. assert!(mesh.sharp_edges[crease]); - assert!(mesh.shaded_edge_visible(crease)); + assert!(mesh.edge_visible(crease) && !mesh.shaded_edge_visible(crease)); assert!(mesh.edge_pickable(crease)); assert!(mesh.edge_faces[crease].iter().any(|f| mesh.surface_patch(*f as usize).len() == 1)); let mid = polyline_mid(&mesh.edges[crease]); @@ -8660,7 +8679,7 @@ mod tests { #[test] fn circular_items_measure_as_whole_rims_and_surfaces() { - let mut app = cylinder_app(); + let mut app = split_cylinder_app(); let st = app.session.world_state().unwrap(); let b = &st.bodies[0]; let m = b.mesh(); @@ -8741,7 +8760,7 @@ mod tests { #[test] fn circular_rim_hover_click_and_dialog_pick_include_both_halves() { - let mut app = cylinder_app(); + let mut app = split_cylinder_app(); let st = app.session.world_state().unwrap(); let b = &st.bodies[0]; let m = b.mesh(); @@ -8788,7 +8807,7 @@ mod tests { #[test] fn curved_face_hover_selection_and_dialogs_cross_the_seam() { - let mut app = cylinder_app(); + let mut app = split_cylinder_app(); let st = app.session.world_state().unwrap(); let b = &st.bodies[0]; let m = b.mesh();