mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-04 02:55:54 +00:00
UI tests: SMLib's cylinder has one wall and one edge per rim; split rims come from two arcs
truck made a cylinder's wall and rims in halves; SMLib makes one wall face and one closed edge
per rim (one face per profile segment, a circle being one closed curve since 09c979a4b). The
tests of what joins a rim's or a wall's pieces for picking, measuring and the agent chat
(circular_rim_hover_click..., circular_items_measure..., curved_face_hover..._cross_the_seam,
a_rim_clicked_once_is_one_item_not_its_pieces) now build their cylinder from a circle drawn as
two half arcs, extruded, so the pieces they test exist. A ring's outer circle is one wall face
(configuration_annulus_picker...: 1, was 2). The certified small crease is no longer taken for
a seam (truck's coarse fit did; the seam flags compare exact surfaces now) and, a kink of a
millionth, is smooth for the shading while still a measured crease: sharp, drawn in wireframe,
picked (smooth_edges::Join).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user