diff --git a/crates/store/re_chunk/src/iter.rs b/crates/store/re_chunk/src/iter.rs index 1534d9ac0a28..fd212996822c 100644 --- a/crates/store/re_chunk/src/iter.rs +++ b/crates/store/re_chunk/src/iter.rs @@ -686,6 +686,10 @@ impl Chunk { /// Use this when working with complex arrow datatypes and performance matters (e.g. ranging /// through enum types across many timestamps). /// + /// TODO(#5305): Note that, while this is much faster than deserializing each row individually, + /// this still uses the old codegen'd deserialization path, which does some very unidiomatic Arrow + /// things, and is therefore very slow at the moment. Avoid this on performance critical paths. + /// /// See also: /// * [`Self::iter_primitive`] /// * [`Self::iter_primitive_array`] diff --git a/crates/store/re_types/src/components/colormap_ext.rs b/crates/store/re_types/src/components/colormap_ext.rs new file mode 100644 index 000000000000..4ac1db7ecda1 --- /dev/null +++ b/crates/store/re_types/src/components/colormap_ext.rs @@ -0,0 +1,31 @@ +use super::Colormap; + +impl Colormap { + /// Instantiate a new [`Colormap`] from a u8 value. + /// + /// Returns `None` if the value doesn't match any of the enum's arms. + pub fn from_u8(value: u8) -> Option { + // NOTE: This code will be optimized out, it's only here to make sure this method fails to + // compile if the enum is modified. + match Self::default() { + Self::Grayscale + | Self::Inferno + | Self::Magma + | Self::Plasma + | Self::Turbo + | Self::Viridis + | Self::CyanToYellow => {} + } + + match value { + v if v == Self::Grayscale as u8 => Some(Self::Grayscale), + v if v == Self::Inferno as u8 => Some(Self::Inferno), + v if v == Self::Magma as u8 => Some(Self::Magma), + v if v == Self::Plasma as u8 => Some(Self::Plasma), + v if v == Self::Turbo as u8 => Some(Self::Turbo), + v if v == Self::Viridis as u8 => Some(Self::Viridis), + v if v == Self::CyanToYellow as u8 => Some(Self::CyanToYellow), + _ => None, + } + } +} diff --git a/crates/store/re_types/src/components/fill_mode_ext.rs b/crates/store/re_types/src/components/fill_mode_ext.rs new file mode 100644 index 000000000000..9096be0cb444 --- /dev/null +++ b/crates/store/re_types/src/components/fill_mode_ext.rs @@ -0,0 +1,21 @@ +use super::FillMode; + +impl FillMode { + /// Instantiate a new [`FillMode`] from a u8 value. + /// + /// Returns `None` if the value doesn't match any of the enum's arms. + pub fn from_u8(value: u8) -> Option { + // NOTE: This code will be optimized out, it's only here to make sure this method fails to + // compile if the enum is modified. + match Self::default() { + Self::MajorWireframe | Self::DenseWireframe | Self::Solid => {} + } + + match value { + v if v == Self::MajorWireframe as u8 => Some(Self::MajorWireframe), + v if v == Self::DenseWireframe as u8 => Some(Self::DenseWireframe), + v if v == Self::Solid as u8 => Some(Self::Solid), + _ => None, + } + } +} diff --git a/crates/store/re_types/src/components/mod.rs b/crates/store/re_types/src/components/mod.rs index 7273851612a7..8e327e644274 100644 --- a/crates/store/re_types/src/components/mod.rs +++ b/crates/store/re_types/src/components/mod.rs @@ -12,6 +12,7 @@ mod class_id_ext; mod color; mod color_ext; mod colormap; +mod colormap_ext; mod depth_meter; mod depth_meter_ext; mod disconnected_space; @@ -20,6 +21,7 @@ mod draw_order; mod draw_order_ext; mod entity_path; mod fill_mode; +mod fill_mode_ext; mod fill_ratio; mod fill_ratio_ext; mod gamma_correction; diff --git a/crates/viewer/re_view/src/results_ext.rs b/crates/viewer/re_view/src/results_ext.rs index e69e764482f0..ed5a05b659d5 100644 --- a/crates/viewer/re_view/src/results_ext.rs +++ b/crates/viewer/re_view/src/results_ext.rs @@ -421,8 +421,12 @@ pub struct HybridResultsChunkIter<'a> { impl<'a> HybridResultsChunkIter<'a> { /// Iterate as indexed deserialized batches. /// + /// TODO(#5305): Note that this uses the old codegen'd deserialization path, which does some + /// very unidiomatic Arrow things, and is therefore very slow at the moment. Avoid this on + /// performance critical paths. + /// /// See [`Chunk::iter_component`] for more information. - pub fn component( + pub fn component_slow( &'a self, ) -> impl Iterator)> + 'a { self.chunks.iter().flat_map(move |chunk| { diff --git a/crates/viewer/re_view_graph/src/visualizers/edges.rs b/crates/viewer/re_view_graph/src/visualizers/edges.rs index 4f980e559df1..fac36b789bf5 100644 --- a/crates/viewer/re_view_graph/src/visualizers/edges.rs +++ b/crates/viewer/re_view_graph/src/visualizers/edges.rs @@ -62,7 +62,8 @@ impl VisualizerSystem for EdgesVisualizer { let all_indexed_edges = results.iter_as(query.timeline, components::GraphEdge::name()); let graph_type = results.get_mono_with_fallback::(); - for (_index, edges) in all_indexed_edges.component::() { + // TODO(cmc): Provide a `iter_struct`. + for (_index, edges) in all_indexed_edges.component_slow::() { let edges = edges .iter() .enumerate() diff --git a/crates/viewer/re_view_graph/src/visualizers/nodes.rs b/crates/viewer/re_view_graph/src/visualizers/nodes.rs index d65e45f15c6f..5c13da73385b 100644 --- a/crates/viewer/re_view_graph/src/visualizers/nodes.rs +++ b/crates/viewer/re_view_graph/src/visualizers/nodes.rs @@ -88,8 +88,9 @@ impl VisualizerSystem for NodeVisualizer { .map_or(true, bool::from); let data = range_zip_1x4( - all_indexed_nodes.component::(), - all_colors.component::(), + // TODO(cmc): Provide a `iter_struct`. + all_indexed_nodes.component_slow::(), + all_colors.primitive::(), all_positions.primitive_array::<2, f32>(), all_labels.string(), all_radii.primitive::(), @@ -100,7 +101,7 @@ impl VisualizerSystem for NodeVisualizer { nodes.iter(), (0..).map(Instance::from), colors.unwrap_or_default().iter().map(Option::Some), - Option::<&Color>::default, + Option::<&u32>::default, positions .unwrap_or_default() .iter() @@ -113,7 +114,7 @@ impl VisualizerSystem for NodeVisualizer { Option::::default, ) .map(|(node, instance, color, position, label, radius)| { - let color = color.map(|&c| egui::Color32::from(c)); + let color = color.map(|&c| egui::Color32::from(Color::new(c))); let label = match (label, show_label) { (Some(label), true) => Label::Text { text: label.clone(), diff --git a/crates/viewer/re_view_map/src/visualizers/geo_line_strings.rs b/crates/viewer/re_view_map/src/visualizers/geo_line_strings.rs index 2b2e145d13e2..74550c4f368a 100644 --- a/crates/viewer/re_view_map/src/visualizers/geo_line_strings.rs +++ b/crates/viewer/re_view_map/src/visualizers/geo_line_strings.rs @@ -66,20 +66,20 @@ impl VisualizerSystem for GeoLineStringsVisualizer { // iterate over each chunk and find all relevant component slices for (_index, lines, colors, radii) in re_query::range_zip_1x2( - all_lines.component::(), - all_colors.component::(), - all_radii.component::(), + all_lines.primitive_array_list::<2, f64>(), + all_colors.primitive::(), + all_radii.primitive::(), ) { // required component let lines = lines.as_slice(); // optional components - let colors = colors.as_ref().map(|c| c.as_slice()).unwrap_or(&[]); - let radii = radii.as_ref().map(|r| r.as_slice()).unwrap_or(&[]); + let colors = colors.unwrap_or(&[]); + let radii = radii.unwrap_or(&[]); // optional components values to be used for instance clamping semantics - let last_color = colors.last().copied().unwrap_or(fallback_color); - let last_radii = radii.last().copied().unwrap_or(fallback_radius); + let last_color = colors.last().copied().unwrap_or(fallback_color.0 .0); + let last_radii = radii.last().copied().unwrap_or(fallback_radius.0 .0); // iterate over all instances for (instance_index, (line, color, radius)) in itertools::izip!( @@ -90,13 +90,12 @@ impl VisualizerSystem for GeoLineStringsVisualizer { .enumerate() { batch_data.lines.push( - line.0 - .iter() - .map(|pos| walkers::Position::from_lat_lon(pos.x(), pos.y())) + line.iter() + .map(|pos| walkers::Position::from_lat_lon(pos[0], pos[1])) .collect(), ); - batch_data.radii.push(*radius); - batch_data.colors.push(color.0.into()); + batch_data.radii.push(Radius((*radius).into())); + batch_data.colors.push(Color::new(*color).into()); batch_data .instance_id .push(re_renderer::PickingLayerInstanceId(instance_index as _)); diff --git a/crates/viewer/re_view_map/src/visualizers/geo_points.rs b/crates/viewer/re_view_map/src/visualizers/geo_points.rs index 29f9426e8d05..f904049f8893 100644 --- a/crates/viewer/re_view_map/src/visualizers/geo_points.rs +++ b/crates/viewer/re_view_map/src/visualizers/geo_points.rs @@ -69,13 +69,12 @@ impl VisualizerSystem for GeoPointsVisualizer { // iterate over each chunk and find all relevant component slices for (_index, positions, colors, radii, class_ids) in re_query::range_zip_1x3( - all_positions.component::(), + all_positions.primitive_array::<2, f64>(), all_colors.primitive::(), - all_radii.component::(), + all_radii.primitive::(), all_class_ids.primitive::(), ) { // required component - let positions = positions.as_slice(); let num_instances = positions.len(); // Resolve annotation info (if needed). @@ -94,10 +93,10 @@ impl VisualizerSystem for GeoPointsVisualizer { &annotation_infos, colors.map_or(&[], |colors| bytemuck::cast_slice(colors)), ); - let radii = radii.as_ref().map(|r| r.as_slice()).unwrap_or(&[]); + let radii = radii.unwrap_or(&[]); // optional components values to be used for instance clamping semantics - let last_radii = radii.last().copied().unwrap_or(fallback_radius); + let last_radii = radii.last().copied().unwrap_or(fallback_radius.0 .0); // iterate over all instances for (instance_index, (position, color, radius)) in itertools::izip!( @@ -107,11 +106,10 @@ impl VisualizerSystem for GeoPointsVisualizer { ) .enumerate() { - batch_data.positions.push(walkers::Position::from_lat_lon( - position.latitude(), - position.longitude(), - )); - batch_data.radii.push(*radius); + batch_data + .positions + .push(walkers::Position::from_lat_lon(position[0], position[1])); + batch_data.radii.push(Radius((*radius).into())); batch_data.colors.push(*color); batch_data .instance_id diff --git a/crates/viewer/re_view_spatial/src/visualizers/arrows2d.rs b/crates/viewer/re_view_spatial/src/visualizers/arrows2d.rs index e8a01ee5a988..c9d062306b2c 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/arrows2d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/arrows2d.rs @@ -244,7 +244,8 @@ impl VisualizerSystem for Arrows2DVisualizer { all_labels.string(), all_class_ids.primitive::(), all_keypoint_ids.primitive::(), - all_show_labels.component::(), + // TODO(cmc): provide a `iter_bool`. + all_show_labels.component_slow::(), ) .map( |( diff --git a/crates/viewer/re_view_spatial/src/visualizers/arrows3d.rs b/crates/viewer/re_view_spatial/src/visualizers/arrows3d.rs index 5249863867f3..401afd9ec21f 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/arrows3d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/arrows3d.rs @@ -241,7 +241,7 @@ impl VisualizerSystem for Arrows3DVisualizer { all_radii.primitive::(), all_labels.string(), all_class_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |(_index, vectors, origins, colors, radii, labels, class_ids, show_labels)| { diff --git a/crates/viewer/re_view_spatial/src/visualizers/boxes2d.rs b/crates/viewer/re_view_spatial/src/visualizers/boxes2d.rs index 5f05e0f649c1..bd451dd39f72 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/boxes2d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/boxes2d.rs @@ -245,7 +245,7 @@ impl VisualizerSystem for Boxes2DVisualizer { all_radii.primitive::(), all_labels.string(), all_class_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |( diff --git a/crates/viewer/re_view_spatial/src/visualizers/boxes3d.rs b/crates/viewer/re_view_spatial/src/visualizers/boxes3d.rs index 40dfe1adbf05..9853118eab2b 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/boxes3d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/boxes3d.rs @@ -159,9 +159,11 @@ impl VisualizerSystem for Boxes3DVisualizer { let all_fill_modes = results.iter_as(timeline, FillMode::name()); // fill mode is currently a non-repeated component let fill_mode: FillMode = all_fill_modes - .component::() + .primitive::() .next() - .and_then(|(_, fill_modes)| fill_modes.as_slice().first().copied()) + .and_then(|(_, fill_modes)| { + fill_modes.first().copied().and_then(FillMode::from_u8) + }) .unwrap_or_default(); match fill_mode { @@ -181,7 +183,7 @@ impl VisualizerSystem for Boxes3DVisualizer { all_radii.primitive::(), all_labels.string(), all_class_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |(_index, half_sizes, colors, radii, labels, class_ids, show_labels)| { diff --git a/crates/viewer/re_view_spatial/src/visualizers/capsules3d.rs b/crates/viewer/re_view_spatial/src/visualizers/capsules3d.rs index a397cb80f8af..70705080e575 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/capsules3d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/capsules3d.rs @@ -195,7 +195,7 @@ impl VisualizerSystem for Capsules3DVisualizer { all_radii_indexed, all_colors.primitive::(), all_labels.string(), - all_show_labels.component::(), + all_show_labels.component_slow::(), all_class_ids.primitive::(), ) .map( diff --git a/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs b/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs index 6d5fbbf68dee..94c53af9c08b 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs @@ -292,7 +292,7 @@ impl VisualizerSystem for DepthImageVisualizer { let mut data = re_query::range_zip_1x5( all_buffers_indexed, all_formats_indexed, - all_colormaps.component::(), + all_colormaps.primitive::(), all_value_ranges.primitive_array::<2, f64>(), all_depth_meters.primitive::(), all_fill_ratios.primitive::(), @@ -310,7 +310,7 @@ impl VisualizerSystem for DepthImageVisualizer { }, depth_meter: first_copied(depth_meter).map(Into::into), fill_ratio: first_copied(fill_ratio).map(Into::into), - colormap: first_copied(colormap.as_deref()), + colormap: first_copied(colormap).and_then(Colormap::from_u8), value_range: first_copied(value_range).map(Into::into), }) }, diff --git a/crates/viewer/re_view_spatial/src/visualizers/ellipsoids.rs b/crates/viewer/re_view_spatial/src/visualizers/ellipsoids.rs index db2add13a89c..fd52a0269b02 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/ellipsoids.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/ellipsoids.rs @@ -178,10 +178,10 @@ impl VisualizerSystem for Ellipsoids3DVisualizer { all_half_sizes_indexed, all_colors.primitive::(), all_line_radii.primitive::(), - all_fill_modes.component::(), + all_fill_modes.primitive::(), all_labels.string(), all_class_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |( @@ -204,6 +204,7 @@ impl VisualizerSystem for Ellipsoids3DVisualizer { .unwrap_or_default() .first() .copied() + .and_then(FillMode::from_u8) .unwrap_or_default(), labels: labels.unwrap_or_default(), class_ids: class_ids diff --git a/crates/viewer/re_view_spatial/src/visualizers/lines2d.rs b/crates/viewer/re_view_spatial/src/visualizers/lines2d.rs index c922ec9ecc22..009b33a3f5dc 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/lines2d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/lines2d.rs @@ -232,7 +232,7 @@ impl VisualizerSystem for Lines2DVisualizer { all_radii.primitive::(), all_labels.string(), all_class_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |(_index, strips, colors, radii, labels, class_ids, show_labels)| { diff --git a/crates/viewer/re_view_spatial/src/visualizers/lines3d.rs b/crates/viewer/re_view_spatial/src/visualizers/lines3d.rs index d8dc908f8458..31d33029c371 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/lines3d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/lines3d.rs @@ -236,7 +236,7 @@ impl VisualizerSystem for Lines3DVisualizer { all_radii.primitive::(), all_labels.string(), all_class_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |(_index, strips, colors, radii, labels, class_ids, show_labels)| { diff --git a/crates/viewer/re_view_spatial/src/visualizers/meshes.rs b/crates/viewer/re_view_spatial/src/visualizers/meshes.rs index 09a73e05bea5..d5e83f60f9d2 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/meshes.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/meshes.rs @@ -214,8 +214,10 @@ impl VisualizerSystem for Mesh3DVisualizer { all_vertex_texcoords.primitive_array::<2, f32>(), all_triangle_indices.primitive_array::<3, u32>(), all_albedo_factors.primitive::(), - all_albedo_buffers.component::(), - all_albedo_formats.component::(), + // TODO(cmc): Provide a `iter_blob`. + all_albedo_buffers.component_slow::(), + // Legit call to `component_slow`, `ImageFormat` is real complicated. + all_albedo_formats.component_slow::(), all_class_ids.primitive::(), ) .map( diff --git a/crates/viewer/re_view_spatial/src/visualizers/points2d.rs b/crates/viewer/re_view_spatial/src/visualizers/points2d.rs index 55bb5eb9908c..8929bec8da31 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/points2d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/points2d.rs @@ -251,7 +251,7 @@ impl VisualizerSystem for Points2DVisualizer { all_labels.string(), all_class_ids.primitive::(), all_keypoint_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |( diff --git a/crates/viewer/re_view_spatial/src/visualizers/points3d.rs b/crates/viewer/re_view_spatial/src/visualizers/points3d.rs index 4860a6f6128c..57abfef3309a 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/points3d.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/points3d.rs @@ -241,7 +241,7 @@ impl VisualizerSystem for Points3DVisualizer { all_labels.string(), all_class_ids.primitive::(), all_keypoint_ids.primitive::(), - all_show_labels.component::(), + all_show_labels.component_slow::(), ) .map( |( diff --git a/crates/viewer/re_view_tensor/src/visualizer_system.rs b/crates/viewer/re_view_tensor/src/visualizer_system.rs index ce6bd9a18858..aa5e0cbd2412 100644 --- a/crates/viewer/re_view_tensor/src/visualizer_system.rs +++ b/crates/viewer/re_view_tensor/src/visualizer_system.rs @@ -69,13 +69,18 @@ impl VisualizerSystem for TensorSystem { let all_ranges = results.iter_as(timeline, ValueRange::name()); for ((_, tensor_row_id), tensors, data_ranges) in - re_query::range_zip_1x1(all_tensors_indexed, all_ranges.component::()) + re_query::range_zip_1x1(all_tensors_indexed, all_ranges.primitive_array::<2, f64>()) { let Some(tensor) = tensors.first() else { continue; }; let data_range = data_ranges - .and_then(|ranges| ranges.first().copied()) + .and_then(|ranges| { + ranges + .first() + .copied() + .map(|range| ValueRange(range.into())) + }) .unwrap_or_else(|| { let tensor_stats = ctx .viewer_ctx diff --git a/crates/viewer/re_view_text_log/src/visualizer_system.rs b/crates/viewer/re_view_text_log/src/visualizer_system.rs index 9440dbf5883d..d6330d8b842d 100644 --- a/crates/viewer/re_view_text_log/src/visualizer_system.rs +++ b/crates/viewer/re_view_text_log/src/visualizer_system.rs @@ -111,7 +111,7 @@ impl TextLogSystem { let all_frames = range_zip_1x2( all_texts.string(), - all_levels.component(), + all_levels.string(), all_colors.primitive::(), ); @@ -139,7 +139,7 @@ impl TextLogSystem { timepoint: timepoint.clone(), color, body: text.clone().into(), - level, + level: level.clone().map(Into::into), }); } }