mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-04 02:55:54 +00:00
Planar regions: a hole goes to the material that holds it, read closer than the hole lies
Reading a planar sheet's faces back as regions, each hole went to the smallest outline whose
Loop2::contains held its middle: even-odd against the outline's polyline within 1e-3 mm. A
5e-5 mm square cut 1.7e-4 mm inside a radius-10 circle lies outside the polyline's chords there,
so no outline held it and the cut failed ("face 0 has a hole outside its material"). An
outline now holds a point by its polyline within a quarter of the point's distance from it (its
nearest point on the exact segments), which no chord can pass the point by.
Fixes kernel prism::planar_tests::tiny_tool_between_circle_and_display_chord_is_not_lost.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -260,7 +260,7 @@ mod sheets {
|
||||
let mid = hole.segs.first().map(|s| s.point_at(0.5)).ok_or_else(|| failed("face", format!("face {f} has an empty loop")))?;
|
||||
let owner = out[first..]
|
||||
.iter_mut()
|
||||
.filter(|r| r.outer.contains(mid))
|
||||
.filter(|r| holds(&r.outer, mid))
|
||||
.min_by(|a, b| a.outer.signed_area().total_cmp(&b.outer.signed_area()))
|
||||
.ok_or_else(|| failed("face", format!("face {f} has a hole outside its material")))?;
|
||||
owner.holes.push(hole);
|
||||
@@ -269,6 +269,15 @@ mod sheets {
|
||||
Ok(Regions { regions: out, touching })
|
||||
}
|
||||
|
||||
/// Whether the loop `outer` holds `p`: even-odd against its polyline within a quarter of
|
||||
/// `p`'s distance from it, so the polyline's chords cannot pass `p` by (a loop's own
|
||||
/// [`Loop2::contains`] reads it within 1e-3 mm, and a hole closer than that to an arc of the
|
||||
/// outline was taken for one outside it, a chord cutting it off).
|
||||
fn holds(outer: &Loop2, p: Vec2) -> bool {
|
||||
let d = outer.segs.iter().map(|s| s.point_at(s.closest_param(p)).dist(p)).fold(f64::INFINITY, f64::min);
|
||||
outer.polyline((d * 0.25).clamp(1e-9, 1e-3)).contains(p)
|
||||
}
|
||||
|
||||
/// The natural normal of a planar surface record.
|
||||
fn natural_normal(s: &Surface) -> Option<Vec3> {
|
||||
let v = |p: [f64; 3]| Vec3::new(p[0], p[1], p[2]);
|
||||
|
||||
Reference in New Issue
Block a user