Skip to main content

Crate cumulus3d_cli

Crate cumulus3d_cli 

Source
Expand description

Library part of the cumulus3d executable: the incremental stream pipeline and the stage-by-stage compatible subcommands (interop).

§Usage example

Feed an image folder (images/camF|camR|camL/*.jpg, gps_ref.txt) position by position for incremental reconstruction, and use the default output hook to produce the same files as cumulus3d stream.

use cumulus3d_cli::events::{Event, EventKind};
use cumulus3d_cli::pipeline::Pipeline;
use cumulus3d_cli::session::{Input, Session, SessionConfig};
use cumulus3d_cli::sinks::{self, SinkOptions};
use cumulus3d_cli::stream::{frame_set, Layout};
use cumulus3d_core::io::read_gps_file;
use std::path::Path;

fn main() -> Result<(), String> {
    let src = Path::new("data");
    let layout = Layout::discover(src, 3)?;
    let mut cfg = SessionConfig::new(src.join("images"));
    cfg.gps = read_gps_file(src.join("gps_ref.txt")).map_err(|e| e.to_string())?;
    cfg.total_positions = Some(layout.frames.len());

    let pipeline = Pipeline::new(Session::new(cfg)).on(EventKind::ZonePreview, |e: &Event| {
        if let Event::ZonePreview { range, cloud, .. } = e {
            println!("preview zone {}: {} points", range.zone, cloud.len());
        }
    });
    let mut pipeline = sinks::attach(pipeline, Path::new("out"), &SinkOptions::default()).map_err(|e| e.to_string())?;
    for p in 0..layout.frames.len() {
        pipeline.push(Input::Frames(frame_set(&layout, p)));
    }
    let (_session, summary) = pipeline.finish();
    println!("{} events", summary.events);
    Ok(())
}

Declarative (record a plan -> validate -> run):

use cumulus3d_cli::declare::{Dense, Recon, Sinks};

let recon = Recon::declare()
    .input("data")
    .preset("aerial-formation")
    .zones(12, 2)
    .dense(Dense::profile("fast").fusion_min_views(3))
    .sinks(Sinks::default_files("out"))
    .seed(7)
    .build()
    .unwrap_or_else(|e| panic!("{e}"));
let summary = recon.run().unwrap();
println!("{} events", summary.events);

Functional use that only passes state values around, without hooks:

use cumulus3d_cli::session::{finish, step, FrameSet, Session, SessionConfig};

let s0 = Session::new(SessionConfig::new("data/images"));
let frames = FrameSet::new([("camF", "camF/camF_0000.jpg"), ("camR", "camR/camR_0000.jpg")]);
let (s1, events) = step(&s0, frames);
for e in &events {
    if let Some(t) = e.timeline_text() {
        println!("{t}");
    }
}
let (_done, _summary_events) = finish(&s1);

Modules§

blocks
Live stream (<out>/live/stream/, format version 4): after every live event the composed display cloud (point keys and the owner zone of every point) is diffed against what the viewer shows and only the changes are written. Every shown point owns a dense u32 slot id assigned here, so the viewer writes straight into its GPU buffers at index = id.
compose
Declarative incremental composition for live frame sources.
declare
Declarative builder layer: record a plan first and run it all at once later.
densewrap
Shared densification path: exclude images outside the zone -> undistortion -> scene conversion -> densify. Used by both the stream and the densify subcommand.
events
Pipeline events. Each time a new frame bundle is processed, the result decomposed by stage is emitted. This file is the shared contract of three modules (session, pipeline, sinks). Adding fields is allowed; changing or removing existing fields is forbidden.
fusion_variants
densify --fusion-variants <file>: build the depth maps once and fuse several times, changing only the fusion settings.
interop
Stage-by-stage subcommands compatible with an external SfM tool (COLMAP) (thin wrappers). Subcommand names and option strings follow that tool’s command line. State between stages is carried by --database_path (a FeatureStore binary file) and model folders (cumulus3d_core::interop format). GPU-related options (--FeatureExtraction.use_gpu etc.) are accepted and ignored.
intrinsics
Soft intrinsics prior (cumulus3d stream --intrinsics-prior): known camera parameters (from an earlier calibration or run) that start every camera at the right values and pull the bundle adjustment back when the data alone are weak.
pipeline
Closure hook pipeline (Pipeline): hook registration, queues, policies, panic isolation, channels.
post
Post-processing: performs the Python part at the end of the script (preview alignment, per-event snapshots, manifest) and incremental_reanchor.py with the align crate. The model uses the in-memory Reconstruction as is.
session
State value and reducer: Session + step / poll / command / finish.
sinks
Default output hooks: receive events and produce the file output of cumulus3d stream.
stream
cumulus3d stream: feed the positions of the input folder one by one into the Session reducer (Pipeline), and the default output hooks (crate::sinks) produce timeline.txt, run.log, point clouds and snapshot files. The computation (features -> pair matching -> first model / continued registration -> per-zone preview and refinement) lives in crate::session. run_stream converts the settings into a plan (crate::declare::Plan) and runs it through the declarative layer (crate::declare).
util
Logging, time measurement and small serialization helpers.