diff --git a/crates/track/src/camtrack/solver.rs b/crates/track/src/camtrack/solver.rs index 5ed7b81b..a4e2c21e 100644 --- a/crates/track/src/camtrack/solver.rs +++ b/crates/track/src/camtrack/solver.rs @@ -113,7 +113,7 @@ fn keyframes(d: &Data) -> Vec { j += 1; } if let Some(lastf) = (0..d.n).rev().find(|k| d.by_frame[*k].len() >= 8) - && *kf.last().expect("one") < lastf + && kf.last().is_some_and(|l| *l < lastf) { kf.push(lastf); } @@ -237,10 +237,10 @@ impl Recon { .iter() .map(|k| { let c = &self.cams[k]; - let uv = d.at(*ti, *k).expect("seen"); - (c.pose, [uv[0] / c.f, uv[1] / c.f], c) + let uv = d.at(*ti, *k)?; + Some((c.pose, [uv[0] / c.f, uv[1] / c.f], c)) }) - .collect(); + .collect::>()?; let x = match kind { Kind::Tripod => normalize(views.iter().fold([0.0; 3], |a, (p, o, _)| add(a, normalize(mtv(&p.r, [o[0], o[1], 1.0]))))), Kind::General => { @@ -255,7 +255,7 @@ impl Recon { } }; for (k, (_, _, c)) in ks.iter().zip(&views) { - let uv = d.at(*ti, *k).expect("seen"); + let uv = d.at(*ti, *k)?; let r = bundle::residual(c, x, uv)?; if r[0] * r[0] + r[1] * r[1] > thr2 { return None; @@ -675,7 +675,7 @@ fn undistorted(tracks: &CameraTracks, dist: &Distortion) -> CameraTracks { pub fn solve(tracks: &CameraTracks, s: &SolveSettings, cancel: Option<&AtomicBool>) -> Result { if !s.lens_distortion { let c = solve_core(tracks, s, cancel)?; - return Ok(finish(&c.d, tracks, s, c.r, c.method, c.kind)); + return finish(&c.d, tracks, s, c.r, c.method, c.kind); } // Lens distortion: solve, adjust (k1, k2) jointly on the raw tracks, then solve again on // tracks undistorted with the estimate and adjust jointly once more. @@ -734,7 +734,7 @@ pub fn solve(tracks: &CameraTracks, s: &SolveSettings, cancel: Option<&AtomicBoo if debug() { eprintln!("lens distortion pass {pass}: k1 {:.5} k2 {:.5}", dist.k1, dist.k2); } - let mut sol = finish(&d, tracks, s, r, c.method, c.kind); + let mut sol = finish(&d, tracks, s, r, c.method, c.kind)?; sol.distortion = Some(dist); out = Some(sol); } @@ -817,8 +817,8 @@ fn solve_core(tracks: &CameraTracks, s: &SolveSettings, cancel: Option<&AtomicBo let rg = &results[g].0.recon; let cs: Vec = rg.cams.values().map(|c| c.pose.c).collect(); let base = cs.iter().flat_map(|a| cs.iter().map(move |b| norm(sub(*a, *b)))).fold(0.0, f64::max); - let c0 = rg.cams.values().next().expect("camera"); - let mut depth: Vec = rg.pts.values().map(|x| norm(sub(*x, c0.pose.c))).collect(); + let c0 = rg.cams.values().next().map_or([0.0; 3], |c| c.pose.c); + let mut depth: Vec = rg.pts.values().map(|x| norm(sub(*x, c0))).collect(); depth.sort_by(f64::total_cmp); let med = depth.get(depth.len() / 2).copied().unwrap_or(1.0); if debug() { @@ -969,8 +969,8 @@ fn cov_ratio(p: &[V3]) -> f64 { } /// Canonical frame, per-frame output (unsolved frames interpolated), points and errors. -fn finish(d: &Data, tracks: &CameraTracks, s: &SolveSettings, r: Recon, method: SolveMethod, kind: Kind) -> CameraSolve { - let (k0, c0) = r.cams.iter().next().map(|(k, c)| (*k, *c)).expect("solved"); +fn finish(d: &Data, tracks: &CameraTracks, s: &SolveSettings, r: Recon, method: SolveMethod, kind: Kind) -> Result { + let Some((k0, c0)) = r.cams.iter().next().map(|(k, c)| (*k, *c)) else { return err("the camera could not be solved (no frame was solved)") }; // Scale: median depth of the points seen by the first solved camera is 1. let mut depths: Vec = d.by_frame[k0].iter().filter_map(|(ti, _)| r.pts.get(ti)).map(|x| c0.pose.to_cam(*x)[2]).filter(|z| *z > 0.0).collect(); depths.sort_by(f64::total_cmp); @@ -1038,7 +1038,7 @@ fn finish(d: &Data, tracks: &CameraTracks, s: &SolveSettings, r: Recon, method: en += n1; points.push(SolvedPoint { id: *id, pos: to_world(x), error: (s1 / n1 as f64) as f32, first: *start as u32, last: (start + pts.len() - 1) as u32 }); } - CameraSolve { + Ok(CameraSolve { version: 1, size: tracks.size, start: tracks.start, @@ -1050,5 +1050,5 @@ fn finish(d: &Data, tracks: &CameraTracks, s: &SolveSettings, r: Recon, method: points, ground: None, distortion: None, - } + }) } diff --git a/crates/track/src/klt.rs b/crates/track/src/klt.rs index 6c569c31..a4566c79 100644 --- a/crates/track/src/klt.rs +++ b/crates/track/src/klt.rs @@ -65,7 +65,7 @@ impl GrayPyramid { pub fn from_plane(base: Plane, offset: [f64; 2], factor: f64, levels: usize) -> GrayPyramid { let mut lv = vec![base]; for _ in 0..levels { - let last = lv.last().expect("level"); + let Some(last) = lv.last() else { break }; if last.w < 16 || last.h < 16 { break; } diff --git a/crates/track/src/lib.rs b/crates/track/src/lib.rs index f4a7b88f..fe36bc09 100644 --- a/crates/track/src/lib.rs +++ b/crates/track/src/lib.rs @@ -18,6 +18,8 @@ //! Coordinates are *layer* pixels: the frame image's pixel `(i, j)` covers `[i, i+1) × [j, j+1)` //! after subtracting the frame's `offset` (see [`Frame`]). +#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] + pub mod camtrack; pub mod face; pub mod fit; diff --git a/crates/track/src/subspace.rs b/crates/track/src/subspace.rs index 339f9708..66b674b5 100644 --- a/crates/track/src/subspace.rs +++ b/crates/track/src/subspace.rs @@ -367,7 +367,7 @@ pub fn smooth_trajectories(tracks: &[Track2D], frames: usize, sigma: f64, rank: let mut ata = vec![0.0; k * k]; let mut atb = [vec![0.0; k], vec![0.0; k]]; for &c in &cols { - let p = tr.at((lo + c) as u32).expect("covered"); + let Some(p) = tr.at((lo + c) as u32) else { continue }; for a in 0..k { for d in 0..2 { atb[d][a] += cmat[a][c] * p[d]; @@ -391,8 +391,8 @@ pub fn smooth_trajectories(tracks: &[Track2D], frames: usize, sigma: f64, rank: } dst[d] = x.iter().zip(&chat).map(|(a, b)| a * b).sum(); } - if ok { - out.push((tr.at(t32).expect("seen"), dst)); + if ok && let Some(p) = tr.at(t32) { + out.push((p, dst)); } } out