pub enum Event {
Show 24 variants
FrameIngested {
meta: Meta,
position: usize,
images: Vec<String>,
},
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,
},
Warning {
meta: Meta,
message: String,
},
Error {
meta: Meta,
message: String,
},
}Expand description
파이프라인 이벤트(단계별 결과). 모든 변형에 Meta 가 붙는다.
Variants§
FrameIngested
위치 하나의 프레임 묶음이 들어옴.
Started
세션 시작(첫 입력 때 한 번). positions = 알려진 전체 위치 수. (session 추가)
Log
run.log 한 줄. stamped 이면 [HH:MM:SS] 머리(meta.at 현지 시각)를 붙여 쓴다. (session 추가)
FeaturesExtracted
영상 하나의 특징 추출 완료.
Fields
PairsMatched
새 짝 매칭 결과.
pairs = 이번 위치에서 매칭한 짝 수, verified = 유효 기하 짝 수, matched = 기술자 매칭을 수행한 짝 수.
Fields
ModelInitialized
첫 모델이 만들어짐.
Fields
model: Arc<Reconstruction>관련 모델 사본.
FrameRegistered
영상이 모델에 등록됨.
Fields
PositionDone
위치 하나의 등록·삼각측량이 끝남.
Fields
ZoneArrived
구역의 마지막 위치가 도착함.
model = 그 시점 체인 모델 사본(정렬 전).
ZonePreview
구역 초벌 점군(BA 없음).
model = 초벌 모델(구역 0 은 GPS 정렬본), dense = 거짓이면 조밀화를 하지 않았거나 실패해 cloud 가 빈 자리표시.
frame = 점군 좌표계(“gps” | “refined_K” | “unaligned”).
RefineStarted
정밀 작업 시작(배경). (session 추가)
ZoneAdjusted
정밀 작업의 BA 직후 모델(GPS 정렬 전). (session 추가)
ZoneRefinedPose
구역 정밀 자세 확정(BA + GPS 정렬).
model = BA + GPS 정렬된 정밀 모델.
Fields
model: Arc<Reconstruction>관련 모델 사본.
ZoneRefined
구역 정밀 점군. 같은 구역 초벌을 대체한다.
dense = 거짓이면 cloud 는 빈 자리표시.
BaseAdopted
정밀 모델이 다음 등록의 기준으로 채택됨.
Reanchored
이미 보낸 구역의 좌표계 변환(점군은 다시 보내지 않음): new_from_old.
Snapshot
화면용 스냅샷(사건 순서 번호와 합성 점군).
AllPositionsDone
모든 위치 처리 완료.
AllRefinedDone
모든 정밀 작업 완료.
chain = 최종 체인 모델.
Finished
세션 종료 요약(모든 이벤트의 마지막). stage_times = (단계, 누적 시간, 횟수) 단계 이름순,
pipeline_secs = 시작 ~ 모든 정밀 완료, chain_stats = 최종 체인 모델 통계 줄. (session 추가)
Fields
Reset
Command::ResetFrom 처리됨. (session 추가)
ZoneInvalidated
Command::InvalidateZone 처리됨. (session 추가)
Warning
경고.
Error
오류(훅 패닉 포함).
Implementations§
Source§impl Event
impl Event
Sourcepub fn meta(&self) -> &Meta
pub fn meta(&self) -> &Meta
공통 머리말.
Examples found in repository?
21fn main() -> Result<(), String> {
22 let out = std::env::args().nth(1).map(PathBuf::from).unwrap_or_else(|| std::env::temp_dir().join("cumulus3d_hooks"));
23 let src = out.with_extension("src");
24 if !src.join("gps_ref.txt").exists() {
25 common::make_dataset(&src);
26 }
27 if out.exists() {
28 std::fs::remove_dir_all(&out).map_err(|e| e.to_string())?;
29 }
30 let layout = Layout::discover(&src, 1)?;
31 let npos = layout.frames.len();
32
33 let mut cfg = SessionConfig::new(src.join("images"));
34 cfg.gps = read_gps_file(src.join("gps_ref.txt")).map_err(|e| e.to_string())?;
35 (cfg.span, cfg.overlap, cfg.total_positions, cfg.seed) = (4, 1, Some(npos), Some(7));
36 if cumulus3d_cuda::is_available() {
37 let mut d = DenseConfig::new(make_pm_backend("cuda"), parse_profile("fast")?);
38 d.undistort.max_image_size = 160;
39 cfg.dense = Some(d);
40 }
41
42 // 훅: 사건 문구 출력, 구역 점군 점 수, 경고·오류. 그리고 기본 출력 훅(파일).
43 let pipeline = Pipeline::new(Session::new(cfg))
44 .on_any(|e: &Event| {
45 if let Some(t) = e.timeline_text() {
46 println!("[event v{}] {t}", e.meta().version);
47 }
48 })
49 .on(EventKind::ZonePreview, |e: &Event| {
50 if let Event::ZonePreview { range, cloud, model, .. } = e {
51 println!(" 초벌 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
52 }
53 })
54 .on(EventKind::ZoneRefined, |e: &Event| {
55 if let Event::ZoneRefined { range, cloud, model, .. } = e {
56 println!(" 정밀 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
57 }
58 })
59 .on_message(|k, m| eprintln!(" {k:?}: {m}"));
60 let mut pipeline = sinks::attach(pipeline, &out, &SinkOptions::default()).map_err(|e| e.to_string())?;
61
62 for p in 0..npos {
63 pipeline.push(Input::Frames(FrameSet::new(CAMS.iter().map(|c| (*c, layout.name(c, p))))));
64 }
65 let (_, summary) = pipeline.finish();
66 println!("이벤트 {} 개, 훅 호출 {} 번, 훅 패닉 {}", summary.events, summary.hook_calls, summary.hook_panics);
67
68 for f in ["timeline.txt", "run.log", "snapshots/manifest.json", "snapshots/timeline.txt", "DONE"] {
69 let p = out.join(f);
70 println!("{} {}", if p.exists() { "있음" } else { "없음" }, p.display());
71 }
72 Ok(())
73}Source§impl Event
impl Event
Sourcepub fn timeline_text(&self) -> Option<String>
pub fn timeline_text(&self) -> Option<String>
timeline.txt 의 사건 문구(없으면 None). 문구·형식은 기존 기록과 같다.
Examples found in repository?
21fn main() -> Result<(), String> {
22 let out = std::env::args().nth(1).map(PathBuf::from).unwrap_or_else(|| std::env::temp_dir().join("cumulus3d_hooks"));
23 let src = out.with_extension("src");
24 if !src.join("gps_ref.txt").exists() {
25 common::make_dataset(&src);
26 }
27 if out.exists() {
28 std::fs::remove_dir_all(&out).map_err(|e| e.to_string())?;
29 }
30 let layout = Layout::discover(&src, 1)?;
31 let npos = layout.frames.len();
32
33 let mut cfg = SessionConfig::new(src.join("images"));
34 cfg.gps = read_gps_file(src.join("gps_ref.txt")).map_err(|e| e.to_string())?;
35 (cfg.span, cfg.overlap, cfg.total_positions, cfg.seed) = (4, 1, Some(npos), Some(7));
36 if cumulus3d_cuda::is_available() {
37 let mut d = DenseConfig::new(make_pm_backend("cuda"), parse_profile("fast")?);
38 d.undistort.max_image_size = 160;
39 cfg.dense = Some(d);
40 }
41
42 // 훅: 사건 문구 출력, 구역 점군 점 수, 경고·오류. 그리고 기본 출력 훅(파일).
43 let pipeline = Pipeline::new(Session::new(cfg))
44 .on_any(|e: &Event| {
45 if let Some(t) = e.timeline_text() {
46 println!("[event v{}] {t}", e.meta().version);
47 }
48 })
49 .on(EventKind::ZonePreview, |e: &Event| {
50 if let Event::ZonePreview { range, cloud, model, .. } = e {
51 println!(" 초벌 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
52 }
53 })
54 .on(EventKind::ZoneRefined, |e: &Event| {
55 if let Event::ZoneRefined { range, cloud, model, .. } = e {
56 println!(" 정밀 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
57 }
58 })
59 .on_message(|k, m| eprintln!(" {k:?}: {m}"));
60 let mut pipeline = sinks::attach(pipeline, &out, &SinkOptions::default()).map_err(|e| e.to_string())?;
61
62 for p in 0..npos {
63 pipeline.push(Input::Frames(FrameSet::new(CAMS.iter().map(|c| (*c, layout.name(c, p))))));
64 }
65 let (_, summary) = pipeline.finish();
66 println!("이벤트 {} 개, 훅 호출 {} 번, 훅 패닉 {}", summary.events, summary.hook_calls, summary.hook_panics);
67
68 for f in ["timeline.txt", "run.log", "snapshots/manifest.json", "snapshots/timeline.txt", "DONE"] {
69 let p = out.join(f);
70 println!("{} {}", if p.exists() { "있음" } else { "없음" }, p.display());
71 }
72 Ok(())
73}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.