Model renders (screenshot with source model, ui.render) show the section the window shows: the CPU renderer drew the cut face on the far walls at their own depth in a plain grey hatch, so the inside of the body, its edges and the grid showed through it and the cut barely read as a section, it had no outline, perspective views cut along a curve, and an open Section Analysis dialog's preview (or a sketch's Slice) was ignored. The cut face now writes the section plane's depth where it is the visible surface (the CPU counterpart of the viewport's stencil cap), takes the viewport's cap tint and hatch, the cut outline is drawn (section_segments moved from the UI to engine::view and shared), world positions and lines are clipped perspective-correctly, and ui.render in the app uses the viewport's section plane
This commit is contained in:
1 parent
22672585c9
commit
21e0e99c86
7 files changed
+217
-46
No files matched your search
@@ -330,7 +330,7 @@ fn build_scene(app: &SolveApp) -> GpuScene {
|
||||
if let Some((o, n)) = section_plane(app) {
|
||||
let col = c4(tk.text.gamma_multiply(0.9));
|
||||
for b in st.bodies.iter().filter(|b| !app.session.visibility.hidden_bodies.contains(&b.name)) {
|
||||
for (a, c) in section_segments(&b.mesh(), o, n) {
|
||||
for (a, c) in solvecraft_engine::view::section_segments(&b.mesh(), o, n) {
|
||||
sc.line(a.to_f32(), c.to_f32(), col, 1.8, false);
|
||||
}
|
||||
}
|
||||
@@ -419,28 +419,6 @@ fn ground_shadow(sc: &mut GpuScene, app: &SolveApp, st: &solvecraft_engine::doc:
|
||||
}
|
||||
}
|
||||
|
||||
/// Where the plane through `o` with normal `n` cuts a mesh: one segment per crossed triangle,
|
||||
/// nudged a hair to the kept side (so the clip leaves them drawn).
|
||||
pub(crate) fn section_segments(m: &solvecraft_engine::geom::Mesh, o: Vec3, n: Vec3) -> Vec<(Vec3, Vec3)> {
|
||||
let eps = 1e-4 * (1.0 + m.bounds().diagonal());
|
||||
let mut out = Vec::new();
|
||||
for t in &m.triangles {
|
||||
let Some(p) = m.tri(t) else { continue };
|
||||
let d = p.map(|q| n.dot(q - o));
|
||||
let mut pts = Vec::with_capacity(2);
|
||||
for (i, j) in [(0, 1), (1, 2), (2, 0)] {
|
||||
if (d[i] < 0.0) != (d[j] < 0.0) {
|
||||
let s = d[i] / (d[i] - d[j]);
|
||||
pts.push(p[i] + (p[j] - p[i]) * s - n * eps);
|
||||
}
|
||||
}
|
||||
if let [a, b] = pts[..] {
|
||||
out.push((a, b));
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// The drawn pieces of a polyline in a dash pattern (on, off, on, off… lengths).
|
||||
pub(crate) fn dashes(pts: &[Vec3], pattern: &[f64]) -> Vec<(Vec3, Vec3)> {
|
||||
let mut out = Vec::new();
|
||||
@@ -2969,7 +2947,7 @@ mod tests {
|
||||
let st = s.model.state();
|
||||
let m = st.bodies[0].mesh();
|
||||
let (o, n) = (Vec3::new(0.0, 15.0, 0.0), Vec3::new(0.0, -1.0, 0.0));
|
||||
let segs = section_segments(&m, o, n);
|
||||
let segs = solvecraft_engine::view::section_segments(&m, o, n);
|
||||
assert!(segs.len() >= 4, "{segs:?}");
|
||||
// On the plane (a hair to the kept side) and around the 40 x 20 cut.
|
||||
let mut len = 0.0;
|
||||
@@ -2979,7 +2957,7 @@ mod tests {
|
||||
}
|
||||
assert!((len - 120.0).abs() < 0.5, "outline length {len}");
|
||||
// A plane that misses the body cuts nothing.
|
||||
assert!(section_segments(&m, Vec3::new(0.0, 99.0, 0.0), n).is_empty());
|
||||
assert!(solvecraft_engine::view::section_segments(&m, Vec3::new(0.0, 99.0, 0.0), n).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user