From 51350829da593ce510e685754a5df4df4a3fb4fe Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 2 Oct 2023 13:43:24 +0200 Subject: [PATCH] allow showing image shaped tensors in the tensor view --- .../src/view_part_system.rs | 54 +++++-------------- .../re_viewport/src/space_view_heuristics.rs | 24 ++++----- 2 files changed, 24 insertions(+), 54 deletions(-) diff --git a/crates/re_space_view_tensor/src/view_part_system.rs b/crates/re_space_view_tensor/src/view_part_system.rs index e4d3cf4f685f..970d5c42f5c5 100644 --- a/crates/re_space_view_tensor/src/view_part_system.rs +++ b/crates/re_space_view_tensor/src/view_part_system.rs @@ -8,8 +8,8 @@ use re_types::{ Archetype, ComponentNameSet, }; use re_viewer_context::{ - default_heuristic_filter, NamedViewSystem, SpaceViewSystemExecutionError, TensorDecodeCache, - ViewContextCollection, ViewPartSystem, ViewQuery, ViewerContext, + NamedViewSystem, SpaceViewSystemExecutionError, TensorDecodeCache, ViewContextCollection, + ViewPartSystem, ViewQuery, ViewerContext, }; #[derive(Default)] @@ -35,28 +35,6 @@ impl ViewPartSystem for TensorSystem { std::iter::once(Tensor::indicator().name()).collect() } - /// Tensor view doesn't handle 2D images, see [`TensorSystem::load_tensor_entity`] - fn heuristic_filter( - &self, - store: &re_arrow_store::DataStore, - ent_path: &EntityPath, - query: &LatestAtQuery, - entity_components: &ComponentNameSet, - ) -> bool { - if !default_heuristic_filter(entity_components, &self.indicator_components()) { - return false; - } - - // NOTE: We want to make sure we query at the right time, otherwise we might take into - // account a `Clear()` that actually only applies into the future, and then - // `is_shaped_like_an_image` will righfully fail because of the empty tensor. - if let Some(tensor) = store.query_latest_component::(ent_path, query) { - !tensor.is_shaped_like_an_image() && !tensor.is_vector() - } else { - false - } - } - fn execute( &mut self, ctx: &mut ViewerContext<'_>, @@ -93,22 +71,18 @@ impl TensorSystem { _props: &EntityProperties, tensor: TensorData, ) { - if !tensor.is_shaped_like_an_image() { - // NOTE: Tensors don't support batches at the moment so always splat. - let tensor_path_hash = InstancePathHash::entity_splat(ent_path).versioned(row_id); - match ctx - .cache - .entry(|c: &mut TensorDecodeCache| c.entry(tensor_path_hash, tensor.0)) - { - Ok(tensor) => { - let instance_path = InstancePath::instance(ent_path.clone(), InstanceKey(0)); - self.tensors.insert(instance_path, (row_id, tensor)); - } - Err(err) => { - re_log::warn_once!( - "Failed to decode decoding tensor at path {ent_path}: {err}" - ); - } + // NOTE: Tensors don't support batches at the moment so always splat. + let tensor_path_hash = InstancePathHash::entity_splat(ent_path).versioned(row_id); + match ctx + .cache + .entry(|c: &mut TensorDecodeCache| c.entry(tensor_path_hash, tensor.0)) + { + Ok(tensor) => { + let instance_path = InstancePath::instance(ent_path.clone(), InstanceKey(0)); + self.tensors.insert(instance_path, (row_id, tensor)); + } + Err(err) => { + re_log::warn_once!("Failed to decode decoding tensor at path {ent_path}: {err}"); } } } diff --git a/crates/re_viewport/src/space_view_heuristics.rs b/crates/re_viewport/src/space_view_heuristics.rs index d99529d967e7..643fdeca971c 100644 --- a/crates/re_viewport/src/space_view_heuristics.rs +++ b/crates/re_viewport/src/space_view_heuristics.rs @@ -4,8 +4,9 @@ use nohash_hasher::{IntMap, IntSet}; use re_arrow_store::{LatestAtQuery, Timeline}; use re_data_store::EntityPath; +use re_types::archetypes::Image; use re_types::components::{DisconnectedSpace, TensorData}; -use re_types::ComponentNameSet; +use re_types::{Archetype, ComponentNameSet}; use re_viewer_context::{ AutoSpawnHeuristic, SpaceViewClassName, ViewContextCollection, ViewPartCollection, ViewSystemName, ViewerContext, @@ -123,22 +124,17 @@ pub fn all_possible_space_views( .collect_vec() } -fn contains_any_image( - entity_path: &EntityPath, - store: &re_arrow_store::DataStore, - query: &LatestAtQuery, -) -> bool { - if let Some(tensor) = store.query_latest_component::(entity_path, query) { - tensor.is_shaped_like_an_image() - } else { - false - } +fn contains_any_image(ent_path: &EntityPath, store: &re_arrow_store::DataStore) -> bool { + store + .all_components(&Timeline::log_time(), ent_path) + .unwrap_or_default() + .iter() + .any(|comp| *comp == Image::indicator().name()) } fn is_interesting_space_view_at_root( data_store: &re_arrow_store::DataStore, candidate: &SpaceViewBlueprint, - query: &LatestAtQuery, ) -> bool { // Not interesting if it has only data blueprint groups and no direct entities. // -> If there In that case we want spaceviews at those groups. @@ -149,7 +145,7 @@ fn is_interesting_space_view_at_root( // If there are any images directly under the root, don't create root space either. // -> For images we want more fine grained control and resort to child-of-root spaces only. for entity_path in &candidate.contents.root_group().entities { - if contains_any_image(entity_path, data_store, query) { + if contains_any_image(entity_path, data_store) { return false; } } @@ -208,7 +204,7 @@ pub fn default_created_space_views( .iter() .filter_map(|space_view_candidate| { (space_view_candidate.space_origin.is_root() - && is_interesting_space_view_at_root(store, space_view_candidate, &query)) + && is_interesting_space_view_at_root(store, space_view_candidate)) .then_some(*space_view_candidate.class_name()) }) .collect::>();