feat(kernel): an edge's meeting sides are sets of origins (merged faces)
EdgeOrigin::Meet now names each side as a Side: the sorted, de-duplicated origins of the face there. substitute maps a side to the union of the inner faces' origins, so a meeting with a face an inner operation merged keeps its lineage; meeting() derives sides from whole faces. Fillets after box cuts that leave coplanar pieces now report exact history. Prism lineage meets a cap of several origins and resolves wall junctions away from shared vertices by the operand's one edge between the walls. bore_union's recut reports history only for a one-face bore (pieces of a two-arc bore's recut wall were given both arcs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J53sR6gEaVt56soFDpTck8
This commit is contained in:
1 parent
08d7037176
commit
43ddde4a5d
11 files changed
+347
-76
No files matched your search
@@ -7,7 +7,7 @@ use solvecraft_geom::{Loop2, Plane, Region2, Seg2, Vec2, Vec3};
|
||||
|
||||
use crate::body::Body;
|
||||
use crate::build::PathSeg;
|
||||
use crate::history::{Change, FaceOrigin, History};
|
||||
use crate::history::{Change, EdgeOrigin, FaceOrigin, FaceProv, History, Side};
|
||||
|
||||
const P: fn(usize) -> FaceOrigin = |segment| FaceOrigin::Profile { segment };
|
||||
const START: FaceOrigin = FaceOrigin::Cap { end: false };
|
||||
@@ -550,3 +550,23 @@ fn emboss_reports_kept_trimmed_and_profile_faces() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A new edge's meeting: each side all of its face's origins (a merged face's several); none
|
||||
/// where an origin lies on both sides (pieces of one face) or a face comes from nothing.
|
||||
#[test]
|
||||
fn a_new_edge_meets_whole_faces() {
|
||||
let f = |face: usize| FaceOrigin::Face { operand: 0, face };
|
||||
let blend = FaceOrigin::Edge { operand: 0, edge: 3 };
|
||||
let faces = vec![
|
||||
FaceProv { origins: vec![f(0), f(1)], change: Change::Merged },
|
||||
FaceProv { origins: vec![blend], change: Change::Generated },
|
||||
FaceProv { origins: vec![f(1)], change: Change::Split },
|
||||
FaceProv { origins: vec![], change: Change::Generated },
|
||||
];
|
||||
let merged = Side::new([f(0), f(1)]).unwrap();
|
||||
assert_eq!(super::meeting(&[1, 0], &faces), [EdgeOrigin::meet(merged, blend)]);
|
||||
assert_eq!(super::meeting(&[2, 1], &faces), [EdgeOrigin::meet(f(1), blend)]);
|
||||
assert!(super::meeting(&[0, 2], &faces).is_empty());
|
||||
assert!(super::meeting(&[1, 3], &faces).is_empty());
|
||||
assert!(super::meeting(&[1], &faces).is_empty());
|
||||
}
|
||||
Reference in new issue
Block a user