mesh: a closed edge's start is no curve end of the swept cross-section (#512)

The extrude/revolve cross-section took both ends of every B-rep edge as curve ends. A closed
edge without a vertex on it (a hole's rim after geometry.faces.merge of its halves) starts
wherever its chain was picked up, the old seam vertex, so that point stayed a curve end and a
node column stayed on the merged boundary. Only open edges' ends (and the B-rep vertices) are
curve ends now; the layout and interval assignment place the rim's nodes.

The hex test runs on a square plate and asserts the seams carry exactly as many nodes as the
same lines turned a quarter round the hole (10 and 10; before 5 and 10): the corner layout
puts arc-midpoint nodes there by symmetry, so 0 is not the right target.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-16 13:39:24 -04:00
1 parent 3a5a8213a1
commit b3a7f12472
2 files changed
+36 -10

No files matched your search

+4
View File
@@ -431,9 +431,13 @@ pub(crate) fn prepare(ctxs: &[Ctx], setup: Setup) -> Result<Prepared> {
}
}
}
// Curve ends: the B-rep vertices and the ends of open edges. A closed edge without a
// vertex on it (a hole's rim after its halves are merged, #512) starts wherever its chain
// was picked up: that point is no end, and the cross-section's mesher places its nodes.
vertices.extend(
brep.edges
.iter()
.filter(|e| !e.closed())
.flat_map(|e| [e.first(), e.last()])
.chain(brep.is_vertex.iter().enumerate().filter(|(_, v)| **v).map(|(i, _)| i as u32))
.map(|v| frame.coords(brep.point(v)).0),