Files
Sylpheed/crates/sylpheed-formats/examples/slab_screen.rs
MechaCat02 ccd49ac31f fix(lint): clear the clippy gate across examples and tests
80 findings, not the 14 the first run showed -- clippy stops at the first
failing compilation unit, so `--keep-going` is what makes the list complete.

60 were machine-applicable (`cargo clippy --fix`). The rest by hand:

* five descending `sort_by` -> `sort_by_key(Reverse(..))`
* `chunks_exact(4)` on both sides of four zips, so the compared items stay
  `[u8; 4]` rather than one array against one slice
* three `type` aliases for the census maps and the captured-quad tuple
* `&PathBuf` -> `&Path` in two disc tests
* two range loops; one of them keeps `#[allow(needless_range_loop)]` with the
  reason -- the index is into a map's value, which changes each iteration
* the module doc list in `invert_capture` re-indented to markdown's rules
* `blit`'s eight arguments get `#[allow(too_many_arguments)]`, not a struct

One dead `let off = b.len();` in a `ratc` test is dropped rather than renamed.
The sibling test at :162 is the one that asserts an offset; if this one was
meant to as well, that is a test change and not a lint fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:42:41 +02:00

85 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Screen every ship family for a part that is wildly out of scale with its
//! siblings — the "slab" signature of a mis-anchored block.
//!
//! Rendering `e106` found such a part (`bdy_03`, 600×1600×998 beside parts of
//! ~250) that coverage, cross-container consistency, the capture oracle and the
//! twin invariant were all blind to. Eyeballing does not scale to 166 containers;
//! this does the same comparison numerically.
//!
//! Usage: slab_screen <resource3d_dir> [factor]
use std::collections::BTreeMap;
use sylpheed_formats::mesh::Xbg7Model;
use sylpheed_formats::ship::{is_base_part, ship_id_of};
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let factor: f32 = std::env::args()
.nth(2)
.and_then(|s| s.parse().ok())
.unwrap_or(4.0);
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut flagged = 0usize;
for f in &files {
let Ok(bytes) = std::fs::read(f) else {
continue;
};
let mut by_ship: BTreeMap<String, Vec<(String, f32)>> = BTreeMap::new();
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
if !is_base_part(&m.name) {
continue;
}
let Some(id) = ship_id_of(&m.name) else {
continue;
};
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
}
if lo[0] == f32::MAX {
continue;
}
// Compare the part's SMALLEST axis span, not its diagonal. A long
// thin part (an antenna, a 100 000-unit tether on `f002`) is
// legitimately huge in one axis and would swamp a diagonal test; a
// mis-anchored block is bulky in all three, which is what the e106
// slab looked like (600×1600×998 beside siblings of ~250).
let thin = (hi[0] - lo[0]).min(hi[1] - lo[1]).min(hi[2] - lo[2]);
by_ship
.entry(id.to_string())
.or_default()
.push((m.name.clone(), thin));
}
for parts in by_ship.values() {
if parts.len() < 3 {
continue; // no meaningful median
}
let mut d: Vec<f32> = parts.iter().map(|(_, x)| *x).collect();
d.sort_by(|a, b| a.partial_cmp(b).unwrap());
let median = d[d.len() / 2];
for (name, diag) in parts {
if *diag > median * factor {
flagged += 1;
println!(
"{:<22} {name:<22} min-axis {diag:>8.0} vs ship median {median:>8.0} ({:.1}×)",
f.file_name().unwrap().to_string_lossy(),
diag / median
);
}
}
}
}
println!("{flagged} parts flagged at {factor}× the ship median");
}