From b20713499348bbc9287779d2cc7990f849daa4bd Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 21 Dec 2023 11:46:44 +0100 Subject: [PATCH 1/4] visualizer_entity_subscriber keeps now track of matching indicator components --- .../space_view/space_view_class_registry.rs | 2 +- .../src/space_view/view_part_system.rs | 2 +- .../visualizer_entity_subscriber.rs | 48 +++++++++++++++++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/crates/re_viewer_context/src/space_view/space_view_class_registry.rs b/crates/re_viewer_context/src/space_view/space_view_class_registry.rs index 96f4a41f099c..51f9832476e9 100644 --- a/crates/re_viewer_context/src/space_view/space_view_class_registry.rs +++ b/crates/re_viewer_context/src/space_view/space_view_class_registry.rs @@ -289,7 +289,7 @@ impl SpaceViewClassRegistry { self.visualizers.get(&visualizer).and_then(|entry| { DataStore::with_subscriber::( entry.entity_subscriber_handle, - |subscriber| subscriber.entities(store).cloned(), + |subscriber| subscriber.applicable_entities(store).cloned(), ) .flatten() }) diff --git a/crates/re_viewer_context/src/space_view/view_part_system.rs b/crates/re_viewer_context/src/space_view/view_part_system.rs index 296910365fe0..f30153c36079 100644 --- a/crates/re_viewer_context/src/space_view/view_part_system.rs +++ b/crates/re_viewer_context/src/space_view/view_part_system.rs @@ -65,7 +65,7 @@ pub trait ViewPartSystem: Send + Sync + 'static { /// The passed-in set of `entity_components` corresponds to all the different components that have ever /// been logged on the entity path. /// - /// By default, this returns true if eiher [`Self::indicator_components`] is empty or + /// By default, this returns true if either [`Self::indicator_components`] is empty or /// `entity_components` contains at least one of these indicator components. /// /// Override this method only if a more detailed condition is required to inform heuristics whether or not diff --git a/crates/re_viewer_context/src/space_view/visualizer_entity_subscriber.rs b/crates/re_viewer_context/src/space_view/visualizer_entity_subscriber.rs index 677bd0710ba2..48aec883f543 100644 --- a/crates/re_viewer_context/src/space_view/visualizer_entity_subscriber.rs +++ b/crates/re_viewer_context/src/space_view/visualizer_entity_subscriber.rs @@ -1,10 +1,11 @@ use ahash::HashMap; use bit_vec::BitVec; +use itertools::Itertools; use nohash_hasher::{IntMap, IntSet}; use re_arrow_store::StoreSubscriber; use re_log_types::{EntityPath, EntityPathHash, StoreId}; -use re_types::ComponentName; +use re_types::{ComponentName, ComponentNameSet}; use crate::{IdentifiedViewSystem, ViewPartSystem, ViewSystemIdentifier}; @@ -24,6 +25,9 @@ pub struct VisualizerEntitySubscriber { /// Visualizer type this subscriber is associated with. visualizer: ViewSystemIdentifier, + /// See [`ViewPartSystem::indicator_components`] + indicator_components: ComponentNameSet, + /// Assigns each required component an index. required_components_indices: IntMap, @@ -74,12 +78,16 @@ struct VisualizerEntityMapping { /// Order is not defined. // TODO(andreas): It would be nice if these were just `EntityPathHash`. applicable_entities: IntSet, + + /// List of all entities in this store that at some point in time had any of the indicator components. + entities_with_matching_indicator: IntSet, } impl VisualizerEntitySubscriber { pub fn new(visualizer: &T) -> Self { Self { visualizer: T::identifier(), + indicator_components: visualizer.indicator_components(), required_components_indices: visualizer .required_components() .into_iter() @@ -95,11 +103,24 @@ impl VisualizerEntitySubscriber { /// List of entities that are applicable to the visualizer. #[inline] - pub fn entities(&self, store: &StoreId) -> Option<&IntSet> { + pub fn applicable_entities(&self, store: &StoreId) -> Option<&IntSet> { self.per_store_mapping .get(store) .map(|mapping| &mapping.applicable_entities) } + + /// List of entities that at some point in time had any of the indicator components advertised by this visualizer. + /// + /// Useful for quickly evaluating basic "should this visualizer apply by default"-heuristic. + /// Does *not* imply that any of the given entities is also in the applicable-set! + pub fn entities_with_matching_indicator( + &self, + store: &StoreId, + ) -> Option<&IntSet> { + self.per_store_mapping + .get(store) + .map(|mapping| &mapping.entities_with_matching_indicator) + } } impl StoreSubscriber for VisualizerEntitySubscriber { @@ -119,6 +140,8 @@ impl StoreSubscriber for VisualizerEntitySubscriber { } fn on_events(&mut self, events: &[re_arrow_store::StoreEvent]) { + re_tracing::profile_function!(self.visualizer); + // TODO(andreas): Need to react to store removals as well. As of writing doesn't exist yet. for event in events { @@ -132,9 +155,24 @@ impl StoreSubscriber for VisualizerEntitySubscriber { .entry(event.store_id.clone()) .or_default(); + let entity_path = &event.diff.entity_path; + let entity_path_hash = entity_path.hash(); + + // Update indicator component tracking: + if self + .indicator_components + .iter() + .any(|component_name| event.diff.cells.keys().contains(component_name)) + { + store_mapping + .entities_with_matching_indicator + .insert(entity_path_hash); + } + + // Update required component tracking: let required_components_bitmap = store_mapping .required_component_and_filter_bitmap_per_entity - .entry(event.diff.entity_path.hash()) + .entry(entity_path_hash) .or_insert_with(|| { BitVec::from_elem(self.required_components_indices.len() + 1, false) }); @@ -162,14 +200,14 @@ impl StoreSubscriber for VisualizerEntitySubscriber { if required_components_bitmap.all() { re_log::debug!( "Entity {:?} in store {:?} is now applicable to visualizer {:?}", - event.diff.entity_path, + entity_path, event.store_id, self.visualizer ); store_mapping .applicable_entities - .insert(event.diff.entity_path.clone()); + .insert(entity_path.clone()); } } } From 9f903bc4dcab2d98e055cb14b34a8c7fa6fb8506 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 21 Dec 2023 11:54:10 +0100 Subject: [PATCH 2/4] make entities_with_matching_indicator_per_visualizer globally available --- crates/re_viewer/src/app_state.rs | 8 +++++ .../space_view/space_view_class_registry.rs | 33 ++++++++++++++++--- .../re_viewer_context/src/viewer_context.rs | 8 ++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/crates/re_viewer/src/app_state.rs b/crates/re_viewer/src/app_state.rs index cdb25b84cea2..ef9b4c576f20 100644 --- a/crates/re_viewer/src/app_state.rs +++ b/crates/re_viewer/src/app_state.rs @@ -138,6 +138,10 @@ impl AppState { &rec_cfg.time_ctrl.get_mut().current_query(), ); + // Gather all entities that have a matching indicator for a visualizer. + let entities_with_matching_indicator_per_visualizer = space_view_class_registry + .entities_with_matching_indicator_per_visualizer(store_db.store_id()); + // Execute the queries for every `SpaceView` let mut query_results = { re_tracing::profile_scope!("query_results"); @@ -168,6 +172,8 @@ impl AppState { store_db, store_context, entities_per_system_per_class: &entities_per_system_per_class, + entities_with_matching_indicator_per_visualizer: + &entities_with_matching_indicator_per_visualizer, query_results: &query_results, rec_cfg, re_ui, @@ -205,6 +211,8 @@ impl AppState { store_db, store_context, entities_per_system_per_class: &entities_per_system_per_class, + entities_with_matching_indicator_per_visualizer: + &entities_with_matching_indicator_per_visualizer, query_results: &query_results, rec_cfg, re_ui, diff --git a/crates/re_viewer_context/src/space_view/space_view_class_registry.rs b/crates/re_viewer_context/src/space_view/space_view_class_registry.rs index 51f9832476e9..e9dc57a35c0b 100644 --- a/crates/re_viewer_context/src/space_view/space_view_class_registry.rs +++ b/crates/re_viewer_context/src/space_view/space_view_class_registry.rs @@ -1,7 +1,7 @@ use ahash::{HashMap, HashSet}; -use nohash_hasher::IntSet; +use nohash_hasher::{IntMap, IntSet}; use re_arrow_store::DataStore; -use re_log_types::EntityPath; +use re_log_types::{EntityPath, EntityPathHash}; use crate::{ DynSpaceViewClass, IdentifiedViewSystem, SpaceViewClassIdentifier, ViewContextCollection, @@ -284,17 +284,42 @@ impl SpaceViewClassRegistry { pub fn applicable_entities_for_visualizer_system( &self, visualizer: ViewSystemIdentifier, - store: &re_log_types::StoreId, + store_id: &re_log_types::StoreId, ) -> Option> { self.visualizers.get(&visualizer).and_then(|entry| { DataStore::with_subscriber::( entry.entity_subscriber_handle, - |subscriber| subscriber.applicable_entities(store).cloned(), + |subscriber| subscriber.applicable_entities(store_id).cloned(), ) .flatten() }) } + /// For each visualizer, the set of entities that have at least one matching indicator component. + pub fn entities_with_matching_indicator_per_visualizer( + &self, + store_id: &re_log_types::StoreId, + ) -> IntMap> { + self.visualizers + .iter() + .map(|(id, entry)| { + ( + *id, + DataStore::with_subscriber::( + entry.entity_subscriber_handle, + |subscriber| { + subscriber + .entities_with_matching_indicator(store_id) + .cloned() + }, + ) + .flatten() + .unwrap_or_default(), + ) + }) + .collect() + } + pub fn new_context_collection( &self, space_view_class_identifier: SpaceViewClassIdentifier, diff --git a/crates/re_viewer_context/src/viewer_context.rs b/crates/re_viewer_context/src/viewer_context.rs index f5ae5a0bffdc..749217837155 100644 --- a/crates/re_viewer_context/src/viewer_context.rs +++ b/crates/re_viewer_context/src/viewer_context.rs @@ -1,12 +1,14 @@ use ahash::HashMap; +use nohash_hasher::{IntMap, IntSet}; use parking_lot::RwLock; use re_data_store::{store_db::StoreDb, EntityTree, TimeHistogramPerTimeline}; +use re_log_types::EntityPathHash; use crate::{ query_context::DataQueryResult, AppOptions, ApplicationSelectionState, Caches, CommandSender, ComponentUiRegistry, DataQueryId, EntitiesPerSystemPerClass, Selection, SpaceViewClassRegistry, - StoreContext, TimeControl, + StoreContext, TimeControl, ViewSystemIdentifier, }; /// Common things needed by many parts of the viewer. @@ -35,6 +37,10 @@ pub struct ViewerContext<'a> { /// Mapping from class and system to entities for the store pub entities_per_system_per_class: &'a EntitiesPerSystemPerClass, + /// For each visualizer, the set of entities that have at least one matching indicator component. + pub entities_with_matching_indicator_per_visualizer: + &'a IntMap>, + /// All the query results for this frame pub query_results: &'a HashMap, From a167e66f4ed814f4f7b7360c4118890cd9134c19 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 21 Dec 2023 16:38:48 +0100 Subject: [PATCH 3/4] use data from store subscriber to drive heuristic_filter --- .../src/parts/boxes2d.rs | 16 ++--- .../re_space_view_spatial/src/parts/images.rs | 11 ++-- .../src/parts/lines2d.rs | 16 ++--- .../src/parts/points2d.rs | 16 ++--- crates/re_viewer/src/app_state.rs | 10 +-- crates/re_viewer_context/src/lib.rs | 10 +-- .../re_viewer_context/src/space_view/mod.rs | 4 +- .../src/space_view/view_part_system.rs | 37 ++--------- .../src/space_view_entity_picker.rs | 2 +- .../re_viewport/src/space_view_heuristics.rs | 66 +++++++------------ 10 files changed, 66 insertions(+), 122 deletions(-) diff --git a/crates/re_space_view_spatial/src/parts/boxes2d.rs b/crates/re_space_view_spatial/src/parts/boxes2d.rs index c539728b1128..731838e1c9f1 100644 --- a/crates/re_space_view_spatial/src/parts/boxes2d.rs +++ b/crates/re_space_view_spatial/src/parts/boxes2d.rs @@ -1,5 +1,6 @@ -use re_arrow_store::LatestAtQuery; +use nohash_hasher::IntSet; use re_data_store::{EntityPath, InstancePathHash}; +use re_log_types::EntityPathHash; use re_query::{ArchetypeView, QueryError}; use re_types::{ archetypes::Boxes2D, @@ -7,9 +8,8 @@ use re_types::{ Archetype, ComponentNameSet, }; use re_viewer_context::{ - default_heuristic_filter, HeuristicFilterContext, IdentifiedViewSystem, - ResolvedAnnotationInfos, SpaceViewSystemExecutionError, ViewContextCollection, ViewPartSystem, - ViewQuery, ViewerContext, + HeuristicFilterContext, IdentifiedViewSystem, ResolvedAnnotationInfos, + SpaceViewSystemExecutionError, ViewContextCollection, ViewPartSystem, ViewQuery, ViewerContext, }; use crate::{ @@ -181,13 +181,11 @@ impl ViewPartSystem for Boxes2DPart { fn heuristic_filter( &self, - _store: &re_arrow_store::DataStore, - _ent_path: &EntityPath, + entities_with_matching_indicator: &IntSet, + ent_path: &EntityPath, ctx: HeuristicFilterContext, - _query: &LatestAtQuery, - entity_components: &ComponentNameSet, ) -> bool { - if !default_heuristic_filter(entity_components, &self.indicator_components()) { + if !entities_with_matching_indicator.contains(&ent_path.hash()) { return false; } diff --git a/crates/re_space_view_spatial/src/parts/images.rs b/crates/re_space_view_spatial/src/parts/images.rs index af200ed56fcd..e324bf70ac54 100644 --- a/crates/re_space_view_spatial/src/parts/images.rs +++ b/crates/re_space_view_spatial/src/parts/images.rs @@ -4,7 +4,6 @@ use egui::NumExt; use itertools::Itertools as _; use nohash_hasher::IntSet; -use re_arrow_store::LatestAtQuery; use re_data_store::{EntityPath, EntityProperties}; use re_log_types::{EntityPathHash, RowId}; use re_query::{ArchetypeView, QueryError}; @@ -20,7 +19,7 @@ use re_types::{ Archetype as _, ComponentNameSet, }; use re_viewer_context::{ - default_heuristic_filter, gpu_bridge, DefaultColor, HeuristicFilterContext, SpaceViewClass, + gpu_bridge, DefaultColor, HeuristicFilterContext, SpaceViewClass, SpaceViewSystemExecutionError, TensorDecodeCache, TensorStatsCache, ViewPartSystem, ViewQuery, ViewerContext, VisualizerAdditionalApplicabilityFilter, }; @@ -694,13 +693,11 @@ impl ViewPartSystem for ImagesPart { fn heuristic_filter( &self, - _store: &re_arrow_store::DataStore, - _ent_path: &EntityPath, + entities_with_matching_indicator: &IntSet, + ent_path: &EntityPath, ctx: HeuristicFilterContext, - _query: &LatestAtQuery, - entity_components: &ComponentNameSet, ) -> bool { - if !default_heuristic_filter(entity_components, &self.indicator_components()) { + if !entities_with_matching_indicator.contains(&ent_path.hash()) { return false; } diff --git a/crates/re_space_view_spatial/src/parts/lines2d.rs b/crates/re_space_view_spatial/src/parts/lines2d.rs index 57e15ddd26aa..3968ea4ff1df 100644 --- a/crates/re_space_view_spatial/src/parts/lines2d.rs +++ b/crates/re_space_view_spatial/src/parts/lines2d.rs @@ -1,5 +1,6 @@ -use re_arrow_store::LatestAtQuery; +use nohash_hasher::IntSet; use re_data_store::{EntityPath, InstancePathHash}; +use re_log_types::EntityPathHash; use re_query::{ArchetypeView, QueryError}; use re_types::{ archetypes::LineStrips2D, @@ -7,9 +8,8 @@ use re_types::{ Archetype as _, ComponentNameSet, }; use re_viewer_context::{ - default_heuristic_filter, HeuristicFilterContext, IdentifiedViewSystem, - ResolvedAnnotationInfos, SpaceViewSystemExecutionError, ViewContextCollection, ViewPartSystem, - ViewQuery, ViewerContext, + HeuristicFilterContext, IdentifiedViewSystem, ResolvedAnnotationInfos, + SpaceViewSystemExecutionError, ViewContextCollection, ViewPartSystem, ViewQuery, ViewerContext, }; use crate::{ @@ -176,13 +176,11 @@ impl ViewPartSystem for Lines2DPart { fn heuristic_filter( &self, - _store: &re_arrow_store::DataStore, - _ent_path: &EntityPath, + entities_with_matching_indicator: &IntSet, + ent_path: &EntityPath, ctx: HeuristicFilterContext, - _query: &LatestAtQuery, - entity_components: &ComponentNameSet, ) -> bool { - if !default_heuristic_filter(entity_components, &self.indicator_components()) { + if !entities_with_matching_indicator.contains(&ent_path.hash()) { return false; } diff --git a/crates/re_space_view_spatial/src/parts/points2d.rs b/crates/re_space_view_spatial/src/parts/points2d.rs index 1edc2fbe4e2d..2dc490fa057d 100644 --- a/crates/re_space_view_spatial/src/parts/points2d.rs +++ b/crates/re_space_view_spatial/src/parts/points2d.rs @@ -1,5 +1,6 @@ -use re_arrow_store::LatestAtQuery; +use nohash_hasher::IntSet; use re_data_store::{EntityPath, InstancePathHash}; +use re_log_types::EntityPathHash; use re_query::{ArchetypeView, QueryError}; use re_types::{ archetypes::Points2D, @@ -7,9 +8,8 @@ use re_types::{ Archetype, ComponentNameSet, }; use re_viewer_context::{ - default_heuristic_filter, HeuristicFilterContext, IdentifiedViewSystem, - ResolvedAnnotationInfos, SpaceViewSystemExecutionError, ViewContextCollection, ViewPartSystem, - ViewQuery, ViewerContext, + HeuristicFilterContext, IdentifiedViewSystem, ResolvedAnnotationInfos, + SpaceViewSystemExecutionError, ViewContextCollection, ViewPartSystem, ViewQuery, ViewerContext, }; use crate::{ @@ -203,13 +203,11 @@ impl ViewPartSystem for Points2DPart { fn heuristic_filter( &self, - _store: &re_arrow_store::DataStore, - _ent_path: &EntityPath, + entities_with_matching_indicator: &IntSet, + ent_path: &EntityPath, ctx: HeuristicFilterContext, - _query: &LatestAtQuery, - entity_components: &ComponentNameSet, ) -> bool { - if !default_heuristic_filter(entity_components, &self.indicator_components()) { + if !entities_with_matching_indicator.contains(&ent_path.hash()) { return false; } diff --git a/crates/re_viewer/src/app_state.rs b/crates/re_viewer/src/app_state.rs index ef9b4c576f20..48f81fc6e1f2 100644 --- a/crates/re_viewer/src/app_state.rs +++ b/crates/re_viewer/src/app_state.rs @@ -132,16 +132,16 @@ impl AppState { let rec_cfg = recording_config_entry(recording_configs, store_db.store_id().clone(), store_db); + // Gather all entities that have a matching indicator for a visualizer. + let entities_with_matching_indicator_per_visualizer = space_view_class_registry + .entities_with_matching_indicator_per_visualizer(store_db.store_id()); + let entities_per_system_per_class = identify_entities_per_system_per_class( + &entities_with_matching_indicator_per_visualizer, space_view_class_registry, store_db, - &rec_cfg.time_ctrl.get_mut().current_query(), ); - // Gather all entities that have a matching indicator for a visualizer. - let entities_with_matching_indicator_per_visualizer = space_view_class_registry - .entities_with_matching_indicator_per_visualizer(store_db.store_id()); - // Execute the queries for every `SpaceView` let mut query_results = { re_tracing::profile_scope!("query_results"); diff --git a/crates/re_viewer_context/src/lib.rs b/crates/re_viewer_context/src/lib.rs index 2c4e569d6f56..a4cbfd02a143 100644 --- a/crates/re_viewer_context/src/lib.rs +++ b/crates/re_viewer_context/src/lib.rs @@ -41,11 +41,11 @@ pub use selection_state::{ Selection, SelectionHighlight, }; pub use space_view::{ - default_heuristic_filter, AutoSpawnHeuristic, DataResult, DynSpaceViewClass, - HeuristicFilterContext, IdentifiedViewSystem, PerSystemDataResults, PerSystemEntities, - PropertyOverrides, SpaceViewClass, SpaceViewClassIdentifier, SpaceViewClassLayoutPriority, - SpaceViewClassRegistry, SpaceViewClassRegistryError, SpaceViewEntityHighlight, - SpaceViewHighlights, SpaceViewOutlineMasks, SpaceViewState, SpaceViewSystemExecutionError, + AutoSpawnHeuristic, DataResult, DynSpaceViewClass, HeuristicFilterContext, + IdentifiedViewSystem, PerSystemDataResults, PerSystemEntities, PropertyOverrides, + SpaceViewClass, SpaceViewClassIdentifier, SpaceViewClassLayoutPriority, SpaceViewClassRegistry, + SpaceViewClassRegistryError, SpaceViewEntityHighlight, SpaceViewHighlights, + SpaceViewOutlineMasks, SpaceViewState, SpaceViewSystemExecutionError, SpaceViewSystemRegistrator, SystemExecutionOutput, ViewContextCollection, ViewContextSystem, ViewPartCollection, ViewPartSystem, ViewQuery, ViewSystemIdentifier, VisualizerAdditionalApplicabilityFilter, diff --git a/crates/re_viewer_context/src/space_view/mod.rs b/crates/re_viewer_context/src/space_view/mod.rs index b8bd66b9db0d..f466377617ed 100644 --- a/crates/re_viewer_context/src/space_view/mod.rs +++ b/crates/re_viewer_context/src/space_view/mod.rs @@ -29,9 +29,7 @@ pub use space_view_class_registry::{ }; pub use system_execution_output::SystemExecutionOutput; pub use view_context_system::{ViewContextCollection, ViewContextSystem}; -pub use view_part_system::{ - default_heuristic_filter, HeuristicFilterContext, ViewPartCollection, ViewPartSystem, -}; +pub use view_part_system::{HeuristicFilterContext, ViewPartCollection, ViewPartSystem}; pub use view_query::{DataResult, PerSystemDataResults, PropertyOverrides, ViewQuery}; pub use visualizer_entity_subscriber::VisualizerAdditionalApplicabilityFilter; diff --git a/crates/re_viewer_context/src/space_view/view_part_system.rs b/crates/re_viewer_context/src/space_view/view_part_system.rs index f30153c36079..95b138fa5e57 100644 --- a/crates/re_viewer_context/src/space_view/view_part_system.rs +++ b/crates/re_viewer_context/src/space_view/view_part_system.rs @@ -1,7 +1,7 @@ use ahash::HashMap; -use re_arrow_store::LatestAtQuery; -use re_log_types::EntityPath; +use nohash_hasher::IntSet; +use re_log_types::{EntityPath, EntityPathHash}; use re_types::ComponentNameSet; use crate::{ @@ -62,24 +62,16 @@ pub trait ViewPartSystem: Send + Sync + 'static { /// the minimal set of required components), this method applies an arbitrary filter to determine whether /// or not the system should be instantiated by default. /// - /// The passed-in set of `entity_components` corresponds to all the different components that have ever - /// been logged on the entity path. - /// - /// By default, this returns true if either [`Self::indicator_components`] is empty or - /// `entity_components` contains at least one of these indicator components. - /// /// Override this method only if a more detailed condition is required to inform heuristics whether or not /// the given entity is relevant for this system. #[inline] fn heuristic_filter( &self, - _store: &re_arrow_store::DataStore, - _ent_path: &EntityPath, + entities_with_matching_indicator: &IntSet, + ent_path: &EntityPath, _ctx: HeuristicFilterContext, - _query: &LatestAtQuery, - entity_components: &ComponentNameSet, ) -> bool { - default_heuristic_filter(entity_components, &self.indicator_components()) + entities_with_matching_indicator.contains(&ent_path.hash()) } /// Additional filter for applicability. @@ -115,25 +107,6 @@ pub trait ViewPartSystem: Send + Sync + 'static { fn as_any(&self) -> &dyn std::any::Any; } -/// The default implementation for [`ViewPartSystem::heuristic_filter`]. -/// -/// Returns true if either `indicator_components` is empty or `entity_components` contains at least one -/// of these indicator components. -/// -/// Exported as a standalone function to simplify the implementation of custom filters. -#[inline] -pub fn default_heuristic_filter( - entity_components: &ComponentNameSet, - indicator_components: &ComponentNameSet, -) -> bool { - if indicator_components.is_empty() { - true // if there are no indicator components, then show anything with the required compoonents - } else { - // do we have at least one of the indicator components? - entity_components.intersection(indicator_components).count() > 0 - } -} - pub struct ViewPartCollection { pub systems: HashMap>, } diff --git a/crates/re_viewport/src/space_view_entity_picker.rs b/crates/re_viewport/src/space_view_entity_picker.rs index f35d30d94504..a00ffa54ee65 100644 --- a/crates/re_viewport/src/space_view_entity_picker.rs +++ b/crates/re_viewport/src/space_view_entity_picker.rs @@ -363,7 +363,7 @@ fn create_entity_add_info( tree.visit_children_recursively(&mut |entity_path| { let heuristic_context_per_entity = heuristic_context_per_entity.get(entity_path).copied().unwrap_or_default(); let can_add: CanAddToSpaceView = - if is_entity_processed_by_class(ctx, *space_view.class_identifier(), entity_path, heuristic_context_per_entity, &ctx.current_query()) { + if is_entity_processed_by_class(ctx, *space_view.class_identifier(), entity_path, heuristic_context_per_entity) { match spaces_info.is_reachable_by_transform(entity_path, &space_view.space_origin) { Ok(()) => CanAddToSpaceView::Compatible { already_added: query_result.contains_any(entity_path), diff --git a/crates/re_viewport/src/space_view_heuristics.rs b/crates/re_viewport/src/space_view_heuristics.rs index bf64526e2527..7a3250bed9fb 100644 --- a/crates/re_viewport/src/space_view_heuristics.rs +++ b/crates/re_viewport/src/space_view_heuristics.rs @@ -4,13 +4,12 @@ use nohash_hasher::{IntMap, IntSet}; use re_arrow_store::{LatestAtQuery, Timeline}; use re_data_store::{EntityPath, EntityTree}; -use re_log_types::{EntityPathExpr, TimeInt}; +use re_log_types::{EntityPathExpr, EntityPathHash, TimeInt}; use re_space_view::{DataQuery as _, DataQueryBlueprint}; use re_types::components::{DisconnectedSpace, TensorData}; -use re_types::ComponentNameSet; use re_viewer_context::{ AutoSpawnHeuristic, DataQueryResult, EntitiesPerSystem, EntitiesPerSystemPerClass, - HeuristicFilterContext, PerSystemEntities, SpaceViewClassIdentifier, ViewPartCollection, + HeuristicFilterContext, PerSystemEntities, SpaceViewClassIdentifier, ViewSystemIdentifier, ViewerContext, }; @@ -435,34 +434,18 @@ pub fn is_entity_processed_by_class( class: SpaceViewClassIdentifier, ent_path: &EntityPath, heuristic_ctx: HeuristicFilterContext, - query: &LatestAtQuery, ) -> bool { - let parts = ctx.space_view_class_registry.new_part_collection(class); - is_entity_processed_by_part_collection( - ctx.store_db.store(), - &parts, - ent_path, - heuristic_ctx.with_class(class), - query, - ) -} + let parts = &ctx.space_view_class_registry.new_part_collection(class); + let heuristic_ctx = heuristic_ctx.with_class(class); -/// Returns true if an entity is processed by any of the given [`re_viewer_context::ViewPartSystem`]s. -fn is_entity_processed_by_part_collection( - store: &re_arrow_store::DataStore, - parts: &ViewPartCollection, - ent_path: &EntityPath, - ctx: HeuristicFilterContext, - query: &LatestAtQuery, -) -> bool { - let timeline = Timeline::log_time(); - let components = store - .all_components(&timeline, ent_path) - .unwrap_or_default() - .into_iter() - .collect(); - for part in parts.iter() { - if part.heuristic_filter(store, ent_path, ctx, query, &components) { + let empty_entity_set = IntSet::default(); + for (id, visualizer) in parts.iter_with_identifiers() { + let entites_with_matching_indicator = ctx + .entities_with_matching_indicator_per_visualizer + .get(&id) + .unwrap_or(&empty_entity_set); + + if visualizer.heuristic_filter(entites_with_matching_indicator, ent_path, heuristic_ctx) { return true; } } @@ -518,15 +501,20 @@ pub fn compute_heuristic_context_for_entities( } pub fn identify_entities_per_system_per_class( + entities_with_matching_indicator_per_visualizer: &IntMap< + ViewSystemIdentifier, + IntSet, + >, space_view_class_registry: &re_viewer_context::SpaceViewClassRegistry, store_db: &re_data_store::store_db::StoreDb, - current_query: &re_arrow_store::LatestAtQuery, ) -> EntitiesPerSystemPerClass { re_tracing::profile_function!(); let store = store_db.store().id(); let heuristic_context = compute_heuristic_context_for_entities(store_db); + let empty_entity_set = IntSet::default(); + space_view_class_registry .iter_registry() .map(|entry| { @@ -539,6 +527,11 @@ pub fn identify_entities_per_system_per_class( .new_part_collection(class_id) .systems { + let entities_with_matching_indicator = + entities_with_matching_indicator_per_visualizer + .get(&system_id) + .unwrap_or(&empty_entity_set); + let entities: IntSet = if let Some(entities) = space_view_class_registry .applicable_entities_for_visualizer_system(system_id, store) { @@ -547,25 +540,14 @@ pub fn identify_entities_per_system_per_class( entities .into_iter() .filter(|ent_path| { - let Some(components) = store_db - .store() - .all_components(&re_log_types::Timeline::log_time(), ent_path) - else { - return false; - }; - - let all_components: ComponentNameSet = components.into_iter().collect(); - system.heuristic_filter( - store_db.store(), + entities_with_matching_indicator, ent_path, heuristic_context .get(ent_path) .copied() .unwrap_or_default() .with_class(class_id), - current_query, - &all_components, ) }) .collect() From 7e27f614542744aa1682b73a4a48039c67ded2a8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 22 Dec 2023 09:05:33 +0100 Subject: [PATCH 4/4] fix typo --- crates/re_viewport/src/space_view_heuristics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/re_viewport/src/space_view_heuristics.rs b/crates/re_viewport/src/space_view_heuristics.rs index 7a3250bed9fb..ff09a256814e 100644 --- a/crates/re_viewport/src/space_view_heuristics.rs +++ b/crates/re_viewport/src/space_view_heuristics.rs @@ -440,12 +440,12 @@ pub fn is_entity_processed_by_class( let empty_entity_set = IntSet::default(); for (id, visualizer) in parts.iter_with_identifiers() { - let entites_with_matching_indicator = ctx + let entities_with_matching_indicator = ctx .entities_with_matching_indicator_per_visualizer .get(&id) .unwrap_or(&empty_entity_set); - if visualizer.heuristic_filter(entites_with_matching_indicator, ent_path, heuristic_ctx) { + if visualizer.heuristic_filter(entities_with_matching_indicator, ent_path, heuristic_ctx) { return true; } }