render: quadratic elements draw through their mid-side nodes; geometry edges over the mesh follow it

Zoomed in on the hex20 crank arm, the element edges and the shaded faces
did not meet (#260). The mesh is conforming; the display drew each hex20
face and edge as straight chords between corners while the mid-side
nodes lie on the curved surface (up to 0.44 mm off the chord at 3 mm),
and drew the geometry's face boundaries from the design tessellation,
off both.

Now a quadratic face is cut into triangles whose vertices are its
corners and mid-side nodes, each edge is drawn as its two halves, and
over the mesh the geometry's edges (and a hovered design edge) are drawn
as the element edges on geometry edges (`DisplayEdge::feature`), so
faces, edges, feature lines and the highlight share their vertices.

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-14 22:13:15 -04:00
1 parent 9e38fe866d
commit a0f48c7207
4 files changed
+233 -78

No files matched your search

+8 -2
View File
@@ -141,8 +141,14 @@ fn model_scene(d: &DisplayMesh, p: &Palette) -> Scene {
s.tris.extend(d.surface_tris.iter().map(|t| SceneTri { p: t.p, normal: t.normal, color: d.body_color(t, p.geometry, &p.bodies) }));
}
s.lines = d.edges.iter().map(|e| SceneLine { a: e.p[0], b: e.p[1], color: p.mesh_edge, width: EDGE_WIDTH }).collect();
let edge = if faces_drawn { p.mesh_edge } else { p.geometry_edge };
s.lines.extend(d.surface_edges.iter().map(|[a, b]| SceneLine { a: *a, b: *b, color: edge, width: GEOMETRY_EDGE_WIDTH }));
if faces_drawn {
s.lines.extend(d.surface_edges.iter().map(|[a, b]| SceneLine { a: *a, b: *b, color: p.mesh_edge, width: GEOMETRY_EDGE_WIDTH }));
} else {
// Over the mesh the geometry's edges are drawn along it (the element edges on them), so
// they lie on the element faces.
let edge = p.geometry_edge;
s.lines.extend(d.edges.iter().filter(|e| e.feature).map(|e| SceneLine { a: e.p[0], b: e.p[1], color: edge, width: GEOMETRY_EDGE_WIDTH }));
}
s.lines.extend(d.lines.iter().map(|l| SceneLine { a: l.a, b: l.b, color: p.element(l.kind), width: LINE_ELEMENT_WIDTH }));
s
}