use cumulus3d_core::io::ply::PointCloud;
use cumulus3d_core::{ImageId, Reconstruction, Rigid3, Sim3};
use std::sync::Arc;
use std::time::{Duration, SystemTime};
#[derive(Clone, Debug)]
pub struct Meta {
pub version: u64,
pub at: SystemTime,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ZoneRange {
pub zone: usize,
pub lo: usize,
pub hi: usize,
}
#[derive(Clone, Debug)]
pub struct Frame {
pub position: usize,
pub camera: String,
pub name: String,
pub path: std::path::PathBuf,
pub width: u32,
pub height: u32,
pub rgb: Arc<[u8]>,
pub gps: Option<cumulus3d_core::io::GpsRecord>,
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum Event {
FrameIngested {
meta: Meta,
position: usize,
images: Vec<String>,
},
FrameDecoded {
meta: Meta,
frame: Arc<Frame>,
},
Started {
meta: Meta,
positions: Option<usize>,
},
Log {
meta: Meta,
line: String,
stamped: bool,
},
FeaturesExtracted {
meta: Meta,
image: String,
count: usize,
position: usize,
image_id: ImageId,
},
PairsMatched {
meta: Meta,
pairs: usize,
verified: usize,
position: usize,
matched: usize,
},
ModelInitialized {
meta: Meta,
registered: usize,
position: usize,
model: Arc<Reconstruction>,
},
FrameRegistered {
meta: Meta,
position: usize,
image: String,
image_id: ImageId,
cam_from_world: Rigid3,
},
PositionDone {
meta: Meta,
position: usize,
registered: usize,
expected: usize,
},
ZoneArrived {
meta: Meta,
range: ZoneRange,
model: Arc<Reconstruction>,
},
ZonePreview {
meta: Meta,
range: ZoneRange,
cloud: Arc<PointCloud>,
model: Arc<Reconstruction>,
dense: bool,
frame: String,
},
RefineStarted {
meta: Meta,
zone: usize,
},
ZoneAdjusted {
meta: Meta,
zone: usize,
model: Arc<Reconstruction>,
},
ZoneRefinedPose {
meta: Meta,
range: ZoneRange,
registered: usize,
mean_reproj_px: f64,
model: Arc<Reconstruction>,
},
ZoneRefined {
meta: Meta,
range: ZoneRange,
cloud: Arc<PointCloud>,
model: Arc<Reconstruction>,
dense: bool,
},
BaseAdopted {
meta: Meta,
zone: usize,
},
Reanchored {
meta: Meta,
zone: usize,
transform: Sim3,
},
Snapshot {
meta: Meta,
index: usize,
cloud: Arc<PointCloud>,
},
AllPositionsDone {
meta: Meta,
},
AllRefinedDone {
meta: Meta,
chain: Option<Arc<Reconstruction>>,
},
Finished {
meta: Meta,
pipeline_secs: f64,
stage_times: Vec<(String, Duration, usize)>,
chain_stats: Vec<String>,
},
Reset {
meta: Meta,
position: usize,
},
ZoneInvalidated {
meta: Meta,
zone: usize,
},
DisplayDelta {
meta: Meta,
delta: Arc<crate::live::DisplayDelta>,
zone: usize,
kind: crate::live::DeltaKind,
t: f64,
frame: crate::live::DisplayFrame,
},
Warning {
meta: Meta,
message: String,
},
Error {
meta: Meta,
message: String,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum EventKind {
FrameIngested,
FrameDecoded,
Started,
Log,
RefineStarted,
ZoneAdjusted,
Finished,
Reset,
ZoneInvalidated,
FeaturesExtracted,
PairsMatched,
ModelInitialized,
FrameRegistered,
PositionDone,
ZoneArrived,
ZonePreview,
ZoneRefinedPose,
ZoneRefined,
BaseAdopted,
Reanchored,
Snapshot,
AllPositionsDone,
AllRefinedDone,
DisplayDelta,
Warning,
Error,
}
impl Event {
pub fn kind(&self) -> EventKind {
use Event::*;
match self {
FrameIngested { .. } => EventKind::FrameIngested,
FrameDecoded { .. } => EventKind::FrameDecoded,
Started { .. } => EventKind::Started,
Log { .. } => EventKind::Log,
RefineStarted { .. } => EventKind::RefineStarted,
ZoneAdjusted { .. } => EventKind::ZoneAdjusted,
Finished { .. } => EventKind::Finished,
Reset { .. } => EventKind::Reset,
ZoneInvalidated { .. } => EventKind::ZoneInvalidated,
FeaturesExtracted { .. } => EventKind::FeaturesExtracted,
PairsMatched { .. } => EventKind::PairsMatched,
ModelInitialized { .. } => EventKind::ModelInitialized,
FrameRegistered { .. } => EventKind::FrameRegistered,
PositionDone { .. } => EventKind::PositionDone,
ZoneArrived { .. } => EventKind::ZoneArrived,
ZonePreview { .. } => EventKind::ZonePreview,
ZoneRefinedPose { .. } => EventKind::ZoneRefinedPose,
ZoneRefined { .. } => EventKind::ZoneRefined,
BaseAdopted { .. } => EventKind::BaseAdopted,
Reanchored { .. } => EventKind::Reanchored,
Snapshot { .. } => EventKind::Snapshot,
AllPositionsDone { .. } => EventKind::AllPositionsDone,
AllRefinedDone { .. } => EventKind::AllRefinedDone,
DisplayDelta { .. } => EventKind::DisplayDelta,
Warning { .. } => EventKind::Warning,
Error { .. } => EventKind::Error,
}
}
pub fn meta(&self) -> &Meta {
use Event::*;
match self {
FrameIngested { meta, .. }
| FeaturesExtracted { meta, .. }
| PairsMatched { meta, .. }
| ModelInitialized { meta, .. }
| FrameRegistered { meta, .. }
| PositionDone { meta, .. }
| ZoneArrived { meta, .. }
| ZonePreview { meta, .. }
| ZoneRefinedPose { meta, .. }
| ZoneRefined { meta, .. }
| BaseAdopted { meta, .. }
| Reanchored { meta, .. }
| Snapshot { meta, .. }
| AllPositionsDone { meta }
| AllRefinedDone { meta, .. }
| FrameDecoded { meta, .. }
| Started { meta, .. }
| Log { meta, .. }
| RefineStarted { meta, .. }
| ZoneAdjusted { meta, .. }
| Finished { meta, .. }
| Reset { meta, .. }
| ZoneInvalidated { meta, .. }
| DisplayDelta { meta, .. }
| Warning { meta, .. }
| Error { meta, .. } => meta,
}
}
}
impl Event {
pub fn timeline_text(&self) -> Option<String> {
use Event::*;
Some(match self {
Started { positions, .. } => match positions {
Some(n) => format!("start NPOS={n}"),
None => "start".to_string(),
},
ModelInitialized { registered, .. } => format!("init_model Registered images: {registered}"),
BaseAdopted { zone, .. } => format!("adopt refined {zone} as base"),
PositionDone { position, registered, expected, .. } => format!("pos {position} registered {registered}/{expected}"),
ZoneArrived { range, .. } => format!("region {} arrived pos[{},{})", range.zone, range.lo, range.hi),
ZonePreview { range, .. } => format!("preview {} ready", range.zone),
RefineStarted { zone, .. } => format!("refined {zone} ba_start"),
ZoneRefinedPose { range, registered, mean_reproj_px, .. } => {
format!("refined {} pose_ready Registered images: {registered} Mean reprojection error: {mean_reproj_px:.6}px ", range.zone)
}
ZoneRefined { range, .. } => format!("refined {} ready", range.zone),
AllPositionsDone { .. } => "all positions done".to_string(),
AllRefinedDone { .. } => "all refined done".to_string(),
_ => return None,
})
}
}
#[derive(Clone, Debug)]
pub enum Command {
ResetFrom(usize),
InvalidateZone(usize),
}