Skip to content

Commit

Permalink
Support loading .bpl blueprint files (#5513)
Browse files Browse the repository at this point in the history
### What
* Part of #5294

This implements loading of blueprint files (.rbl) on native and on web,
using either drag-and-drop of the `Open…` command.

One shortcoming of the approach in this PR is documented here:
* #5514

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using newly built examples:
[app.rerun.io](https://app.rerun.io/pr/5513/index.html)
* Using examples from latest `main` build:
[app.rerun.io](https://app.rerun.io/pr/5513/index.html?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[app.rerun.io](https://app.rerun.io/pr/5513/index.html?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/5513)
- [Docs
preview](https://rerun.io/preview/9b3e7d9aed9113d340516caed9d87897c8ae8abb/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/9b3e7d9aed9113d340516caed9d87897c8ae8abb/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)
  • Loading branch information
emilk authored Mar 15, 2024
1 parent 33c53da commit a79520e
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 81 deletions.
6 changes: 4 additions & 2 deletions crates/re_data_source/src/data_loader/loader_rrd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ impl crate::DataLoader for RrdLoader {
re_tracing::profile_function!(filepath.display().to_string());

let extension = crate::extension(&filepath);
if extension != "rrd" {
if !matches!(extension.as_str(), "rbl" | "rrd") {
// NOTE: blueprints and recordings has the same file format
return Err(crate::DataLoaderError::Incompatible(filepath.clone()));
}

Expand Down Expand Up @@ -66,7 +67,8 @@ impl crate::DataLoader for RrdLoader {
re_tracing::profile_function!(filepath.display().to_string());

let extension = crate::extension(&filepath);
if extension != "rrd" {
if !matches!(extension.as_str(), "rbl" | "rrd") {
// NOTE: blueprints and recordings has the same file format
return Err(crate::DataLoaderError::Incompatible(filepath));
}

Expand Down
18 changes: 18 additions & 0 deletions crates/re_data_source/src/data_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ impl DataSource {
}
}

pub fn file_name(&self) -> Option<String> {
match self {
DataSource::RrdHttpUrl(url) => url.split('/').last().map(|r| r.to_owned()),
#[cfg(not(target_arch = "wasm32"))]
DataSource::FilePath(_, path) => {
path.file_name().map(|s| s.to_string_lossy().to_string())
}
DataSource::FileContents(_, file_contents) => Some(file_contents.name.clone()),
DataSource::WebSocketAddr(_) => None,
#[cfg(not(target_arch = "wasm32"))]
DataSource::Stdin => None,
}
}

pub fn is_blueprint(&self) -> Option<bool> {
self.file_name().map(|name| name.ends_with(".rbl"))
}

/// Stream the data from the given data source.
///
/// Will do minimal checks (e.g. that the file exists), for synchronous errors,
Expand Down
13 changes: 11 additions & 2 deletions crates/re_data_source/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,21 @@ pub use self::load_file::load_from_path;
/// This is what you get when loading a file on Web, or when using drag-n-drop.
//
// TODO(#4554): drag-n-drop streaming support
#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct FileContents {
pub name: String,
pub bytes: std::sync::Arc<[u8]>,
}

impl std::fmt::Debug for FileContents {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FileContents")
.field("name", &self.name)
.field("bytes", &format_args!("{} bytes", self.bytes.len()))
.finish()
}
}

// …given that all feature flags are turned on for the `image` crate.
pub const SUPPORTED_IMAGE_EXTENSIONS: &[&str] = &[
"avif", "bmp", "dds", "exr", "farbfeld", "ff", "gif", "hdr", "ico", "jpeg", "jpg", "pam",
Expand All @@ -55,7 +64,7 @@ pub const SUPPORTED_MESH_EXTENSIONS: &[&str] = &["glb", "gltf", "obj", "stl"];
// TODO(#4532): `.ply` data loader should support 2D point cloud & meshes
pub const SUPPORTED_POINT_CLOUD_EXTENSIONS: &[&str] = &["ply"];

pub const SUPPORTED_RERUN_EXTENSIONS: &[&str] = &["rrd"];
pub const SUPPORTED_RERUN_EXTENSIONS: &[&str] = &["rbl", "rrd"];

// TODO(#4555): Add catch-all builtin `DataLoader` for text files
pub const SUPPORTED_TEXT_EXTENSIONS: &[&str] = &["txt", "md"];
Expand Down
4 changes: 2 additions & 2 deletions crates/re_data_source/src/load_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn load_from_path(

re_log::info!("Loading {path:?}…");

let data = load(settings, path, None)?;
let rx = load(settings, path, None)?;

// TODO(cmc): should we always unconditionally set store info though?
// If we reach this point, then at least one compatible `DataLoader` has been found.
Expand All @@ -45,7 +45,7 @@ pub fn load_from_path(
}
}

send(&settings.store_id, data, tx);
send(&settings.store_id, rx, tx);

Ok(())
}
Expand Down
9 changes: 2 additions & 7 deletions crates/re_entity_db/src/entity_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ fn insert_row_with_retries(
///
/// NOTE: all mutation is to be done via public functions!
pub struct EntityDb {
/// The [`StoreId`] for this log.
store_id: StoreId,

/// Set by whomever created this [`EntityDb`].
pub data_source: Option<re_smart_channel::SmartChannelSource>,

Expand Down Expand Up @@ -126,7 +123,6 @@ impl EntityDb {
);
let query_caches = re_query_cache::Caches::new(&data_store);
Self {
store_id: store_id.clone(),
data_source: None,
set_store_info: None,
last_modified_at: web_time::Instant::now(),
Expand Down Expand Up @@ -193,11 +189,11 @@ impl EntityDb {
}

pub fn store_kind(&self) -> StoreKind {
self.store_id.kind
self.store_id().kind
}

pub fn store_id(&self) -> &StoreId {
&self.store_id
self.data_store.id()
}

pub fn timelines(&self) -> impl ExactSizeIterator<Item = &Timeline> {
Expand Down Expand Up @@ -486,7 +482,6 @@ impl EntityDb {
re_tracing::profile_function!();

let Self {
store_id: _,
data_source: _,
set_store_info: _,
last_modified_at: _,
Expand Down
11 changes: 11 additions & 0 deletions crates/re_log_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,17 @@ impl LogMsg {
Self::ArrowMsg(store_id, _) => store_id,
}
}

pub fn set_store_id(&mut self, new_store_id: StoreId) {
match self {
LogMsg::SetStoreInfo(store_info) => {
store_info.info.store_id = new_store_id;
}
LogMsg::ArrowMsg(msg_store_id, _) => {
*msg_store_id = new_store_id;
}
}
}
}

impl_into_enum!(SetStoreInfo, LogMsg, SetStoreInfo);
Expand Down
Loading

0 comments on commit a79520e

Please sign in to comment.