From bf89c307dac5dc8fd8016dd985f8af30a6ee73a7 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Tue, 23 Jan 2024 16:32:17 +0100 Subject: [PATCH] don't denormalize defaulted values (fix #4779) --- crates/re_data_store/benches/data_store.rs | 4 +- crates/re_query_cache/benches/latest_at.rs | 16 ++--- crates/re_query_cache/src/cache.rs | 21 +++++-- crates/re_query_cache/src/latest_at.rs | 4 +- crates/re_query_cache/src/query.rs | 22 +++++-- crates/re_query_cache/src/range.rs | 4 +- crates/re_query_cache/tests/latest_at.rs | 12 +++- crates/re_query_cache/tests/range.rs | 14 ++++- .../benches/bench_points.rs | 16 ++--- .../src/visualizers/entity_iterator.rs | 4 +- .../src/visualizers/mod.rs | 21 +++++-- .../src/visualizers/points2d.rs | 57 +++++++++++------- .../src/visualizers/points3d.rs | 59 +++++++++++-------- .../src/visualizer_system.rs | 9 ++- .../src/visualizer_system.rs | 10 ++-- 15 files changed, 173 insertions(+), 100 deletions(-) diff --git a/crates/re_data_store/benches/data_store.rs b/crates/re_data_store/benches/data_store.rs index 460a24dfcc1e..d89009ff67f1 100644 --- a/crates/re_data_store/benches/data_store.rs +++ b/crates/re_data_store/benches/data_store.rs @@ -1,7 +1,7 @@ #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; -use arrow2::array::{Array as _, StructArray, UnionArray}; +use arrow2::array::{Array as _, StructArray}; use criterion::{criterion_group, criterion_main, Criterion}; use re_data_store::{ @@ -312,7 +312,7 @@ fn range(c: &mut Criterion) { .unwrap() .as_arrow_ref() .as_any() - .downcast_ref::() + .downcast_ref::() .unwrap(); assert_eq!(NUM_INSTANCES as usize, large_structs.len()); } diff --git a/crates/re_query_cache/benches/latest_at.rs b/crates/re_query_cache/benches/latest_at.rs index dfd7f3e8827f..f1cafd9e0878 100644 --- a/crates/re_query_cache/benches/latest_at.rs +++ b/crates/re_query_cache/benches/latest_at.rs @@ -292,12 +292,14 @@ fn query_and_visit_points( &query.clone().into(), path, |(_, _, positions, colors)| { - itertools::izip!(positions.iter(), colors.iter()).for_each(|(pos, color)| { - points.push(SavePoint { - _pos: *pos, - _color: *color, - }); - }); + itertools::izip!(positions.iter(), colors.unwrap().iter()).for_each( + |(pos, color)| { + points.push(SavePoint { + _pos: *pos, + _color: *color, + }); + }, + ); }, ) .unwrap(); @@ -328,7 +330,7 @@ fn query_and_visit_strings( &query.clone().into(), path, |(_, _, _, labels)| { - for label in labels.iter() { + for label in labels.unwrap().iter() { strings.push(SaveString { _label: label.clone(), }); diff --git a/crates/re_query_cache/src/cache.rs b/crates/re_query_cache/src/cache.rs index dd19c620c4fb..99da6dc98e7f 100644 --- a/crates/re_query_cache/src/cache.rs +++ b/crates/re_query_cache/src/cache.rs @@ -770,6 +770,7 @@ impl CacheBucket { Ok(added_size_bytes) } + /// This will insert an empty slice for a missing component (instead of N `None` values). #[inline] fn insert_component_opt( &mut self, @@ -783,12 +784,20 @@ impl CacheBucket { .entry(C::name()) .or_insert_with(|| Box::new(FlatVecDeque::>::new())); - // The `FlatVecDeque` will have to collect the data one way or another: do it ourselves - // instead, that way we can efficiently computes its size while we're at it. - let added: FlatVecDeque> = arch_view - .iter_optional_component::()? - .collect::>>() - .into(); + let added: FlatVecDeque> = if arch_view.has_component::() { + // The `FlatVecDeque` will have to collect the data one way or another: do it ourselves + // instead, that way we can efficiently computes its size while we're at it. + arch_view + .iter_optional_component::()? + .collect::>>() + .into() + } else { + // If an optional component is missing entirely, we just store an empty slice in its + // stead, rather than a bunch of `None` values. + let mut added = FlatVecDeque::>::new(); + added.push_back(std::iter::empty()); + added + }; let added_size_bytes = added.total_size_bytes(); // NOTE: downcast cannot fail, we create it just above. diff --git a/crates/re_query_cache/src/latest_at.rs b/crates/re_query_cache/src/latest_at.rs index 5cce908a1ea4..40d79014d80d 100644 --- a/crates/re_query_cache/src/latest_at.rs +++ b/crates/re_query_cache/src/latest_at.rs @@ -125,7 +125,7 @@ macro_rules! impl_query_archetype_latest_at { (Option, RowId), MaybeCachedComponentData<'_, InstanceKey>, $(MaybeCachedComponentData<'_, $pov>,)+ - $(MaybeCachedComponentData<'_, Option<$comp>>,)* + $(Option>>,)* ), ), { @@ -144,7 +144,7 @@ macro_rules! impl_query_archetype_latest_at { ((!timeless).then_some(*time), *row_id), MaybeCachedComponentData::Cached(instance_keys), $(MaybeCachedComponentData::Cached($pov),)+ - $(MaybeCachedComponentData::Cached($comp),)* + $((!$comp.is_empty()).then_some(MaybeCachedComponentData::Cached($comp)),)* ) }); diff --git a/crates/re_query_cache/src/query.rs b/crates/re_query_cache/src/query.rs index 2c1bc56cb018..10c479676976 100644 --- a/crates/re_query_cache/src/query.rs +++ b/crates/re_query_cache/src/query.rs @@ -22,6 +22,20 @@ pub enum MaybeCachedComponentData<'a, C> { Raw(Vec), } +impl<'a, C> MaybeCachedComponentData<'a, Option> { + /// Iterates over the data of an optional component, or repeat `None` values if it's missing. + #[inline] + pub fn iter_or_repeat_opt( + this: &Option, + len: usize, + ) -> impl Iterator> + '_ { + this.as_ref().map_or( + itertools::Either::Left(std::iter::repeat(&None).take(len)), + |data| itertools::Either::Right(data.iter()), + ) + } +} + impl<'a, C> std::ops::Deref for MaybeCachedComponentData<'a, C> { type Target = [C]; @@ -99,7 +113,7 @@ macro_rules! impl_query_archetype { (Option, RowId), MaybeCachedComponentData<'_, InstanceKey>, $(MaybeCachedComponentData<'_, $pov>,)+ - $(MaybeCachedComponentData<'_, Option<$comp>>,)* + $(Option>>,)* ), ), { @@ -119,7 +133,7 @@ macro_rules! impl_query_archetype { (arch_view.data_time(), arch_view.primary_row_id()), MaybeCachedComponentData::Raw(arch_view.iter_instance_keys().collect()), $(MaybeCachedComponentData::Raw(arch_view.iter_required_component::<$pov>()?.collect()),)+ - $(MaybeCachedComponentData::Raw(arch_view.iter_optional_component::<$comp>()?.collect()),)* + $(Some(MaybeCachedComponentData::Raw(arch_view.iter_optional_component::<$comp>()?.collect())),)* ); f(data); @@ -150,7 +164,7 @@ macro_rules! impl_query_archetype { (arch_view.data_time(), arch_view.primary_row_id()), MaybeCachedComponentData::Raw(arch_view.iter_instance_keys().collect()), $(MaybeCachedComponentData::Raw(arch_view.iter_required_component::<$pov>()?.collect()),)+ - $(MaybeCachedComponentData::Raw(arch_view.iter_optional_component::<$comp>()?.collect()),)* + $(Some(MaybeCachedComponentData::Raw(arch_view.iter_optional_component::<$comp>()?.collect())),)* ); f(data); @@ -259,7 +273,7 @@ macro_rules! impl_query_archetype_with_history { (Option, RowId), MaybeCachedComponentData<'_, InstanceKey>, $(MaybeCachedComponentData<'_, $pov>,)+ - $(MaybeCachedComponentData<'_, Option<$comp>>,)* + $(Option>>,)* ), ), { diff --git a/crates/re_query_cache/src/range.rs b/crates/re_query_cache/src/range.rs index 1e99ce567ab3..0864414c5ae9 100644 --- a/crates/re_query_cache/src/range.rs +++ b/crates/re_query_cache/src/range.rs @@ -136,7 +136,7 @@ macro_rules! impl_query_archetype_range { (Option, RowId), MaybeCachedComponentData<'_, InstanceKey>, $(MaybeCachedComponentData<'_, $pov>,)+ - $(MaybeCachedComponentData<'_, Option<$comp>>,)* + $(Option>>,)* ), ), { @@ -158,7 +158,7 @@ macro_rules! impl_query_archetype_range { ((!timeless).then_some(*time), *row_id), MaybeCachedComponentData::Cached(instance_keys), $(MaybeCachedComponentData::Cached($pov),)+ - $(MaybeCachedComponentData::Cached($comp),)* + $((!$comp.is_empty()).then_some(MaybeCachedComponentData::Cached($comp)),)* ) }); diff --git a/crates/re_query_cache/tests/latest_at.rs b/crates/re_query_cache/tests/latest_at.rs index e98297065b6a..f8199cfee14c 100644 --- a/crates/re_query_cache/tests/latest_at.rs +++ b/crates/re_query_cache/tests/latest_at.rs @@ -10,7 +10,7 @@ use re_log_types::{ example_components::{MyColor, MyPoint, MyPoints}, DataRow, EntityPath, RowId, TimePoint, }; -use re_query_cache::Caches; +use re_query_cache::{Caches, MaybeCachedComponentData}; use re_types_core::{components::InstanceKey, Loggable as _}; // --- @@ -463,7 +463,10 @@ fn query_and_compare( uncached_data_time = data_time; uncached_instance_keys.extend(instance_keys.iter().copied()); uncached_positions.extend(positions.iter().copied()); - uncached_colors.extend(colors.iter().copied()); + uncached_colors.extend(MaybeCachedComponentData::iter_or_repeat_opt( + &colors, + positions.len(), + )); }, ) .unwrap(); @@ -482,7 +485,10 @@ fn query_and_compare( cached_data_time = data_time; cached_instance_keys.extend(instance_keys.iter().copied()); cached_positions.extend(positions.iter().copied()); - cached_colors.extend(colors.iter().copied()); + cached_colors.extend(MaybeCachedComponentData::iter_or_repeat_opt( + &colors, + positions.len(), + )); }, ) .unwrap(); diff --git a/crates/re_query_cache/tests/range.rs b/crates/re_query_cache/tests/range.rs index dd91cb9c77fa..a96115ce1920 100644 --- a/crates/re_query_cache/tests/range.rs +++ b/crates/re_query_cache/tests/range.rs @@ -10,7 +10,7 @@ use re_log_types::{ example_components::{MyColor, MyLabel, MyPoint, MyPoints}, DataRow, EntityPath, RowId, TimeInt, TimePoint, TimeRange, }; -use re_query_cache::Caches; +use re_query_cache::{Caches, MaybeCachedComponentData}; use re_types::components::InstanceKey; use re_types_core::Loggable as _; @@ -597,7 +597,11 @@ fn query_and_compare( uncached_data_times.push(data_time); uncached_instance_keys.push(instance_keys.to_vec()); uncached_positions.push(positions.to_vec()); - uncached_colors.push(colors.to_vec()); + uncached_colors.push( + MaybeCachedComponentData::iter_or_repeat_opt(&colors, positions.len()) + .copied() + .collect_vec(), + ); }, ) .unwrap(); @@ -616,7 +620,11 @@ fn query_and_compare( cached_data_times.push(data_time); cached_instance_keys.push(instance_keys.to_vec()); cached_positions.push(positions.to_vec()); - cached_colors.push(colors.to_vec()); + cached_colors.push( + MaybeCachedComponentData::iter_or_repeat_opt(&colors, positions.len()) + .copied() + .collect_vec(), + ); }, ) .unwrap(); diff --git a/crates/re_space_view_spatial/benches/bench_points.rs b/crates/re_space_view_spatial/benches/bench_points.rs index 5e63ad0e0bef..52b32ce2b18d 100644 --- a/crates/re_space_view_spatial/benches/bench_points.rs +++ b/crates/re_space_view_spatial/benches/bench_points.rs @@ -116,17 +116,11 @@ fn bench_points(c: &mut criterion::Criterion) { let data = Points3DComponentData { instance_keys: instance_keys.as_slice(), positions: positions.as_slice(), - colors: colors.as_slice(), - radii: radii.as_slice(), - labels: labels.as_slice(), - keypoint_ids: keypoint_ids - .iter() - .any(Option::is_some) - .then_some(keypoint_ids.as_slice()), - class_ids: class_ids - .iter() - .any(Option::is_some) - .then_some(class_ids.as_slice()), + colors: colors.as_deref(), + radii: radii.as_deref(), + labels: labels.as_deref(), + keypoint_ids: keypoint_ids.as_deref(), + class_ids: class_ids.as_deref(), }; assert_eq!(data.instance_keys.len(), NUM_POINTS); diff --git a/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs b/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs index 9e34213dce07..78119e8d0786 100644 --- a/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs +++ b/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs @@ -139,7 +139,7 @@ macro_rules! impl_process_archetype { (Option, RowId), &[InstanceKey], $(&[$pov],)* - $(&[Option<$comp>],)* + $(Option<&[Option<$comp>]>,)* ) -> ::re_query::Result<()>, { // NOTE: not `profile_function!` because we want them merged together. @@ -204,7 +204,7 @@ macro_rules! impl_process_archetype { t, keys.as_slice(), $($pov.as_slice(),)+ - $($comp.as_slice(),)* + $($comp.as_deref(),)* ) { re_log::error_once!( "Unexpected error querying {:?}: {err}", diff --git a/crates/re_space_view_spatial/src/visualizers/mod.rs b/crates/re_space_view_spatial/src/visualizers/mod.rs index e574d2b0c6e6..67e362a771ce 100644 --- a/crates/re_space_view_spatial/src/visualizers/mod.rs +++ b/crates/re_space_view_spatial/src/visualizers/mod.rs @@ -126,13 +126,19 @@ pub fn process_colors<'a, A: Archetype>( /// Process [`Color`] components using annotations and default colors. pub fn process_color_slice<'a>( - colors: &'a [Option], + colors: Option<&'a [Option]>, + default_len: usize, ent_path: &'a EntityPath, annotation_infos: &'a ResolvedAnnotationInfos, ) -> impl Iterator + 'a { re_tracing::profile_function!(); let default_color = DefaultColor::EntityPath(ent_path); + let colors = colors.as_ref().map_or( + itertools::Either::Left(std::iter::repeat(&None).take(default_len)), + |data| itertools::Either::Right(data.iter()), + ); + itertools::izip!(annotation_infos.iter(), colors).map(move |(annotation_info, color)| { annotation_info.color(color.map(|c| c.to_array()), default_color) }) @@ -169,14 +175,19 @@ pub fn process_radii<'a, A: Archetype>( /// Process [`re_types::components::Radius`] components to [`re_renderer::Size`] using auto size /// where no radius is specified. pub fn process_radius_slice<'a>( - radii: &'a [Option], + radii: Option<&'a [Option]>, + default_len: usize, ent_path: &EntityPath, ) -> impl Iterator + 'a { re_tracing::profile_function!(); let ent_path = ent_path.clone(); - radii - .iter() - .map(move |radius| process_radius(&ent_path, radius)) + + let radii = radii.as_ref().map_or( + itertools::Either::Left(std::iter::repeat(&None).take(default_len)), + |data| itertools::Either::Right(data.iter()), + ); + + radii.map(move |radius| process_radius(&ent_path, radius)) } fn process_radius( diff --git a/crates/re_space_view_spatial/src/visualizers/points2d.rs b/crates/re_space_view_spatial/src/visualizers/points2d.rs index 9bb7d20f9354..3e632411540a 100644 --- a/crates/re_space_view_spatial/src/visualizers/points2d.rs +++ b/crates/re_space_view_spatial/src/visualizers/points2d.rs @@ -41,7 +41,7 @@ impl Default for Points2DVisualizer { impl Points2DVisualizer { fn process_labels<'a>( - &Points2DComponentData { labels, .. }: &'a Points2DComponentData<'_>, + labels: &'a [Option], positions: &'a [glam::Vec3], instance_path_hashes: &'a [InstancePathHash], colors: &'a [egui::Color32], @@ -143,8 +143,13 @@ impl Points2DVisualizer { re_tracing::profile_scope!("labels"); // Max labels is small enough that we can afford iterating on the colors again. - let colors = - process_color_slice(data.colors, ent_path, &annotation_infos).collect::>(); + let colors = process_color_slice( + data.colors, + data.positions.len(), + ent_path, + &annotation_infos, + ) + .collect::>(); let instance_path_hashes_for_picking = { re_tracing::profile_scope!("instance_hashes"); @@ -155,13 +160,15 @@ impl Points2DVisualizer { .collect::>() }; - self.data.ui_labels.extend(Self::process_labels( - data, - &positions, - &instance_path_hashes_for_picking, - &colors, - &annotation_infos, - )); + if let Some(labels) = data.labels { + self.data.ui_labels.extend(Self::process_labels( + labels, + &positions, + &instance_path_hashes_for_picking, + &colors, + &annotation_infos, + )); + } } } @@ -178,11 +185,13 @@ impl Points2DVisualizer { #[inline] pub fn load_radii( - &Points2DComponentData { radii, .. }: &Points2DComponentData<'_>, + &Points2DComponentData { + positions, radii, .. + }: &Points2DComponentData<'_>, ent_path: &EntityPath, ) -> Vec { re_tracing::profile_function!(); - let radii = crate::visualizers::process_radius_slice(radii, ent_path); + let radii = crate::visualizers::process_radius_slice(radii, positions.len(), ent_path); { re_tracing::profile_scope!("collect"); radii.collect() @@ -191,12 +200,19 @@ impl Points2DVisualizer { #[inline] pub fn load_colors( - &Points2DComponentData { colors, .. }: &Points2DComponentData<'_>, + &Points2DComponentData { + positions, colors, .. + }: &Points2DComponentData<'_>, ent_path: &EntityPath, annotation_infos: &ResolvedAnnotationInfos, ) -> Vec { re_tracing::profile_function!(); - let colors = crate::visualizers::process_color_slice(colors, ent_path, annotation_infos); + let colors = crate::visualizers::process_color_slice( + colors, + positions.len(), + ent_path, + annotation_infos, + ); { re_tracing::profile_scope!("collect"); colors.collect() @@ -218,9 +234,9 @@ impl Points2DVisualizer { pub struct Points2DComponentData<'a> { pub instance_keys: &'a [InstanceKey], pub positions: &'a [Position2D], - pub colors: &'a [Option], - pub radii: &'a [Option], - pub labels: &'a [Option], + pub colors: Option<&'a [Option]>, + pub radii: Option<&'a [Option]>, + pub labels: Option<&'a [Option]>, pub keypoint_ids: Option<&'a [Option]>, pub class_ids: Option<&'a [Option]>, } @@ -291,11 +307,8 @@ impl VisualizerSystem for Points2DVisualizer { colors, radii, labels, - keypoint_ids: keypoint_ids - .iter() - .any(Option::is_some) - .then_some(keypoint_ids), - class_ids: class_ids.iter().any(Option::is_some).then_some(class_ids), + keypoint_ids, + class_ids, }; self.process_data(query, &data, ent_path, ent_context); Ok(()) diff --git a/crates/re_space_view_spatial/src/visualizers/points3d.rs b/crates/re_space_view_spatial/src/visualizers/points3d.rs index 5b23536013c6..67846b0f02dc 100644 --- a/crates/re_space_view_spatial/src/visualizers/points3d.rs +++ b/crates/re_space_view_spatial/src/visualizers/points3d.rs @@ -40,7 +40,7 @@ impl Default for Points3DVisualizer { impl Points3DVisualizer { fn process_labels<'a>( - &Points3DComponentData { labels, .. }: &'a Points3DComponentData<'_>, + labels: &'a [Option], positions: &'a [glam::Vec3], instance_path_hashes: &'a [InstancePathHash], colors: &'a [egui::Color32], @@ -134,8 +134,13 @@ impl Points3DVisualizer { re_tracing::profile_scope!("labels"); // Max labels is small enough that we can afford iterating on the colors again. - let colors = - process_color_slice(data.colors, ent_path, &annotation_infos).collect::>(); + let colors = process_color_slice( + data.colors, + data.positions.len(), + ent_path, + &annotation_infos, + ) + .collect::>(); let instance_path_hashes_for_picking = { re_tracing::profile_scope!("instance_hashes"); @@ -146,14 +151,16 @@ impl Points3DVisualizer { .collect::>() }; - self.data.ui_labels.extend(Self::process_labels( - data, - &positions, - &instance_path_hashes_for_picking, - &colors, - &annotation_infos, - ent_context.world_from_entity, - )); + if let Some(labels) = data.labels { + self.data.ui_labels.extend(Self::process_labels( + labels, + &positions, + &instance_path_hashes_for_picking, + &colors, + &annotation_infos, + ent_context.world_from_entity, + )); + } } } } @@ -224,11 +231,8 @@ impl VisualizerSystem for Points3DVisualizer { colors, radii, labels, - keypoint_ids: keypoint_ids - .iter() - .any(Option::is_some) - .then_some(keypoint_ids), - class_ids: class_ids.iter().any(Option::is_some).then_some(class_ids), + keypoint_ids, + class_ids, }; self.process_data(query, ent_path, ent_context, &data); Ok(()) @@ -263,9 +267,9 @@ pub struct LoadedPoints { pub struct Points3DComponentData<'a> { pub instance_keys: &'a [InstanceKey], pub positions: &'a [Position3D], - pub colors: &'a [Option], - pub radii: &'a [Option], - pub labels: &'a [Option], + pub colors: Option<&'a [Option]>, + pub radii: Option<&'a [Option]>, + pub labels: Option<&'a [Option]>, pub keypoint_ids: Option<&'a [Option]>, pub class_ids: Option<&'a [Option]>, } @@ -316,11 +320,13 @@ impl LoadedPoints { #[inline] pub fn load_radii( - &Points3DComponentData { radii, .. }: &Points3DComponentData<'_>, + &Points3DComponentData { + positions, radii, .. + }: &Points3DComponentData<'_>, ent_path: &EntityPath, ) -> Vec { re_tracing::profile_function!(); - let radii = crate::visualizers::process_radius_slice(radii, ent_path); + let radii = crate::visualizers::process_radius_slice(radii, positions.len(), ent_path); { re_tracing::profile_scope!("collect"); radii.collect() @@ -329,12 +335,19 @@ impl LoadedPoints { #[inline] pub fn load_colors( - &Points3DComponentData { colors, .. }: &Points3DComponentData<'_>, + &Points3DComponentData { + positions, colors, .. + }: &Points3DComponentData<'_>, ent_path: &EntityPath, annotation_infos: &ResolvedAnnotationInfos, ) -> Vec { re_tracing::profile_function!(); - let colors = crate::visualizers::process_color_slice(colors, ent_path, annotation_infos); + let colors = crate::visualizers::process_color_slice( + colors, + positions.len(), + ent_path, + annotation_infos, + ); { re_tracing::profile_scope!("collect"); colors.collect() diff --git a/crates/re_space_view_text_log/src/visualizer_system.rs b/crates/re_space_view_text_log/src/visualizer_system.rs index 4da792f1f71d..6d172ba1d69f 100644 --- a/crates/re_space_view_text_log/src/visualizer_system.rs +++ b/crates/re_space_view_text_log/src/visualizer_system.rs @@ -1,6 +1,7 @@ use re_data_store::TimeRange; use re_entity_db::EntityPath; use re_log_types::RowId; +use re_query_cache::MaybeCachedComponentData; use re_types::{ archetypes::TextLog, components::{Color, Text, TextLogLevel}, @@ -74,9 +75,11 @@ impl VisualizerSystem for TextLogSystem { &timeline_query.clone().into(), &data_result.entity_path, |((time, row_id), _, bodies, levels, colors)| { - for (body, level, color) in - itertools::izip!(bodies.iter(), levels.iter(), colors.iter()) - { + for (body, level, color) in itertools::izip!( + bodies.iter(), + MaybeCachedComponentData::iter_or_repeat_opt(&levels, bodies.len()), + MaybeCachedComponentData::iter_or_repeat_opt(&colors, bodies.len()), + ) { self.entries.push(Entry { row_id, entity_path: data_result.entity_path.clone(), diff --git a/crates/re_space_view_time_series/src/visualizer_system.rs b/crates/re_space_view_time_series/src/visualizer_system.rs index f18feaf0a2d3..82f46c7941e0 100644 --- a/crates/re_space_view_time_series/src/visualizer_system.rs +++ b/crates/re_space_view_time_series/src/visualizer_system.rs @@ -1,6 +1,6 @@ use re_data_store::TimeRange; use re_log_types::TimeInt; -use re_query_cache::QueryError; +use re_query_cache::{MaybeCachedComponentData, QueryError}; use re_types::{ archetypes::TimeSeriesScalar, components::{Color, Radius, Scalar, ScalarScattering, Text}, @@ -180,10 +180,10 @@ impl TimeSeriesSystem { for (scalar, scattered, color, radius, label) in itertools::izip!( scalars.iter(), - scatterings.iter(), - colors.iter(), - radii.iter(), - labels.iter() + MaybeCachedComponentData::iter_or_repeat_opt(&scatterings, scalars.len()), + MaybeCachedComponentData::iter_or_repeat_opt(&colors, scalars.len()), + MaybeCachedComponentData::iter_or_repeat_opt(&radii, scalars.len()), + MaybeCachedComponentData::iter_or_repeat_opt(&labels, scalars.len()), ) { let color = annotation_info.color(color.map(|c| c.to_array()), default_color);