Skip to content

Commit

Permalink
DataLoaders 3: add 3D point cloud DataLoader (.ply) (#4519)
Browse files Browse the repository at this point in the history
`.ply` support, but point clouds only, at least for now.

No feature flag: I had some, and tbh it only made thing needlessly hard
to work with for very little gains.
`.ply` are so common anyway, they always come up in user requests.

Here's an example from
[there](https://github.com/HuangCongQing/Point-Clouds-Visualization/blob/master/2open3D/data/fragment.ply):

![image](https://github.com/rerun-io/rerun/assets/2910679/8242c5a2-037d-46c6-9816-ab9b240a7473)


Checks:
- [x] `cargo r -p rerun-cli --no-default-features --features
native_viewer --
examples/assets/example.{glb,gltf,obj,jpg,png,rrd,txt,md,ply}`
- [x] Native: `File > Open > examples/assets/*`
- [x] Native: `Drag-n-drop > examples/assets/*`
- [x] Web: `File > Open > examples/assets/*`
- [x] Web: `Drag-n-drop > examples/assets/*`

---

Part of a series of PRs to make it possible to load _any_ file from the
local filesystem, by any means, on web and native:
- #4516
- #4517 
- #4518 
- #4519 
- #4520 
- #4521 
- TODO: register custom loaders
- TODO: high level docs and guides for everything related to loading
files
  • Loading branch information
teh-cmc authored Dec 15, 2023
1 parent 8f4f4e9 commit 82f17dc
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 21 deletions.
88 changes: 86 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ itertools = "0.11" # updating it
js-sys = "0.3"
# No lazy_static - use `std::sync::OnceLock` or `once_cell` instead
libc = "0.2"
linked-hash-map = { version = "0.5", default-features = false }
log = "0.4"
log-once = "0.4"
lz4_flex = "0.11"
Expand All @@ -167,6 +168,7 @@ ordered-float = "4.2"
parking_lot = "0.12"
pathdiff = "0.2"
pico-args = "0.5"
ply-rs = { version = "0.1", default-features = false }
polars-core = "0.29"
polars-lazy = "0.29"
polars-ops = "0.29"
Expand Down
54 changes: 38 additions & 16 deletions crates/re_data_source/src/data_loader/loader_archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,25 @@ impl DataLoader for ArchetypeLoader {

let mut rows = Vec::new();

if crate::SUPPORTED_MESH_EXTENSIONS.contains(&extension.as_str()) {
re_log::debug!(?filepath, loader = self.name(), "Loading 3D model…",);
rows.extend(load_mesh(
filepath,
if crate::SUPPORTED_IMAGE_EXTENSIONS.contains(&extension.as_str()) {
re_log::debug!(?filepath, loader = self.name(), "Loading image…",);
rows.extend(load_image(
&filepath,
timepoint,
entity_path,
contents.into_owned(),
)?);
} else if crate::SUPPORTED_IMAGE_EXTENSIONS.contains(&extension.as_str()) {
re_log::debug!(?filepath, loader = self.name(), "Loading image…",);
rows.extend(load_image(
&filepath,
} else if crate::SUPPORTED_MESH_EXTENSIONS.contains(&extension.as_str()) {
re_log::debug!(?filepath, loader = self.name(), "Loading 3D model…",);
rows.extend(load_mesh(
filepath,
timepoint,
entity_path,
contents.into_owned(),
)?);
} else if crate::SUPPORTED_POINT_CLOUD_EXTENSIONS.contains(&extension.as_str()) {
re_log::debug!(?filepath, loader = self.name(), "Loading 3D point cloud…",);
rows.extend(load_point_cloud(timepoint, entity_path, &contents)?);
} else if crate::SUPPORTED_TEXT_EXTENSIONS.contains(&extension.as_str()) {
re_log::debug!(?filepath, loader = self.name(), "Loading text document…",);
rows.extend(load_text_document(
Expand All @@ -118,6 +121,28 @@ impl DataLoader for ArchetypeLoader {

// ---

fn load_image(
filepath: &std::path::Path,
timepoint: TimePoint,
entity_path: EntityPath,
contents: Vec<u8>,
) -> Result<impl ExactSizeIterator<Item = DataRow>, DataLoaderError> {
re_tracing::profile_function!();

let rows = [
{
let arch = re_types::archetypes::Image::from_file_contents(
contents,
image::ImageFormat::from_path(filepath).ok(),
)?;
DataRow::from_archetype(RowId::new(), timepoint, entity_path, &arch)?
},
//
];

Ok(rows.into_iter())
}

fn load_mesh(
filepath: std::path::PathBuf,
timepoint: TimePoint,
Expand All @@ -140,21 +165,18 @@ fn load_mesh(
Ok(rows.into_iter())
}

fn load_image(
filepath: &std::path::Path,
fn load_point_cloud(
timepoint: TimePoint,
entity_path: EntityPath,
contents: Vec<u8>,
contents: &[u8],
) -> Result<impl ExactSizeIterator<Item = DataRow>, DataLoaderError> {
re_tracing::profile_function!();

let rows = [
{
let arch = re_types::archetypes::Image::from_file_contents(
contents,
image::ImageFormat::from_path(filepath).ok(),
)?;
DataRow::from_archetype(RowId::new(), timepoint, entity_path, &arch)?
// TODO(#4532): `.ply` data loader should support 2D point cloud & meshes
let points3d = re_types::archetypes::Points3D::from_file_contents(contents)?;
DataRow::from_archetype(RowId::new(), timepoint, entity_path, &points3d)?
},
//
];
Expand Down
4 changes: 4 additions & 0 deletions crates/re_data_source/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ pub const SUPPORTED_IMAGE_EXTENSIONS: &[&str] = &[

pub const SUPPORTED_MESH_EXTENSIONS: &[&str] = &["glb", "gltf", "obj"];

// 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"];

// TODO(#4555): Add catch-all builtin `DataLoader` for text files
Expand All @@ -64,6 +67,7 @@ pub fn supported_extensions() -> impl Iterator<Item = &'static str> {
pub fn is_supported_file_extension(extension: &str) -> bool {
SUPPORTED_IMAGE_EXTENSIONS.contains(&extension)
|| SUPPORTED_MESH_EXTENSIONS.contains(&extension)
|| SUPPORTED_POINT_CLOUD_EXTENSIONS.contains(&extension)
|| SUPPORTED_RERUN_EXTENSIONS.contains(&extension)
|| SUPPORTED_TEXT_EXTENSIONS.contains(&extension)
}
6 changes: 3 additions & 3 deletions crates/re_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ arrow2 = { workspace = true, features = [
] }
bytemuck = { workspace = true, features = ["derive", "extern_crate_alloc"] }
document-features.workspace = true
half = { workspace = true, features = ["bytemuck"] }
infer.workspace = true
itertools.workspace = true
half = { workspace = true, features = ["bytemuck"] }
linked-hash-map.workspace = true
mime_guess2.workspace = true
ndarray.workspace = true
once_cell.workspace = true
ply-rs.workspace = true
smallvec.workspace = true
thiserror.workspace = true
uuid = { workspace = true, features = ["serde", "v4", "js"] }
Expand Down Expand Up @@ -100,8 +102,6 @@ re_types_builder.workspace = true
rayon.workspace = true

# `machete` is not a fan of `build-dependencies`.


[package.metadata.cargo-machete]
ignored = ["rayon", "re_build_tools", "re_types_builder"]

Expand Down
1 change: 1 addition & 0 deletions crates/re_types/src/archetypes/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 82f17dc

Please sign in to comment.