Files
cadcraft/crates/engine/tests/snaps_more.rs

68 lines
2.7 KiB
Rust

//! The remaining object snaps (#519, gaps.md U8): Insertion on attribute definitions and
//! multileaders, Geometric Center on closed splines, and no Midpoint on closed curves.
use cadcraft_doc::{EntityKind, Space};
use cadcraft_engine::Session;
use cadcraft_engine::snap::{self, mode};
use cadcraft_geom::Vec2;
use serde_json::json;
/// The snap of `modes` near `p` (a hair off it, inside a 0.1 aperture).
fn snap_at(s: &Session, p: Vec2, modes: u32) -> Option<(Vec2, u32)> {
snap::osnap(s.doc().unwrap(), &Space::Model, p + Vec2::new(0.02, -0.01), 0.1, modes, None, false).map(|h| (h.point, h.mode))
}
fn near(a: Option<(Vec2, u32)>, p: Vec2, m: u32) -> bool {
a.is_some_and(|(q, k)| k == m && q.dist(p) < 1e-6)
}
#[test]
fn insertion_snaps_to_attribute_definitions() {
let mut s = Session::new();
s.execute("attdef", &json!({"tag": "PART", "default": "A-1", "at": [3, 4]})).unwrap();
assert!(near(snap_at(&s, Vec2::new(3.0, 4.0), mode::INS), Vec2::new(3.0, 4.0), mode::INS));
}
#[test]
fn insertion_snaps_to_a_multileader_text() {
let mut s = Session::new();
s.execute("mleader", &json!({"points": [[0, 0], [10, 5]], "text": "NOTE"})).unwrap();
let at = s
.doc()
.unwrap()
.model
.iter()
.find_map(|e| match &e.kind {
EntityKind::MLeader(m) => m.text.as_ref().map(|t| t.insert.xy()),
_ => None,
})
.expect("a multileader with text");
assert!(near(snap_at(&s, at, mode::INS), at, mode::INS));
}
#[test]
fn geometric_center_of_a_closed_spline() {
let mut s = Session::new();
// A closed fit spline symmetric about (5,5): its centroid is the centre.
s.execute("spline", &json!({"fit": [[0, 5], [5, 0], [10, 5], [5, 10]], "closed": true})).unwrap();
let c = Vec2::new(5.0, 5.0);
let hit = snap::osnap(s.doc().unwrap(), &Space::Model, c + Vec2::new(0.05, 0.0), 0.5, mode::GCEN, None, false).expect("a geometric center");
assert_eq!(hit.mode, mode::GCEN);
assert!(hit.point.dist(c) < 1e-3, "{:?}", hit.point);
// An open spline has none.
let mut s = Session::new();
s.execute("spline", &json!({"fit": [[0, 5], [5, 0], [10, 5], [5, 10]]})).unwrap();
assert!(snap::osnap(s.doc().unwrap(), &Space::Model, c, 0.5, mode::GCEN, None, false).is_none());
}
#[test]
fn closed_curves_have_no_midpoint() {
// As in AutoCAD: Midpoint works on arcs and elliptical arcs, not on a full circle or ellipse.
let mut s = Session::new();
s.cmdline("circle 0,0 5").unwrap();
s.cmdline("ellipse 20,0 30,0 3").unwrap();
for p in [Vec2::new(-5.0, 0.0), Vec2::new(5.0, 0.0), Vec2::new(10.0, 0.0), Vec2::new(30.0, 0.0), Vec2::new(20.0, 3.0)] {
assert_eq!(snap_at(&s, p, mode::MID), None, "{p:?}");
}
}