1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! Solid inspection preview: a flat-shaded, edge-outlined CPU render of the current
//! design's [`indicatrix::geometry::stone_metrics::SolidMesh`], independent of the
//! GPU path tracer.
//!
//! [`raster`] is a pure-Rust, Slint-free rasterizer with its own unit tests.
//! [`to_pixel_buffer`] is the one bridge into Slint types, kept here so `raster.rs`
//! stays independently testable and reusable as the seam for a possible future `wgpu`
//! backend.
//!
//! [`mesh_cache`] caches the `SolidMesh` build plus a one-time ring-simplification
//! pass against the design's plane-set hash. [`preview_state`] is the editor-side
//! controller: one dedicated worker thread owning the cache and rasterizer,
//! coalescing redraw requests via `RedrawGate`, handing finished frames to a
//! [`preview_state::PreviewSink`] kept generic over Slint rather than depending on
//! `MainWindow` directly.
//!
//! [`facet_map`] maps a rasterized `facet_id` back to its tier/orbit-member for
//! hover/click/selection and the critical-angle overlay; [`live_update`] decides
//! which geometry to draw after an edit (`plan_preview`, budgeted `resolve_dirty` with
//! a pinned/fresh/stale/unsolvable outcome); [`edges_layer`] is the "Both" view mode's
//! transparent-fill, opaque-edges render; [`diagram2d`] is view mode 3's GemCAD-style
//! three-panel (crown/pavilion/profile) 2D facet diagram, with its own per-pixel
//! facet-picking buffer. All four are Slint-free; `facet_map`/`live_update` are gated
//! on `indicatrix-cut-core`, `edges_layer`/`diagram2d` are not.
/// Converts a finished [`raster::SolidRasterizer`] frame into a `Send`-safe pixel
/// buffer for [`preview_state::PreviewSink::apply`] to hand to the UI thread.
///
/// Deliberately a `slint::SharedPixelBuffer<slint::Rgba8Pixel>`, not a `slint::Image`
/// (not `Send` in this Slint version -- moving one into an `upgrade_in_event_loop`
/// closure fails to compile): `slint::Image::from_rgba8` is called only on the UI
/// thread, matching this crate's other cross-thread frame handoffs.
/// [`to_pixel_buffer`]'s twin for a [`diagram2d::DiagramFrame`] -- same reasoning
/// (a raw `SharedPixelBuffer`, never a `slint::Image`, so the worker thread's
/// result stays `Send`).