HATCH treats rooms enclosed by multilines as islands (#1642)

A pick inside a multiline wall found the band between the wall's lines
as the outer boundary, but the rooms the inner lines enclose were
dropped as islands: island_curve accepted lines, arcs, polylines and
splines, not multilines. The rooms were filled along with the walls. A
multiline's lines can now make up an island like the other open curves.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
Vinicius Augusto
2026-10-24 01:53:00 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 Brandon Thomas
parent 88a73b7618
commit 532c4ccc1c
2 changed files with 13 additions and 1 deletions
+3 -1
View File
@@ -113,7 +113,8 @@ fn closed_loop(d: &Drawing, e: &Entity) -> Option<Vec<PolyVertex>> {
}
/// Open curves that can make up an island together (a square drawn as four LINEs, two ARCs
/// forming a circle). Closed objects are islands on their own (see `closed_loop`).
/// forming a circle, the inner lines of multiline walls around a room). Closed objects are
/// islands on their own (see `closed_loop`).
fn island_curve(d: &Drawing, e: &Entity) -> bool {
matches!(
e.kind,
@@ -123,6 +124,7 @@ fn island_curve(d: &Drawing, e: &Entity) -> bool {
| EntityKind::LwPolyline(_)
| EntityKind::Polyline3d(_)
| EntityKind::Spline(_)
| EntityKind::MLine(_)
) && closed_loop(d, e).is_none()
}
+10
View File
@@ -249,3 +249,13 @@ fn hatchedit_refuses_unknown_patterns_and_region_boundaries() {
// Region boundaries need REGION objects; the hatch is left as it was.
assert!(s.execute("hatchedit", &json!({ "handles": [h], "recreate": "region" })).is_err());
}
#[test]
fn multiline_wall_hatch_keeps_the_room_as_an_island() {
// A closed multiline wall: picking inside the wall hatches the band between its outer and
// inner lines; the room the inner lines enclose is an island, not filled.
let mut s = Session::new();
s.execute("mline", &json!({ "points": [[0, 0], [10, 0], [10, 10], [0, 10]], "closed": true, "scale": 1, "justification": "zero" })).unwrap();
let h = handle(&s.execute("hatch", &json!({ "points": [[0, 5]], "pattern": "SOLID" })).unwrap());
assert_eq!(hatch(&s, &h).loops.len(), 2, "outer face + the room as an island");
}