Skip to content

Commit a9a466f

Browse files
jleibsWumpf
andcommitted
Refactor the 2D heuristic again (#5166)
### What - Builds on top of #5164 Adds a store subscriber for tracking the dimensions of image entities. Gets rid of the previous bucketing logic and replaces it with a new implementation that starts at the top of the subspace and incrementally splits when it finds conflicting image entities within the space. ### 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/5166/index.html) * Using examples from latest `main` build: [app.rerun.io](https://app.rerun.io/pr/5166/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/5166/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/5166) - [Docs preview](https://rerun.io/preview/da9a0d206235016d14d9826e8c42ed8481d29643/docs) <!--DOCS-PREVIEW--> - [Examples preview](https://rerun.io/preview/da9a0d206235016d14d9826e8c42ed8481d29643/examples) <!--EXAMPLES-PREVIEW--> - [Recent benchmark results](https://build.rerun.io/graphs/crates.html) - [Wasm size tracking](https://build.rerun.io/graphs/sizes.html) --------- Co-authored-by: Andreas Reich <[email protected]>
1 parent 40b43ad commit a9a466f

File tree

3 files changed

+247
-184
lines changed

3 files changed

+247
-184
lines changed

crates/re_space_view_spatial/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod contexts;
66
mod eye;
77
mod heuristics;
88
mod instance_hash_conversions;
9+
mod max_image_dimension_subscriber;
910
mod mesh_cache;
1011
mod mesh_loader;
1112
mod picking;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use ahash::HashMap;
2+
use nohash_hasher::IntMap;
3+
use once_cell::sync::OnceCell;
4+
use re_data_store::{StoreSubscriber, StoreSubscriberHandle};
5+
use re_log_types::{EntityPath, StoreId};
6+
use re_types::{components::TensorData, Loggable};
7+
8+
#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
9+
pub struct ImageDimensions {
10+
pub height: u64,
11+
pub width: u64,
12+
pub channels: u64,
13+
}
14+
15+
#[derive(Default, Debug, Clone)]
16+
pub struct MaxImageDimensions(IntMap<EntityPath, ImageDimensions>);
17+
18+
impl MaxImageDimensions {
19+
/// Accesses the image dimension information for a given store
20+
pub fn access<T>(
21+
store_id: &StoreId,
22+
f: impl FnOnce(&IntMap<EntityPath, ImageDimensions>) -> T,
23+
) -> Option<T> {
24+
re_data_store::DataStore::with_subscriber_once(
25+
MaxImageDimensionSubscriber::subscription_handle(),
26+
move |subscriber: &MaxImageDimensionSubscriber| {
27+
subscriber.max_dimensions.get(store_id).map(|v| &v.0).map(f)
28+
},
29+
)
30+
.flatten()
31+
}
32+
}
33+
34+
#[derive(Default)]
35+
struct MaxImageDimensionSubscriber {
36+
max_dimensions: HashMap<StoreId, MaxImageDimensions>,
37+
}
38+
39+
impl MaxImageDimensionSubscriber {
40+
/// Accesses the global store subscriber.
41+
///
42+
/// Lazily registers the subscriber if it hasn't been registered yet.
43+
pub fn subscription_handle() -> StoreSubscriberHandle {
44+
static SUBSCRIPTION: OnceCell<re_data_store::StoreSubscriberHandle> = OnceCell::new();
45+
*SUBSCRIPTION.get_or_init(|| {
46+
re_data_store::DataStore::register_subscriber(
47+
Box::<MaxImageDimensionSubscriber>::default(),
48+
)
49+
})
50+
}
51+
}
52+
53+
impl StoreSubscriber for MaxImageDimensionSubscriber {
54+
fn name(&self) -> String {
55+
"MaxImageDimensionStoreSubscriber".to_owned()
56+
}
57+
58+
fn as_any(&self) -> &dyn std::any::Any {
59+
self
60+
}
61+
62+
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
63+
self
64+
}
65+
66+
fn on_events(&mut self, events: &[re_data_store::StoreEvent]) {
67+
re_tracing::profile_function!();
68+
69+
for event in events {
70+
if event.diff.kind != re_data_store::StoreDiffKind::Addition {
71+
// Max image dimensions are strictly additive
72+
continue;
73+
}
74+
75+
if let Some(cell) = event.diff.cells.get(&TensorData::name()) {
76+
if let Ok(Some(tensor_data)) = cell.try_to_native_mono::<TensorData>() {
77+
if let Some([height, width, channels]) =
78+
tensor_data.image_height_width_channels()
79+
{
80+
let dimensions = self
81+
.max_dimensions
82+
.entry(event.store_id.clone())
83+
.or_default()
84+
.0
85+
.entry(event.diff.entity_path.clone())
86+
.or_default();
87+
88+
dimensions.height = dimensions.height.max(height);
89+
dimensions.width = dimensions.width.max(width);
90+
dimensions.channels = dimensions.channels.max(channels);
91+
}
92+
}
93+
}
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)