forked from 1b-agent/fieldcraft-upstream
render: the bodies of a design with several in their own colours
Geometry triangles remember their surface (body); the viewport and the headless pictures draw each body of a multi-body design, such as the cells of a partitioned part, in its own colour from the theme (eight in turn), and a single body in the geometry colour as before. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
This commit is contained in:
1 parent
7f5399c7e9
commit
98d2f55407
4 files changed
+63
-3
No files matched your search
@@ -32,6 +32,8 @@ pub struct Palette {
|
|||||||
pub mesh_edge: Rgb,
|
pub mesh_edge: Rgb,
|
||||||
pub geometry: Rgb,
|
pub geometry: Rgb,
|
||||||
pub geometry_edge: Rgb,
|
pub geometry_edge: Rgb,
|
||||||
|
/// The bodies of a design with several, in turn.
|
||||||
|
pub bodies: [Rgb; 8],
|
||||||
/// Faces of nodes without a value in a contour plot.
|
/// Faces of nodes without a value in a contour plot.
|
||||||
pub no_result: Rgb,
|
pub no_result: Rgb,
|
||||||
/// The contour colour scale, low to high.
|
/// The contour colour scale, low to high.
|
||||||
@@ -52,6 +54,16 @@ impl Palette {
|
|||||||
mesh_edge: Rgb(0x1e, 0x23, 0x2a),
|
mesh_edge: Rgb(0x1e, 0x23, 0x2a),
|
||||||
geometry: Rgb(0xb4, 0xba, 0xc4),
|
geometry: Rgb(0xb4, 0xba, 0xc4),
|
||||||
geometry_edge: Rgb(0x2a, 0x30, 0x3a),
|
geometry_edge: Rgb(0x2a, 0x30, 0x3a),
|
||||||
|
bodies: [
|
||||||
|
Rgb(0x8f, 0xb4, 0xd9),
|
||||||
|
Rgb(0xe0, 0xa4, 0x6c),
|
||||||
|
Rgb(0x8c, 0xc4, 0x8a),
|
||||||
|
Rgb(0xd6, 0x8c, 0x96),
|
||||||
|
Rgb(0xb0, 0x9c, 0xd8),
|
||||||
|
Rgb(0xd8, 0xc8, 0x70),
|
||||||
|
Rgb(0x7c, 0xc4, 0xc0),
|
||||||
|
Rgb(0xc0, 0xa0, 0x84),
|
||||||
|
],
|
||||||
no_result: Rgb(0x9a, 0xa0, 0xaa),
|
no_result: Rgb(0x9a, 0xa0, 0xaa),
|
||||||
contour: [Rgb(0x2b, 0x4f, 0xd8), Rgb(0x2f, 0xb8, 0xe0), Rgb(0x3c, 0xc8, 0x64), Rgb(0xf0, 0xd2, 0x3c), Rgb(0xe0, 0x40, 0x2e)],
|
contour: [Rgb(0x2b, 0x4f, 0xd8), Rgb(0x2f, 0xb8, 0xe0), Rgb(0x3c, 0xc8, 0x64), Rgb(0xf0, 0xd2, 0x3c), Rgb(0xe0, 0x40, 0x2e)],
|
||||||
glyphs: GlyphColors {
|
glyphs: GlyphColors {
|
||||||
@@ -125,7 +137,7 @@ fn model_scene(d: &DisplayMesh, p: &Palette) -> Scene {
|
|||||||
s.tris = d.tris.iter().map(|t| SceneTri { p: t.p, normal: t.normal, color: p.element(t.kind) }).collect();
|
s.tris = d.tris.iter().map(|t| SceneTri { p: t.p, normal: t.normal, color: p.element(t.kind) }).collect();
|
||||||
let faces_drawn = d.tris.is_empty();
|
let faces_drawn = d.tris.is_empty();
|
||||||
if faces_drawn {
|
if faces_drawn {
|
||||||
s.tris.extend(d.surface_tris.iter().map(|t| SceneTri { p: t.p, normal: t.normal, color: p.geometry }));
|
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();
|
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 };
|
let edge = if faces_drawn { p.mesh_edge } else { p.geometry_edge };
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ pub struct DisplayNode {
|
|||||||
pub struct SurfaceTri {
|
pub struct SurfaceTri {
|
||||||
pub p: [Vec3; 3],
|
pub p: [Vec3; 3],
|
||||||
pub normal: Vec3,
|
pub normal: Vec3,
|
||||||
|
/// Which surface (body) it belongs to: the order [`DisplayMesh::add_surface`] got them in.
|
||||||
|
pub body: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Display data for a model and its geometry.
|
/// Display data for a model and its geometry.
|
||||||
@@ -72,6 +74,8 @@ pub struct DisplayMesh {
|
|||||||
pub surface_tris: Vec<SurfaceTri>,
|
pub surface_tris: Vec<SurfaceTri>,
|
||||||
/// Geometry edges: where two faces meet, and open boundaries.
|
/// Geometry edges: where two faces meet, and open boundaries.
|
||||||
pub surface_edges: Vec<[Vec3; 2]>,
|
pub surface_edges: Vec<[Vec3; 2]>,
|
||||||
|
/// Geometry surfaces (bodies) added.
|
||||||
|
pub bodies: u32,
|
||||||
pub bounds: Aabb3,
|
pub bounds: Aabb3,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +229,7 @@ impl DisplayMesh {
|
|||||||
for p in [a, b, c] {
|
for p in [a, b, c] {
|
||||||
self.bounds.add(p);
|
self.bounds.add(p);
|
||||||
}
|
}
|
||||||
self.surface_tris.push(SurfaceTri { p: [a, b, c], normal });
|
self.surface_tris.push(SurfaceTri { p: [a, b, c], normal, body: self.bodies });
|
||||||
let face = tri_face.get(t).copied().unwrap_or(u32::MAX);
|
let face = tri_face.get(t).copied().unwrap_or(u32::MAX);
|
||||||
let [v0, v1, v2] = [vertex(i0), vertex(i1), vertex(i2)];
|
let [v0, v1, v2] = [vertex(i0), vertex(i1), vertex(i2)];
|
||||||
for (u, v) in [(v0, v1), (v1, v2), (v2, v0)] {
|
for (u, v) in [(v0, v1), (v1, v2), (v2, v0)] {
|
||||||
@@ -241,6 +245,17 @@ impl DisplayMesh {
|
|||||||
self.surface_edges.push([a, b]);
|
self.surface_edges.push([a, b]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.bodies = self.bodies.saturating_add(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The colour of a geometry triangle: `single` when there is one body, else body `k`'s
|
||||||
|
/// colour from `palette` (cycling), so the bodies of a design, such as the cells of a
|
||||||
|
/// partitioned part, tell apart.
|
||||||
|
pub fn body_color<C: Copy>(&self, tri: &SurfaceTri, single: C, palette: &[C]) -> C {
|
||||||
|
if self.bodies <= 1 || palette.is_empty() {
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
palette.get(tri.body as usize % palette.len()).copied().unwrap_or(single)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Where node `label` is drawn, if it is (nodes are kept in label order).
|
/// Where node `label` is drawn, if it is (nodes are kept in label order).
|
||||||
@@ -401,6 +416,13 @@ mod tests {
|
|||||||
welded.add_surface(&soup, &[[0, 1, 2], [3, 4, 5]], &[0, 0]);
|
welded.add_surface(&soup, &[[0, 1, 2], [3, 4, 5]], &[0, 0]);
|
||||||
assert_eq!(welded.surface_edges.len(), 4);
|
assert_eq!(welded.surface_edges.len(), 4);
|
||||||
let mut hostile = DisplayMesh::default();
|
let mut hostile = DisplayMesh::default();
|
||||||
|
let mut two = DisplayMesh::default();
|
||||||
|
two.add_surface(&p, &[[0, 1, 2]], &[0]);
|
||||||
|
two.add_surface(&p, &[[0, 2, 3]], &[0]);
|
||||||
|
assert_eq!(two.bodies, 2);
|
||||||
|
let colors: Vec<u8> = two.surface_tris.iter().map(|t| two.body_color(t, 0u8, &[7, 8])).collect();
|
||||||
|
assert_eq!(colors, vec![7, 8]);
|
||||||
|
assert_eq!(one_face.body_color(&one_face.surface_tris[0], 0u8, &[7, 8]), 0);
|
||||||
hostile.add_surface(&[[f64::NAN, 0., 0.], [1., 0., 0.], [0., 1., 0.]], &[[0, 1, 2], [u32::MAX, 0, 1]], &[]);
|
hostile.add_surface(&[[f64::NAN, 0., 0.], [1., 0., 0.], [0., 1., 0.]], &[[0, 1, 2], [u32::MAX, 0, 1]], &[]);
|
||||||
assert!(hostile.surface_tris.is_empty() && hostile.surface_edges.is_empty());
|
assert!(hostile.surface_tris.is_empty() && hostile.surface_edges.is_empty());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,11 @@ pub fn build(display: &DisplayMesh, style: Style, show: Show, t: &Tokens) -> Sce
|
|||||||
s.tris = display.tris.iter().map(|d| SceneTri { p: d.p, normal: d.normal, color: rgb(t.element(d.kind)) }).collect();
|
s.tris = display.tris.iter().map(|d| SceneTri { p: d.p, normal: d.normal, color: rgb(t.element(d.kind)) }).collect();
|
||||||
}
|
}
|
||||||
if !mesh_faces && show.geometry {
|
if !mesh_faces && show.geometry {
|
||||||
s.tris.extend(display.surface_tris.iter().map(|d| SceneTri { p: d.p, normal: d.normal, color: rgb(t.geometry) }));
|
s.tris.extend(display.surface_tris.iter().map(|d| SceneTri {
|
||||||
|
p: d.p,
|
||||||
|
normal: d.normal,
|
||||||
|
color: rgb(display.body_color(d, t.geometry, &t.bodies)),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if style != Style::Shaded && show.mesh {
|
if style != Style::Shaded && show.mesh {
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ pub struct Tokens {
|
|||||||
pub geometry: Color32,
|
pub geometry: Color32,
|
||||||
/// Their face boundaries.
|
/// Their face boundaries.
|
||||||
pub geometry_edge: Color32,
|
pub geometry_edge: Color32,
|
||||||
|
/// The bodies of a design with several (the cells of a partitioned part), in turn.
|
||||||
|
pub bodies: [Color32; 8],
|
||||||
// ---- results ----
|
// ---- results ----
|
||||||
/// The contour colour scale, low to high (the same in both themes).
|
/// The contour colour scale, low to high (the same in both themes).
|
||||||
pub contour: [Color32; 5],
|
pub contour: [Color32; 5],
|
||||||
@@ -137,6 +139,16 @@ impl Tokens {
|
|||||||
node: Color32::from_rgb(0xb4, 0x3c, 0x8c),
|
node: Color32::from_rgb(0xb4, 0x3c, 0x8c),
|
||||||
geometry: Color32::from_rgb(176, 186, 198),
|
geometry: Color32::from_rgb(176, 186, 198),
|
||||||
geometry_edge: Color32::from_rgb(40, 44, 52),
|
geometry_edge: Color32::from_rgb(40, 44, 52),
|
||||||
|
bodies: [
|
||||||
|
Color32::from_rgb(0x8f, 0xb4, 0xd9),
|
||||||
|
Color32::from_rgb(0xe0, 0xa4, 0x6c),
|
||||||
|
Color32::from_rgb(0x8c, 0xc4, 0x8a),
|
||||||
|
Color32::from_rgb(0xd6, 0x8c, 0x96),
|
||||||
|
Color32::from_rgb(0xb0, 0x9c, 0xd8),
|
||||||
|
Color32::from_rgb(0xd8, 0xc8, 0x70),
|
||||||
|
Color32::from_rgb(0x7c, 0xc4, 0xc0),
|
||||||
|
Color32::from_rgb(0xc0, 0xa0, 0x84),
|
||||||
|
],
|
||||||
contour: CONTOUR,
|
contour: CONTOUR,
|
||||||
no_result: Color32::from_rgb(0x9a, 0xa0, 0xaa),
|
no_result: Color32::from_rgb(0x9a, 0xa0, 0xaa),
|
||||||
glyph_constraint: Color32::from_rgb(0x00, 0x8a, 0xa8),
|
glyph_constraint: Color32::from_rgb(0x00, 0x8a, 0xa8),
|
||||||
@@ -188,6 +200,16 @@ impl Tokens {
|
|||||||
t.node = Color32::from_rgb(0xf2, 0xe6, 0x6e);
|
t.node = Color32::from_rgb(0xf2, 0xe6, 0x6e);
|
||||||
t.geometry = Color32::from_rgb(152, 156, 162);
|
t.geometry = Color32::from_rgb(152, 156, 162);
|
||||||
t.geometry_edge = Color32::from_rgb(16, 16, 18);
|
t.geometry_edge = Color32::from_rgb(16, 16, 18);
|
||||||
|
t.bodies = [
|
||||||
|
Color32::from_rgb(0x6c, 0x92, 0xb8),
|
||||||
|
Color32::from_rgb(0xbc, 0x84, 0x50),
|
||||||
|
Color32::from_rgb(0x6c, 0xa2, 0x6a),
|
||||||
|
Color32::from_rgb(0xb4, 0x6e, 0x78),
|
||||||
|
Color32::from_rgb(0x90, 0x7e, 0xb6),
|
||||||
|
Color32::from_rgb(0xb6, 0xa6, 0x54),
|
||||||
|
Color32::from_rgb(0x5c, 0xa2, 0x9e),
|
||||||
|
Color32::from_rgb(0xa0, 0x82, 0x66),
|
||||||
|
];
|
||||||
t.no_result = Color32::from_rgb(0x70, 0x76, 0x80);
|
t.no_result = Color32::from_rgb(0x70, 0x76, 0x80);
|
||||||
t.glyph_constraint = Color32::from_rgb(0x3c, 0xdc, 0xf0);
|
t.glyph_constraint = Color32::from_rgb(0x3c, 0xdc, 0xf0);
|
||||||
t.glyph_load = Color32::from_rgb(0xff, 0x5a, 0x4c);
|
t.glyph_load = Color32::from_rgb(0xff, 0x5a, 0x4c);
|
||||||
|
|||||||
Reference in new issue
Block a user