#[non_exhaustive]pub enum Event {
Show 26 variants
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<DisplayDelta>,
zone: usize,
kind: DeltaKind,
t: f64,
frame: DisplayFrame,
},
Warning {
meta: Meta,
message: String,
},
Error {
meta: Meta,
message: String,
},
}Expand description
Pipeline events (per-stage results). Every variant carries a Meta.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
FrameIngested
The frame bundle of one position has arrived.
Fields
FrameDecoded
Decoding of one input frame is complete. Comes first, before the position is processed (only when SessionConfig::decode_frames
is on).
Started
Session start (once, at the first input). positions = total number of known positions. (added by session)
Fields
Log
One run.log line. If stamped, it is written with a [HH:MM:SS] prefix (meta.at local time). (added by session)
Fields
FeaturesExtracted
Feature extraction of one image is complete.
Fields
PairsMatched
Result of matching new pairs.
pairs = pairs matched at this position, verified = pairs with valid geometry, matched = pairs for which descriptor matching
was performed.
Fields
ModelInitialized
The first model has been built.
Fields
model: Arc<Reconstruction>Copy of the relevant model.
FrameRegistered
An image has been registered to the model.
Fields
PositionDone
Registration and triangulation of one position are finished.
Fields
ZoneArrived
The last position of a zone has arrived.
model = copy of the chain model at that point (before alignment).
Fields
model: Arc<Reconstruction>Copy of the relevant model.
ZonePreview
Zone preview point cloud (no BA).
model = preview model (zone 0 is the GPS-aligned one), dense = false means densification was not run or failed and cloud is
an empty placeholder.
frame = point-cloud coordinate frame (“gps” | “refined_K” | “unaligned”).
Fields
cloud: Arc<PointCloud>Point cloud (an empty placeholder if there is no densification).
model: Arc<Reconstruction>Copy of the relevant model.
RefineStarted
Refinement job start (background). (added by session)
ZoneAdjusted
Model right after BA of the refinement job (before GPS alignment). (added by session)
Fields
model: Arc<Reconstruction>Copy of the relevant model.
ZoneRefinedPose
Zone refined pose finalized (BA + GPS alignment).
model = refined model after BA + GPS alignment.
Fields
model: Arc<Reconstruction>Copy of the relevant model.
ZoneRefined
Zone refined point cloud. It replaces the preview of the same zone.
dense = false means cloud is an empty placeholder.
Fields
cloud: Arc<PointCloud>Point cloud (an empty placeholder if there is no densification).
model: Arc<Reconstruction>Copy of the relevant model.
BaseAdopted
The refined model was adopted as the reference for subsequent registration.
Reanchored
Coordinate-frame transform of an already sent zone (the point cloud is not sent again): new_from_old.
Snapshot
Snapshot for display (event sequence number and composite point cloud).
Fields
cloud: Arc<PointCloud>Point cloud (an empty placeholder if there is no densification).
AllPositionsDone
All positions processed.
AllRefinedDone
All refinement jobs complete.
chain = final chain model.
Finished
Session end summary (the last of all events). stage_times = (stage, accumulated time, count) in stage-name order,
pipeline_secs = start to all refinements complete, chain_stats = statistics line of the final chain model. (added by session)
Fields
Reset
Command::ResetFrom was handled. (added by session)
ZoneInvalidated
Command::InvalidateZone was handled. (added by session)
DisplayDelta
Incremental display update computed by the library (opt-in, see NodeBuilder::display_deltas and
crate::live::DisplayFeed): the point-keyed difference between the previous and the new composed display cloud after
a zone result. Emitted right after the event that caused it.
Fields
delta: Arc<DisplayDelta>Adds, moves and removes with dense slot ids (apply: removes, adds, moves).
frame: DisplayFrameCoordinate frame of the display points.
Warning
Warning.
Error
Error (including hook panics).
Implementations§
Source§impl Event
impl Event
Sourcepub fn meta(&self) -> &Meta
pub fn meta(&self) -> &Meta
Common header.
Examples found in repository?
49fn main() -> Result<(), String> {
50 let out = std::env::args().nth(1).map(PathBuf::from).unwrap_or_else(|| std::env::temp_dir().join("cumulus3d_hooks"));
51 let src = out.with_extension("src");
52 if !src.join("gps_ref.txt").exists() {
53 common::make_dataset(&src);
54 }
55 if out.exists() {
56 std::fs::remove_dir_all(&out).map_err(|e| e.to_string())?;
57 }
58 let layout = Layout::discover(&src, 1)?;
59 let npos = layout.frames.len();
60
61 let mut cfg = SessionConfig::new(src.join("images"));
62 cfg.gps = read_gps_file(src.join("gps_ref.txt")).map_err(|e| e.to_string())?;
63 (cfg.span, cfg.overlap, cfg.total_positions, cfg.seed) = (4, 1, Some(npos), Some(7));
64 if cumulus3d_cuda::is_available() {
65 let mut d = DenseConfig::new(make_pm_backend("cuda"), parse_profile("fast")?);
66 d.undistort.max_image_size = 160;
67 cfg.dense = Some(d);
68 }
69
70 // Hook: print event text, zone point-cloud point counts, warnings and errors; plus the default output hook (files).
71 let pipeline = Pipeline::new(Session::new(cfg))
72 .on_any(|e: &Event| {
73 if let Some(t) = e.timeline_text() {
74 println!("[event v{}] {t}", e.meta().version);
75 }
76 })
77 .on(EventKind::ZonePreview, |e: &Event| {
78 if let Event::ZonePreview { range, cloud, model, .. } = e {
79 println!(" 초벌 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
80 }
81 })
82 .on(EventKind::ZoneRefined, |e: &Event| {
83 if let Event::ZoneRefined { range, cloud, model, .. } = e {
84 println!(" 정밀 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
85 }
86 })
87 .on_message(|k, m| eprintln!(" {k:?}: {m}"));
88 let mut pipeline = sinks::attach(pipeline, &out, &SinkOptions::default()).map_err(|e| e.to_string())?;
89
90 for p in 0..npos {
91 pipeline.push(Input::Frames(FrameSet::new(CAMS.iter().map(|c| (*c, layout.name(c, p))))));
92 }
93 let (_, summary) = pipeline.finish();
94 println!("이벤트 {} 개, 훅 호출 {} 번, 훅 패닉 {}", summary.events, summary.hook_calls, summary.hook_panics);
95
96 for f in ["timeline.txt", "run.log", "snapshots/manifest.json", "snapshots/timeline.txt", "DONE"] {
97 let p = out.join(f);
98 println!("{} {}", if p.exists() { "있음" } else { "없음" }, p.display());
99 }
100 Ok(())
101}Source§impl Event
impl Event
Sourcepub fn timeline_text(&self) -> Option<String>
pub fn timeline_text(&self) -> Option<String>
Event text for timeline.txt (None if there is none). The wording and format are the same as the existing record.
Examples found in repository?
49fn main() -> Result<(), String> {
50 let out = std::env::args().nth(1).map(PathBuf::from).unwrap_or_else(|| std::env::temp_dir().join("cumulus3d_hooks"));
51 let src = out.with_extension("src");
52 if !src.join("gps_ref.txt").exists() {
53 common::make_dataset(&src);
54 }
55 if out.exists() {
56 std::fs::remove_dir_all(&out).map_err(|e| e.to_string())?;
57 }
58 let layout = Layout::discover(&src, 1)?;
59 let npos = layout.frames.len();
60
61 let mut cfg = SessionConfig::new(src.join("images"));
62 cfg.gps = read_gps_file(src.join("gps_ref.txt")).map_err(|e| e.to_string())?;
63 (cfg.span, cfg.overlap, cfg.total_positions, cfg.seed) = (4, 1, Some(npos), Some(7));
64 if cumulus3d_cuda::is_available() {
65 let mut d = DenseConfig::new(make_pm_backend("cuda"), parse_profile("fast")?);
66 d.undistort.max_image_size = 160;
67 cfg.dense = Some(d);
68 }
69
70 // Hook: print event text, zone point-cloud point counts, warnings and errors; plus the default output hook (files).
71 let pipeline = Pipeline::new(Session::new(cfg))
72 .on_any(|e: &Event| {
73 if let Some(t) = e.timeline_text() {
74 println!("[event v{}] {t}", e.meta().version);
75 }
76 })
77 .on(EventKind::ZonePreview, |e: &Event| {
78 if let Event::ZonePreview { range, cloud, model, .. } = e {
79 println!(" 초벌 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
80 }
81 })
82 .on(EventKind::ZoneRefined, |e: &Event| {
83 if let Event::ZoneRefined { range, cloud, model, .. } = e {
84 println!(" 정밀 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
85 }
86 })
87 .on_message(|k, m| eprintln!(" {k:?}: {m}"));
88 let mut pipeline = sinks::attach(pipeline, &out, &SinkOptions::default()).map_err(|e| e.to_string())?;
89
90 for p in 0..npos {
91 pipeline.push(Input::Frames(FrameSet::new(CAMS.iter().map(|c| (*c, layout.name(c, p))))));
92 }
93 let (_, summary) = pipeline.finish();
94 println!("이벤트 {} 개, 훅 호출 {} 번, 훅 패닉 {}", summary.events, summary.hook_calls, summary.hook_panics);
95
96 for f in ["timeline.txt", "run.log", "snapshots/manifest.json", "snapshots/timeline.txt", "DONE"] {
97 let p = out.join(f);
98 println!("{} {}", if p.exists() { "있음" } else { "없음" }, p.display());
99 }
100 Ok(())
101}Trait Implementations§
Auto Trait Implementations§
impl Freeze for Event
impl RefUnwindSafe for Event
impl Send for Event
impl Sync for Event
impl Unpin for Event
impl UnsafeUnpin for Event
impl UnwindSafe for Event
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.