From 53ff95973725faa8e597ac002b6cfd6fbd349afa Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Tue, 8 Nov 2022 15:01:00 +0100 Subject: [PATCH] independent scenes and retiring `Objects` (#270) * preparing the field * some more setup and decoupling text-entry UI from Objects * decoupling tensor UI from Objects and fusing old & new * decoupling 3D scenes from Objects * moving view_text_entry over to new logical organization * moving view_tensor over to new logical organization * view2d: no more wildcard imports * decoupling 2D scenes from Objects (part 1) * TextEntry are now Objects-free end to end * dont need em sticky objects no more * Tensors are now Objects-free end to end * Point3Ds are now Objects-free end to end * InstanceHash::from_props => InstanceHash::from_path_and_index * abstracting away object store retrieval * random cleanups * Box3Ds are now Objects-free end to end * cleaning up the DataVec::as_vec situation * Path3Ds are now Objects-free end to end + a lot segments cleanup * LineSegments3D are now Objects-free end to end + related improvements * Mesh3Ds are now Objects-free end to end + related improvements * Arrow3Ds are now Objects-free end to end + related improvements * keeping em warnings under control * Tensor & TextEntry moving towards independent scenes * start independentizing view_3d too * tensor mapping UI now lives with the rest of its kind * cleaning up view_3d's module situation * Images are now Objects-free end to end * BBox2Ds are now Objects-free end to end * Point2Ds are now Objects-free end to end * Legends/ClassDescr are now Objects-free, and Objects is gone for good * plugging back legends into images * bringing back data store benchmarks * independent view_2d * some more clean up * bringing the tooltip back * no need for this i guess * scene cleanup and doc * TODO hunting, cleanup.... * 2d: naming and making loading phase more digestible * 2d: cleanup and document frame delay for hovering * more fixes and TODO hunting * 3d: naming and making loading phase more digestible * tensor: naming and making loading phase more digestible * text: naming and making loading phase more digestible * bring back bench assertion * last cleanup * more profiling * addressing PR comments --- Cargo.lock | 1 + .../benches/obj_query_benchmark.rs | 45 +- crates/re_data_store/src/instance.rs | 21 +- crates/re_data_store/src/lib.rs | 2 - crates/re_data_store/src/objects.rs | 854 ------------------ crates/re_log_types/Cargo.toml | 1 + crates/re_log_types/src/data.rs | 24 + crates/re_viewer/src/app.rs | 2 +- crates/re_viewer/src/misc/mod.rs | 43 +- .../re_viewer/src/misc/tensor_image_cache.rs | 19 +- crates/re_viewer/src/misc/viewer_context.rs | 28 +- crates/re_viewer/src/ui/data_ui.rs | 7 +- crates/re_viewer/src/ui/mod.rs | 26 +- crates/re_viewer/src/ui/scene.rs | 64 ++ crates/re_viewer/src/ui/selection_panel.rs | 2 +- crates/re_viewer/src/ui/space_view.rs | 133 ++- crates/re_viewer/src/ui/text_entry_view.rs | 249 ----- .../ui/{ => view_2d}/class_description_ui.rs | 0 .../src/ui/{ => view_2d}/image_ui.rs | 7 +- .../re_viewer/src/ui/{ => view_2d}/legend.rs | 72 +- crates/re_viewer/src/ui/view_2d/mod.rs | 16 + crates/re_viewer/src/ui/view_2d/scene.rs | 503 +++++++++++ .../src/ui/{view2d.rs => view_2d/ui.rs} | 222 ++--- .../src/ui/{view3d => view_3d}/eye.rs | 8 +- .../{view3d => view_3d}/glow_rendering/mod.rs | 27 +- .../glow_rendering/sphere_renderer.rs | 0 .../src/ui/{view3d => view_3d}/mesh_cache.rs | 0 crates/re_viewer/src/ui/view_3d/mod.rs | 19 + .../src/ui/{view3d => view_3d}/scene.rs | 626 ++++++++----- .../ui/{view3d => view_3d}/space_camera.rs | 0 .../src/ui/{view3d/mod.rs => view_3d/ui.rs} | 118 ++- crates/re_viewer/src/ui/view_tensor/mod.rs | 8 + crates/re_viewer/src/ui/view_tensor/scene.rs | 85 ++ .../tensor_dimension_mapper.rs | 0 .../ui/{view_tensor.rs => view_tensor/ui.rs} | 196 ++-- crates/re_viewer/src/ui/view_text/mod.rs | 5 + crates/re_viewer/src/ui/view_text/scene.rs | 97 ++ crates/re_viewer/src/ui/view_text/ui.rs | 198 ++++ crates/re_viewer/src/ui/viewport.rs | 117 +-- scripts/build_web.sh | 2 +- 40 files changed, 1880 insertions(+), 1967 deletions(-) delete mode 100644 crates/re_data_store/src/objects.rs create mode 100644 crates/re_viewer/src/ui/scene.rs delete mode 100644 crates/re_viewer/src/ui/text_entry_view.rs rename crates/re_viewer/src/ui/{ => view_2d}/class_description_ui.rs (100%) rename crates/re_viewer/src/ui/{ => view_2d}/image_ui.rs (99%) rename crates/re_viewer/src/ui/{ => view_2d}/legend.rs (51%) create mode 100644 crates/re_viewer/src/ui/view_2d/mod.rs create mode 100644 crates/re_viewer/src/ui/view_2d/scene.rs rename crates/re_viewer/src/ui/{view2d.rs => view_2d/ui.rs} (79%) rename crates/re_viewer/src/ui/{view3d => view_3d}/eye.rs (98%) rename crates/re_viewer/src/ui/{view3d => view_3d}/glow_rendering/mod.rs (95%) rename crates/re_viewer/src/ui/{view3d => view_3d}/glow_rendering/sphere_renderer.rs (100%) rename crates/re_viewer/src/ui/{view3d => view_3d}/mesh_cache.rs (100%) create mode 100644 crates/re_viewer/src/ui/view_3d/mod.rs rename crates/re_viewer/src/ui/{view3d => view_3d}/scene.rs (56%) rename crates/re_viewer/src/ui/{view3d => view_3d}/space_camera.rs (100%) rename crates/re_viewer/src/ui/{view3d/mod.rs => view_3d/ui.rs} (91%) create mode 100644 crates/re_viewer/src/ui/view_tensor/mod.rs create mode 100644 crates/re_viewer/src/ui/view_tensor/scene.rs rename crates/re_viewer/src/ui/{ => view_tensor}/tensor_dimension_mapper.rs (100%) rename crates/re_viewer/src/ui/{view_tensor.rs => view_tensor/ui.rs} (96%) create mode 100644 crates/re_viewer/src/ui/view_text/mod.rs create mode 100644 crates/re_viewer/src/ui/view_text/scene.rs create mode 100644 crates/re_viewer/src/ui/view_text/ui.rs diff --git a/Cargo.lock b/Cargo.lock index 4d5911b05b19..64574f803e93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3063,6 +3063,7 @@ dependencies = [ "macaw", "nohash-hasher", "puffin", + "re_log", "re_string_interner", "rmp-serde", "ruzstd", diff --git a/crates/re_data_store/benches/obj_query_benchmark.rs b/crates/re_data_store/benches/obj_query_benchmark.rs index 3191e2e5eca8..fd2d71cc1506 100644 --- a/crates/re_data_store/benches/obj_query_benchmark.rs +++ b/crates/re_data_store/benches/obj_query_benchmark.rs @@ -5,7 +5,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use itertools::Itertools; use nohash_hasher::IntMap; -use re_data_store::*; +use re_data_store::{query::visit_type_data_3, *}; use re_log_types::*; #[cfg(not(debug_assertions))] @@ -23,16 +23,43 @@ fn timeline() -> Timeline { Timeline::new("frame", TimeType::Sequence) } -fn do_query<'s>( - obj_types: &IntMap, - data_store: &'s DataStore, -) -> Objects<'s> { +#[allow(dead_code)] +#[derive(Clone, Copy)] +struct Point { + pos: [f32; 3], + color: Option<[u8; 4]>, +} + +fn do_query(obj_types: &IntMap, data_store: &DataStore) -> Vec { let time_query = TimeQuery::LatestAt(NUM_FRAMES / 2); - let mut objects = Objects::default(); let timeline_store = data_store.get(&timeline()).unwrap(); - objects.query(timeline_store, &time_query, obj_types); - assert_eq!(objects.point3d.len(), NUM_POINTS as usize); - objects + + let mut points = Vec::new(); + + for (obj_path, obj_store) in timeline_store.iter() { + let _ = obj_types.get(obj_path.obj_type_path()).unwrap(); + visit_type_data_3( + obj_store, + &FieldName::from("pos"), + &time_query, + ("_visible", "color", "radius"), + |_instance_index: Option<&IndexHash>, + _time: i64, + _msg_id: &MsgId, + pos: &[f32; 3], + _visible: Option<&bool>, + color: Option<&[u8; 4]>, + _radius: Option<&f32>| { + points.push(Point { + pos: *pos, + color: color.cloned(), + }); + }, + ); + } + + assert_eq!(points.len(), NUM_POINTS as usize); + points } fn mono_data_messages() -> Vec { diff --git a/crates/re_data_store/src/instance.rs b/crates/re_data_store/src/instance.rs index d44277682c8f..d77512a8e957 100644 --- a/crates/re_data_store/src/instance.rs +++ b/crates/re_data_store/src/instance.rs @@ -2,7 +2,7 @@ use std::hash::Hash; use re_log_types::{Index, IndexHash, ObjPath, ObjPathHash}; -use crate::{DataStore, InstanceProps}; +use crate::DataStore; // ---------------------------------------------------------------------------- @@ -27,12 +27,12 @@ impl InstanceId { /// Does this object match this instance id? #[inline] - pub fn is_instance(&self, props: &InstanceProps<'_>) -> bool { - &self.obj_path == props.obj_path + pub fn is_instance(&self, obj_path: &ObjPath, instance_index: IndexHash) -> bool { + &self.obj_path == obj_path && if let Some(index) = &self.instance_index { - index.hash() == props.instance_index + index.hash() == instance_index } else { - props.instance_index.is_none() + instance_index.is_none() } } @@ -72,10 +72,10 @@ impl InstanceIdHash { }; #[inline] - pub fn from_props(props: &InstanceProps<'_>) -> Self { + pub fn from_path_and_index(obj_path: &ObjPath, instance_index: IndexHash) -> Self { Self { - obj_path_hash: *props.obj_path.hash(), - instance_index_hash: props.instance_index, + obj_path_hash: *obj_path.hash(), + instance_index_hash: instance_index, } } @@ -93,8 +93,7 @@ impl InstanceIdHash { /// Does this object match this instance id? #[inline] - pub fn is_instance(&self, props: &InstanceProps<'_>) -> bool { - &self.obj_path_hash == props.obj_path.hash() - && self.instance_index_hash == props.instance_index + pub fn is_instance(&self, obj_path: &ObjPath, instance_index: IndexHash) -> bool { + &self.obj_path_hash == obj_path.hash() && self.instance_index_hash == instance_index } } diff --git a/crates/re_data_store/src/lib.rs b/crates/re_data_store/src/lib.rs index 895d2f3be0f5..d0c440389dfe 100644 --- a/crates/re_data_store/src/lib.rs +++ b/crates/re_data_store/src/lib.rs @@ -23,7 +23,6 @@ mod instance; pub mod log_db; pub mod object_tree; pub mod object_tree_properties; -pub mod objects; pub mod query; mod stores; @@ -32,7 +31,6 @@ pub use instance::*; pub use log_db::LogDb; pub use object_tree::*; pub use object_tree_properties::*; -pub use objects::*; pub use stores::*; use re_log_types::DataType; diff --git a/crates/re_data_store/src/objects.rs b/crates/re_data_store/src/objects.rs deleted file mode 100644 index ed00c944d056..000000000000 --- a/crates/re_data_store/src/objects.rs +++ /dev/null @@ -1,854 +0,0 @@ -use std::collections::BTreeMap; - -use ahash::HashMap; -use nohash_hasher::IntMap; -use re_log_types::{objects::*, DataVec, FieldName, IndexHash, MsgId, ObjPath, ObjTypePath}; - -use crate::{query::*, ObjStore, TimeQuery, TimelineStore}; - -/// Common properties of an object instance. -#[derive(Copy, Clone, Debug)] -pub struct InstanceProps<'s> { - // NOTE: While we would normally make InstanceProps generic over time - // (`InstanceProps<'s, Time`>), doing so leads to a gigantic template-leak that - // propagates all over the codebase. - // So for now we will constrain ourselves to an i64 here, which is the only unit - // of time we currently use in practice anyway. - pub time: i64, - pub msg_id: &'s MsgId, - pub color: Option<[u8; 4]>, - - /// Use this to test if the object should be visible, etc. - pub obj_path: &'s ObjPath, - - /// If it is a multi-object, this is the instance index, - /// else it is [`IndexHash::NONE`]. - pub instance_index: IndexHash, - - /// Whether or not the object is visible - pub visible: bool, -} - -#[derive(Copy, Clone, Debug)] -struct Object<'s, T: Copy + Clone + std::fmt::Debug> { - pub props: InstanceProps<'s>, - pub data: T, -} - -#[derive(Clone, Debug)] -pub struct ObjectVec<'s, T: Copy + Clone + std::fmt::Debug>(Vec>); - -impl<'s, T: Clone + Copy + std::fmt::Debug> Default for ObjectVec<'s, T> { - fn default() -> Self { - Self(Default::default()) - } -} - -impl<'s, T: Clone + Copy + std::fmt::Debug> ObjectVec<'s, T> { - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn iter(&self) -> impl ExactSizeIterator, &T)> { - self.0.iter().map(|obj| (&obj.props, &obj.data)) - } - - pub fn first(&self) -> Option<(&InstanceProps<'s>, &T)> { - self.0.first().map(|obj| (&obj.props, &obj.data)) - } - - pub fn last(&self) -> Option<(&InstanceProps<'s>, &T)> { - self.0.last().map(|obj| (&obj.props, &obj.data)) - } - - pub fn get(&self, idx: usize) -> Option<(&InstanceProps<'s>, &T)> { - self.0.get(idx).map(|obj| (&obj.props, &obj.data)) - } - - pub fn filter(&self, keep: &impl Fn(&InstanceProps<'_>) -> bool) -> Self { - crate::profile_function!(); - Self( - self.0 - .iter() - .filter(|obj| keep(&obj.props)) - .copied() - .collect(), - ) - } -} - -#[derive(Copy, Clone, Debug)] -pub struct Image<'s> { - pub tensor: &'s re_log_types::Tensor, - - /// If this is a depth map, how long is a meter? - /// - /// For instance, with a `u16` dtype one might have - /// `meter == 1000.0` for millimeter precision - /// up to a ~65m range. - pub meter: Option, - - /// A thing that provides additional semantic context for your dtype - /// Currrently must point to a SegmentationMap - pub legend: Option<&'s ObjPath>, -} - -impl<'s> Image<'s> { - fn query>( - obj_path: &'s ObjPath, - obj_store: &'s ObjStore