Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A nice speed up of 3D points clouds by ~69% #3114

Merged
merged 14 commits into from
Aug 28, 2023
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
# `cargo rerun` is short a convenient shorthand, skipping the web viewer.
rerun = "run --package rerun-cli --no-default-features --features native_viewer --"

# like `rerun`, but with --release
rerun-release = "run --package rerun-cli --no-default-features --features native_viewer --release --"

# `cargo rerun-web` is short a convenient shorthand for building & starting the web viewer.
rerun-web = "run --package rerun-cli --no-default-features --features web_viewer -- --web-viewer"

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/re_space_view_spatial/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ itertools.workspace = true
macaw = { workspace = true, features = ["with_serde"] }
nohash-hasher.workspace = true
parking_lot.workspace = true
rayon.workspace = true
serde = "1"
smallvec = { workspace = true, features = ["serde"] }
vec1.workspace = true
Expand Down
74 changes: 47 additions & 27 deletions crates/re_space_view_spatial/src/parts/points3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use re_viewer_context::{
ViewContextCollection, ViewPartSystem, ViewQuery, ViewerContext,
};

use itertools::Itertools as _;

use crate::{
contexts::{EntityDepthOffsets, SpatialSceneEntityContext},
parts::{
Expand Down Expand Up @@ -122,36 +124,34 @@ impl Points3DPart {
.outline_mask_ids(ent_context.highlight.overall)
.picking_object_id(re_renderer::PickingLayerObjectId(ent_path.hash64()));

let point_positions = arch_view
.iter_required_component::<Point3D>()?
.map(glam::Vec3::from);

let picking_instance_ids = arch_view
.iter_instance_keys()
.map(picking_id_from_instance_key);

let point_positions: Vec<glam::Vec3> = {
re_tracing::profile_scope!("collect_positions");
point_positions.collect()
};

let radii: Vec<_> = {
re_tracing::profile_scope!("collect_radii");
radii.collect()
};

let colors: Vec<_> = {
re_tracing::profile_scope!("collect_colors");
colors.collect()
};
let (positions, radii, colors, picking_instance_ids) = join4(
|| {
re_tracing::profile_scope!("positions");
arch_view
.iter_required_component::<Point3D>()
.map(|p| p.map(glam::Vec3::from).collect_vec())
},
|| {
re_tracing::profile_scope!("radii");
radii.collect_vec()
},
|| {
re_tracing::profile_scope!("colors");
colors.collect_vec()
},
|| {
re_tracing::profile_scope!("picking_ids");
arch_view
.iter_instance_keys()
.map(picking_id_from_instance_key)
.collect_vec()
},
);

let picking_instance_ids: Vec<_> = {
re_tracing::profile_scope!("collect_picking_instance_ids");
picking_instance_ids.collect()
};
let positions = positions?;

let mut point_range_builder =
point_batch.add_points(&point_positions, &radii, &colors, &picking_instance_ids);
point_batch.add_points(&positions, &radii, &colors, &picking_instance_ids);

// Determine if there's any sub-ranges that need extra highlighting.
{
Expand Down Expand Up @@ -219,3 +219,23 @@ impl ViewPartSystem for Points3DPart {
self
}
}

/// Run 4 things in parallel
fn join4<A: Send, B: Send, C: Send, D: Send>(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder where we should put helpers like these. Yet another helper crate (re_parallel)?

a: impl FnOnce() -> A + Send,
b: impl FnOnce() -> B + Send,
c: impl FnOnce() -> C + Send,
d: impl FnOnce() -> D + Send,
) -> (A, B, C, D) {
#[cfg(not(target_arch = "wasm32"))]
{
re_tracing::profile_function!();
let ((a, b), (c, d)) = rayon::join(|| rayon::join(a, b), || rayon::join(c, d));
(a, b, c, d)
}

#[cfg(target_arch = "wasm32")]
{
(a(), b(), c(), d())
}
}